Meshtastic-Android/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt

246 lines
No EOL
8.4 KiB
Kotlin

package com.geeksville.mesh.ui
import android.content.Intent
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.ArrayAdapter
import android.widget.ImageView
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.geeksville.analytics.DataPair
import com.geeksville.android.GeeksvilleApplication
import com.geeksville.android.Logging
import com.geeksville.android.hideKeyboard
import com.geeksville.mesh.R
import com.geeksville.mesh.model.UIViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.android.synthetic.main.channel_fragment.*
// Make an image view dim
fun ImageView.setDim() {
val matrix = ColorMatrix()
matrix.setSaturation(0f) //0 means grayscale
val cf = ColorMatrixColorFilter(matrix)
colorFilter = cf
imageAlpha = 64 // 128 = 0.5
}
/// Return image view to normal
fun ImageView.setOpaque() {
colorFilter = null
imageAlpha = 255
}
class ChannelFragment : ScreenFragment("Channel"), Logging {
private val model: UIViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.channel_fragment, container, false)
}
/// Called when the lock/unlock icon has changed
private fun onEditingChanged() {
val isEditing = editableCheckbox.isChecked
channelOptions.isEnabled = false // Not yet ready
shareButton.isEnabled = !isEditing
channelNameView.isEnabled = isEditing
if (isEditing) // Dim the (stale) QR code while editing...
qrView.setDim()
else
qrView.setOpaque()
}
/// Pull the latest data from the model (discarding any user edits)
private fun setGUIfromModel() {
val channel = UIViewModel.getChannel(model.radioConfig.value)
editableCheckbox.isChecked = false // start locked
if (channel != null) {
qrView.visibility = View.VISIBLE
channelNameEdit.visibility = View.VISIBLE
channelNameEdit.setText(channel.name)
editableCheckbox.isEnabled = true
qrView.setImageBitmap(channel.getChannelQR())
} else {
qrView.visibility = View.INVISIBLE
channelNameEdit.visibility = View.INVISIBLE
editableCheckbox.isEnabled = false
}
onEditingChanged() // we just locked the gui
val adapter = ArrayAdapter(
requireContext(),
R.layout.dropdown_menu_popup_item,
arrayOf("Item 1", "Item 2", "Item 3", "Item 4")
)
filled_exposed_dropdown.setAdapter(adapter)
}
private fun shareChannel() {
UIViewModel.getChannel(model.radioConfig.value)?.let { channel ->
GeeksvilleApplication.analytics.track(
"share",
DataPair("content_type", "channel")
) // track how many times users share channels
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, channel.getChannelUrl().toString())
putExtra(
Intent.EXTRA_TITLE,
getString(R.string.url_for_join)
)
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
requireActivity().startActivity(shareIntent)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
channelNameEdit.on(EditorInfo.IME_ACTION_DONE) {
requireActivity().hideKeyboard()
}
editableCheckbox.setOnCheckedChangeListener { _, checked ->
if (!checked) {
// User just locked it, we should warn and then apply changes to radio
/* Snackbar.make(
editableCheckbox,
"Changing channels is not yet supported",
Snackbar.LENGTH_SHORT
).show() */
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.change_channel)
.setMessage(R.string.are_you_sure_channel)
.setNeutralButton(R.string.cancel) { _, _ ->
setGUIfromModel()
}
.setPositiveButton(getString(R.string.accept)) { _, _ ->
// Generate a new channel with only the changes the user can change in the GUI
UIViewModel.getChannel(model.radioConfig.value)?.let { old ->
val newSettings = old.settings.toBuilder()
newSettings.name = channelNameEdit.text.toString().trim()
// FIXME, regenerate a new preshared key!
model.setChannel(newSettings.build())
// Since we are writing to radioconfig, that will trigger the rest of the GUI update (QR code etc)
}
}
.show()
}
onEditingChanged() // update GUI on what user is allowed to edit/share
}
// Share this particular channel if someone clicks share
shareButton.setOnClickListener {
shareChannel()
}
model.radioConfig.observe(viewLifecycleOwner, Observer { config ->
setGUIfromModel()
})
}
}
/*
@Composable
fun ChannelContent(channel: Channel?) {
val typography = MaterialTheme.typography
val context = ContextAmbient.current
Column(modifier = LayoutSize.Fill + LayoutPadding(16.dp)) {
if (channel != null) {
Row(modifier = LayoutGravity.Center) {
Text(text = "Channel ", modifier = LayoutGravity.Center)
if (channel.editable) {
// FIXME - limit to max length
StyledTextField(
value = channel.name,
onValueChange = { channel.name = it },
textStyle = typography.h4.copy(
color = palette.onSecondary.copy(alpha = 0.8f)
),
imeAction = ImeAction.Done,
onImeActionPerformed = {
ChannelLog.errormsg("FIXME, implement channel edit button")
}
)
} else {
Text(
text = channel.name,
style = typography.h4
)
}
}
// simulated qr code
// val image = imageResource(id = R.drawable.qrcode)
val image = AndroidImage(channel.getChannelQR())
ScaledImage(
image = image,
modifier = LayoutGravity.Center + LayoutSize.Min(200.dp, 200.dp)
)
Text(
text = "Mode: ${channel.modemConfig.toHumanString()}",
modifier = LayoutGravity.Center + LayoutPadding(bottom = 16.dp)
)
Row(modifier = LayoutGravity.Center) {
OutlinedButton(onClick = {
channel.editable = !channel.editable
}) {
if (channel.editable)
VectorImage(
id = R.drawable.ic_twotone_lock_open_24,
tint = palette.onBackground
)
else
VectorImage(
id = R.drawable.ic_twotone_lock_24,
tint = palette.onBackground
)
}
// Only show the share buttone once we are locked
if (!channel.editable)
OutlinedButton(modifier = LayoutPadding(start = 24.dp),
onClick = {
}) {
VectorImage(
id = R.drawable.ic_twotone_share_24,
tint = palette.onBackground
)
}
}
}
}
}
*/