kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
feat: add condition check to scroll to bottom of messages list (#882)
rodzic
0ba462db83
commit
2e009ca49c
|
@ -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())
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue