feat: add condition check to scroll to bottom of messages list (#882)

pull/884/head
Andre K 2024-02-28 12:53:08 -03:00 zatwierdzone przez GitHub
rodzic 0ba462db83
commit 2e009ca49c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
2 zmienionych plików z 41 dodań i 51 usunięć

Wyświetl plik

@ -21,7 +21,6 @@ import com.geeksville.mesh.model.Channel
import com.geeksville.mesh.model.UIViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import java.text.DateFormat
import java.util.*
@AndroidEntryPoint
@ -48,19 +47,6 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
private val contactsAdapter = object : RecyclerView.Adapter<ViewHolder>() {
private val dateTimeFormat: DateFormat =
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT)
private val timeFormat: DateFormat =
DateFormat.getTimeInstance(DateFormat.SHORT)
private fun getShortDateTime(time: Date): String {
// return time if within 24 hours, otherwise date/time
val oneDayMsec = 60 * 60 * 24 * 1000L
return if (System.currentTimeMillis() - time.time > oneDayMsec) {
dateTimeFormat.format(time)
} else timeFormat.format(time)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(requireContext())

Wyświetl plik

@ -33,6 +33,17 @@ import dagger.hilt.android.AndroidEntryPoint
import java.text.DateFormat
import java.util.*
// return time if within 24 hours, otherwise date/time
internal fun getShortDateTime(date: Date): String {
val isWithin24Hours = System.currentTimeMillis() - date.time <= 24 * 60 * 60 * 1000L
return if (isWithin24Hours) {
DateFormat.getTimeInstance(DateFormat.SHORT).format(date)
} else {
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(date)
}
}
@AndroidEntryPoint
class MessagesFragment : Fragment(), Logging {
@ -58,19 +69,6 @@ class MessagesFragment : Fragment(), Logging {
private val messagesAdapter = object : RecyclerView.Adapter<ViewHolder>() {
private val dateTimeFormat: DateFormat =
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT)
private val timeFormat: DateFormat =
DateFormat.getTimeInstance(DateFormat.SHORT)
private fun getShortDateTime(time: Date): String {
// return time if within 24 hours, otherwise date/time
val oneDayMsec = 60 * 60 * 24 * 1000L
return if (System.currentTimeMillis() - time.time > oneDayMsec) {
dateTimeFormat.format(time)
} else timeFormat.format(time)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(requireContext())
@ -83,6 +81,11 @@ class MessagesFragment : Fragment(), Logging {
var messages = listOf<Packet>()
var selectedList = ArrayList<Packet>()
val layoutManager get() = binding.messageListView.layoutManager as LinearLayoutManager
fun scrollToBottom() {
if (itemCount > 0) layoutManager.scrollToPosition(itemCount - 1)
}
override fun getItemCount(): Int = messages.size
@ -168,7 +171,7 @@ class MessagesFragment : Fragment(), Logging {
}
holder.itemView.setOnLongClickListener {
clickItem(holder)
clickItem(position)
if (actionMode == null) {
actionMode =
(activity as AppCompatActivity).startSupportActionMode(actionModeCallback)
@ -176,7 +179,7 @@ class MessagesFragment : Fragment(), Logging {
true
}
holder.itemView.setOnClickListener {
if (actionMode != null) clickItem(holder)
if (actionMode != null) clickItem(position)
}
if (selectedList.contains(packet)) {
@ -194,12 +197,10 @@ class MessagesFragment : Fragment(), Logging {
}
}
private fun clickItem(holder: ViewHolder) {
val position = holder.bindingAdapterPosition
if (!selectedList.contains(messages[position])) {
selectedList.add(messages[position])
} else {
selectedList.remove(messages[position])
private fun clickItem(position: Int) {
val message = messages[position]
selectedList.apply {
if (contains(message)) remove(message) else add(message)
}
if (selectedList.isEmpty()) {
// finish action mode when no items selected
@ -213,12 +214,14 @@ class MessagesFragment : Fragment(), Logging {
/// Called when our node DB changes
fun onMessagesChanged(messages: List<Packet>) {
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
val shouldScrollToBottom =
lastVisibleItemPosition <= 0 || lastVisibleItemPosition == itemCount - 1
this.messages = messages
notifyDataSetChanged() // FIXME, this is super expensive and redraws all messages
// scroll to the last line
if (itemCount != 0)
binding.messageListView.scrollToPosition(itemCount - 1)
if (shouldScrollToBottom) scrollToBottom()
}
}
@ -242,25 +245,24 @@ class MessagesFragment : Fragment(), Logging {
parentFragmentManager.popBackStack()
}
fun sendMessageInputText() {
val str = binding.messageInputText.text.toString().trim()
if (str.isNotEmpty()) {
model.sendMessage(str)
messagesAdapter.scrollToBottom()
}
binding.messageInputText.setText("") // blow away the string the user just entered
// requireActivity().hideKeyboard()
}
binding.sendButton.setOnClickListener {
debug("User clicked sendButton")
val str = binding.messageInputText.text.toString().trim()
if (str.isNotEmpty())
model.sendMessage(str)
binding.messageInputText.setText("") // blow away the string the user just entered
// requireActivity().hideKeyboard()
sendMessageInputText()
}
binding.messageInputText.onEditorAction(EditorInfo.IME_ACTION_SEND) {
debug("received IME_ACTION_SEND")
val str = binding.messageInputText.text.toString().trim()
if (str.isNotEmpty()) model.sendMessage(str)
binding.messageInputText.setText("") // blow away the string the user just entered
// requireActivity().hideKeyboard()
sendMessageInputText()
}
binding.messageListView.adapter = messagesAdapter
@ -269,6 +271,7 @@ class MessagesFragment : Fragment(), Logging {
binding.messageListView.layoutManager = layoutManager
model.messages.observe(viewLifecycleOwner) {
if (it.isNotEmpty() && it.first().contact_key != model.contactKey.value) return@observe
debug("New messages received: ${it.size}")
messagesAdapter.onMessagesChanged(it)
}
@ -314,6 +317,7 @@ class MessagesFragment : Fragment(), Logging {
binding.messageInputText.setSelection(newText.length)
} else {
model.sendMessage(action.message)
messagesAdapter.scrollToBottom()
}
}
binding.quickChatLayout.addView(button)