kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: simplify passing args to `MessagesFragment`
rodzic
6a0d9b523b
commit
5c98936e23
|
@ -190,9 +190,27 @@ class UIViewModel @Inject constructor(
|
||||||
debug("ViewModel created")
|
debug("ViewModel created")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val contactKey: MutableStateFlow<String> = MutableStateFlow(DataPacket.ID_BROADCAST)
|
private val _contactKey = MutableStateFlow("0${DataPacket.ID_BROADCAST}")
|
||||||
|
val contactKey: StateFlow<String> = _contactKey
|
||||||
fun setContactKey(contact: String) {
|
fun setContactKey(contact: String) {
|
||||||
contactKey.value = contact
|
_contactKey.value = contact
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getContactName(contactKey: String): String {
|
||||||
|
val (channel, dest) = contactKey[0].digitToIntOrNull() to contactKey.substring(1)
|
||||||
|
|
||||||
|
return if (channel == null || dest == DataPacket.ID_BROADCAST) {
|
||||||
|
// grab channel names from ChannelSet
|
||||||
|
val channelName = with(channelSet) {
|
||||||
|
if (channel != null && settingsCount > channel)
|
||||||
|
Channel(settingsList[channel], loraConfig).name else null
|
||||||
|
}
|
||||||
|
channelName ?: app.getString(R.string.channel_name)
|
||||||
|
} else {
|
||||||
|
// grab usernames from NodeInfo
|
||||||
|
val node = nodeDB.nodes.value[dest]
|
||||||
|
node?.user?.longName ?: app.getString(R.string.unknown_username)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@ -237,7 +255,7 @@ class UIViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendMessage(str: String, contactKey: String = "0${DataPacket.ID_BROADCAST}") {
|
fun sendMessage(str: String, contactKey: String = this.contactKey.value) {
|
||||||
// contactKey: unique contact key filter (channel)+(nodeId)
|
// contactKey: unique contact key filter (channel)+(nodeId)
|
||||||
val channel = contactKey[0].digitToIntOrNull()
|
val channel = contactKey[0].digitToIntOrNull()
|
||||||
val dest = if (channel != null) contactKey.substring(1) else contactKey
|
val dest = if (channel != null) contactKey.substring(1) else contactKey
|
||||||
|
|
|
@ -7,9 +7,7 @@ import android.view.*
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.setFragmentResult
|
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
@ -122,10 +120,7 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
||||||
if (actionMode != null) clickItem(holder, packet.contact_key)
|
if (actionMode != null) clickItem(holder, packet.contact_key)
|
||||||
else {
|
else {
|
||||||
debug("calling MessagesFragment filter:${packet.contact_key}")
|
debug("calling MessagesFragment filter:${packet.contact_key}")
|
||||||
setFragmentResult(
|
model.setContactKey(packet.contact_key)
|
||||||
"requestKey",
|
|
||||||
bundleOf("contactKey" to packet.contact_key, "contactName" to longName)
|
|
||||||
)
|
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction()
|
||||||
.replace(R.id.mainActivityLayout, MessagesFragment())
|
.replace(R.id.mainActivityLayout, MessagesFragment())
|
||||||
.addToBackStack(null)
|
.addToBackStack(null)
|
||||||
|
|
|
@ -13,7 +13,6 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.allViews
|
import androidx.core.view.allViews
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.setFragmentResultListener
|
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
@ -43,13 +42,9 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
|
|
||||||
// This property is only valid between onCreateView and onDestroyView.
|
// This property is only valid between onCreateView and onDestroyView.
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
private var contactKey: String = DataPacket.ID_BROADCAST
|
|
||||||
private var contactName: String = DataPacket.ID_BROADCAST
|
|
||||||
|
|
||||||
private val model: UIViewModel by activityViewModels()
|
private val model: UIViewModel by activityViewModels()
|
||||||
|
|
||||||
private var isConnected = false
|
|
||||||
|
|
||||||
// Provide a direct reference to each of the views within a data item
|
// Provide a direct reference to each of the views within a data item
|
||||||
// Used to cache the views within the item layout for fast access
|
// Used to cache the views within the item layout for fast access
|
||||||
class ViewHolder(itemView: AdapterMessageLayoutBinding) :
|
class ViewHolder(itemView: AdapterMessageLayoutBinding) :
|
||||||
|
@ -240,12 +235,6 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
outState.putString("contactKey", contactKey)
|
|
||||||
outState.putString("contactName", contactName)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
@ -253,25 +242,12 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
parentFragmentManager.popBackStack()
|
parentFragmentManager.popBackStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
setFragmentResultListener("requestKey") { _, bundle->
|
|
||||||
// get the result from bundle
|
|
||||||
contactKey = bundle.getString("contactKey").toString()
|
|
||||||
contactName = bundle.getString("contactName").toString()
|
|
||||||
model.setContactKey(contactKey)
|
|
||||||
binding.messageTitle.text = contactName
|
|
||||||
}
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
contactKey = savedInstanceState.getString("contactKey").toString()
|
|
||||||
contactName = savedInstanceState.getString("contactName").toString()
|
|
||||||
binding.messageTitle.text = contactName
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.sendButton.setOnClickListener {
|
binding.sendButton.setOnClickListener {
|
||||||
debug("User clicked sendButton")
|
debug("User clicked sendButton")
|
||||||
|
|
||||||
val str = binding.messageInputText.text.toString().trim()
|
val str = binding.messageInputText.text.toString().trim()
|
||||||
if (str.isNotEmpty())
|
if (str.isNotEmpty())
|
||||||
model.sendMessage(str, contactKey)
|
model.sendMessage(str)
|
||||||
binding.messageInputText.setText("") // blow away the string the user just entered
|
binding.messageInputText.setText("") // blow away the string the user just entered
|
||||||
|
|
||||||
// requireActivity().hideKeyboard()
|
// requireActivity().hideKeyboard()
|
||||||
|
@ -281,7 +257,7 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
debug("received IME_ACTION_SEND")
|
debug("received IME_ACTION_SEND")
|
||||||
|
|
||||||
val str = binding.messageInputText.text.toString().trim()
|
val str = binding.messageInputText.text.toString().trim()
|
||||||
if (str.isNotEmpty()) model.sendMessage(str, contactKey)
|
if (str.isNotEmpty()) model.sendMessage(str)
|
||||||
binding.messageInputText.setText("") // blow away the string the user just entered
|
binding.messageInputText.setText("") // blow away the string the user just entered
|
||||||
|
|
||||||
// requireActivity().hideKeyboard()
|
// requireActivity().hideKeyboard()
|
||||||
|
@ -300,7 +276,7 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
// If connection state _OR_ myID changes we have to fix our ability to edit outgoing messages
|
// If connection state _OR_ myID changes we have to fix our ability to edit outgoing messages
|
||||||
model.connectionState.observe(viewLifecycleOwner) {
|
model.connectionState.observe(viewLifecycleOwner) {
|
||||||
// If we don't know our node ID and we are offline don't let user try to send
|
// If we don't know our node ID and we are offline don't let user try to send
|
||||||
isConnected = model.isConnected()
|
val isConnected = model.isConnected()
|
||||||
binding.textInputLayout.isEnabled = isConnected
|
binding.textInputLayout.isEnabled = isConnected
|
||||||
binding.sendButton.isEnabled = isConnected
|
binding.sendButton.isEnabled = isConnected
|
||||||
for (subView: View in binding.quickChatLayout.allViews) {
|
for (subView: View in binding.quickChatLayout.allViews) {
|
||||||
|
@ -310,6 +286,10 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model.contactKey.asLiveData().observe(viewLifecycleOwner) {
|
||||||
|
binding.messageTitle.text = model.getContactName(it)
|
||||||
|
}
|
||||||
|
|
||||||
model.quickChatActions.asLiveData().observe(viewLifecycleOwner) { actions ->
|
model.quickChatActions.asLiveData().observe(viewLifecycleOwner) { actions ->
|
||||||
actions?.let {
|
actions?.let {
|
||||||
// This seems kinda hacky it might be better to replace with a recycler view
|
// This seems kinda hacky it might be better to replace with a recycler view
|
||||||
|
@ -317,7 +297,7 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
for (action in actions) {
|
for (action in actions) {
|
||||||
val button = Button(context)
|
val button = Button(context)
|
||||||
button.text = action.name
|
button.text = action.name
|
||||||
button.isEnabled = isConnected
|
button.isEnabled = model.isConnected()
|
||||||
if (action.mode == QuickChatAction.Mode.Instant) {
|
if (action.mode == QuickChatAction.Mode.Instant) {
|
||||||
button.backgroundTintList = ContextCompat.getColorStateList(requireActivity(), R.color.colorMyMsg)
|
button.backgroundTintList = ContextCompat.getColorStateList(requireActivity(), R.color.colorMyMsg)
|
||||||
}
|
}
|
||||||
|
@ -333,7 +313,7 @@ class MessagesFragment : Fragment(), Logging {
|
||||||
binding.messageInputText.setText(newText)
|
binding.messageInputText.setText(newText)
|
||||||
binding.messageInputText.setSelection(newText.length)
|
binding.messageInputText.setSelection(newText.length)
|
||||||
} else {
|
} else {
|
||||||
model.sendMessage(action.message, contactKey)
|
model.sendMessage(action.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.quickChatLayout.addView(button)
|
binding.quickChatLayout.addView(button)
|
||||||
|
|
|
@ -15,10 +15,8 @@ import android.view.animation.LinearInterpolator
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.animation.doOnEnd
|
import androidx.core.animation.doOnEnd
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.setFragmentResult
|
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
@ -119,13 +117,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.direct_message -> {
|
R.id.direct_message -> {
|
||||||
debug("calling MessagesFragment filter: ${node.channel}${user.id}")
|
debug("calling MessagesFragment filter: ${node.channel}${user.id}")
|
||||||
setFragmentResult(
|
model.setContactKey("${node.channel}${user.id}")
|
||||||
"requestKey",
|
|
||||||
bundleOf(
|
|
||||||
"contactKey" to "${node.channel}${user.id}",
|
|
||||||
"contactName" to user.longName
|
|
||||||
)
|
|
||||||
)
|
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction()
|
||||||
.replace(R.id.mainActivityLayout, MessagesFragment())
|
.replace(R.id.mainActivityLayout, MessagesFragment())
|
||||||
.addToBackStack(null)
|
.addToBackStack(null)
|
||||||
|
|
|
@ -31,9 +31,7 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.setFragmentResult
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.geeksville.mesh.BuildConfig
|
import com.geeksville.mesh.BuildConfig
|
||||||
|
@ -115,13 +113,7 @@ class MapFragment : ScreenFragment("Map Fragment"), Logging {
|
||||||
|
|
||||||
private fun openDirectMessage(node: NodeInfo) {
|
private fun openDirectMessage(node: NodeInfo) {
|
||||||
val user = node.user ?: return
|
val user = node.user ?: return
|
||||||
setFragmentResult(
|
model.setContactKey("${node.channel}${user.id}")
|
||||||
"requestKey",
|
|
||||||
bundleOf(
|
|
||||||
"contactKey" to "${node.channel}${user.id}",
|
|
||||||
"contactName" to user.longName
|
|
||||||
)
|
|
||||||
)
|
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction()
|
||||||
.replace(R.id.mainActivityLayout, MessagesFragment())
|
.replace(R.id.mainActivityLayout, MessagesFragment())
|
||||||
.addToBackStack(null)
|
.addToBackStack(null)
|
||||||
|
|
Ładowanie…
Reference in New Issue