e-ntfy-android/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt
2021-12-30 14:23:47 +01:00

110 lines
5.6 KiB
Kotlin

package io.heckel.ntfy.ui
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import io.heckel.ntfy.R
import io.heckel.ntfy.data.ConnectionState
import io.heckel.ntfy.data.Subscription
import io.heckel.ntfy.util.topicShortUrl
import java.text.DateFormat
import java.util.*
class MainAdapter(private val onClick: (Subscription) -> Unit, private val onLongClick: (Subscription) -> Unit) :
ListAdapter<Subscription, MainAdapter.SubscriptionViewHolder>(TopicDiffCallback) {
val selected = mutableSetOf<Long>() // Subscription IDs
/* Creates and inflates view and return TopicViewHolder. */
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.fragment_main_item, parent, false)
return SubscriptionViewHolder(view, selected, onClick, onLongClick)
}
/* Gets current topic and uses it to bind view. */
override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) {
val subscription = getItem(position)
holder.bind(subscription)
}
fun toggleSelection(subscriptionId: Long) {
if (selected.contains(subscriptionId)) {
selected.remove(subscriptionId)
} else {
selected.add(subscriptionId)
}
}
/* ViewHolder for Topic, takes in the inflated view and the onClick behavior. */
class SubscriptionViewHolder(itemView: View, private val selected: Set<Long>, val onClick: (Subscription) -> Unit, val onLongClick: (Subscription) -> Unit) :
RecyclerView.ViewHolder(itemView) {
private var subscription: Subscription? = null
private val context: Context = itemView.context
private val nameView: TextView = itemView.findViewById(R.id.main_item_text)
private val statusView: TextView = itemView.findViewById(R.id.main_item_status)
private val dateView: TextView = itemView.findViewById(R.id.main_item_date)
private val notificationDisabledUntilImageView: View = itemView.findViewById(R.id.main_item_notification_disabled_until_image)
private val notificationDisabledForeverImageView: View = itemView.findViewById(R.id.main_item_notification_disabled_forever_image)
private val instantImageView: View = itemView.findViewById(R.id.main_item_instant_image)
private val newItemsView: TextView = itemView.findViewById(R.id.main_item_new)
fun bind(subscription: Subscription) {
this.subscription = subscription
var statusMessage = if (subscription.upAppId != null) {
context.getString(R.string.main_item_status_unified_push, subscription.upAppId)
} else if (subscription.totalCount == 1) {
context.getString(R.string.main_item_status_text_one, subscription.totalCount)
} else {
context.getString(R.string.main_item_status_text_not_one, subscription.totalCount)
}
if (subscription.instant && subscription.state == ConnectionState.CONNECTING) {
statusMessage += ", " + context.getString(R.string.main_item_status_reconnecting)
}
val date = Date(subscription.lastActive * 1000)
val dateStr = DateFormat.getDateInstance(DateFormat.SHORT).format(date)
val moreThanOneDay = System.currentTimeMillis()/1000 - subscription.lastActive > 24 * 60 * 60
val sameDay = dateStr == DateFormat.getDateInstance(DateFormat.SHORT).format(Date()) // Omg this is horrible
val dateText = if (subscription.lastActive == 0L) {
""
} else if (sameDay) {
DateFormat.getTimeInstance(DateFormat.SHORT).format(date)
} else if (!moreThanOneDay) {
context.getString(R.string.main_item_date_yesterday)
} else {
dateStr
}
nameView.text = topicShortUrl(subscription.baseUrl, subscription.topic)
statusView.text = statusMessage
dateView.text = dateText
notificationDisabledUntilImageView.visibility = if (subscription.mutedUntil > 1L) View.VISIBLE else View.GONE
notificationDisabledForeverImageView.visibility = if (subscription.mutedUntil == 1L) View.VISIBLE else View.GONE
instantImageView.visibility = if (subscription.instant) View.VISIBLE else View.GONE
if (subscription.upAppId != null || subscription.newCount == 0) {
newItemsView.visibility = View.GONE
} else {
newItemsView.visibility = View.VISIBLE
newItemsView.text = if (subscription.newCount <= 99) subscription.newCount.toString() else "99+"
}
itemView.setOnClickListener { onClick(subscription) }
itemView.setOnLongClickListener { onLongClick(subscription); true }
if (selected.contains(subscription.id)) {
itemView.setBackgroundResource(R.color.primarySelectedRowColor);
}
}
}
object TopicDiffCallback : DiffUtil.ItemCallback<Subscription>() {
override fun areItemsTheSame(oldItem: Subscription, newItem: Subscription): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Subscription, newItem: Subscription): Boolean {
return oldItem == newItem
}
}
}