Merge branch 'meshtastic:master' into osmdroid-phase2

pull/489/head
PWRxPSYCHO 2022-09-30 16:37:24 -04:00 zatwierdzone przez GitHub
commit 640737adeb
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
19 zmienionych plików z 230 dodań i 253 usunięć

Wyświetl plik

@ -88,13 +88,16 @@ interface IMeshService {
void setChannels(in byte []payload);
/// Send Shutdown admin packet to nodeNum
void requestShutdown(in String nodeId);
void requestShutdown(in int idNum);
/// Send Reboot admin packet to nodeNum
void requestReboot(in String nodeId);
void requestReboot(in int idNum);
/// Send FactoryReset admin packet to nodeNum
void requestFactoryReset(in String nodeId);
void requestFactoryReset(in int idNum);
/// Send NodedbReset admin packet to nodeNum
void requestNodedbReset(in int idNum);
/**
Is the packet radio currently connected to the phone? Returns a ConnectionState string.

Wyświetl plik

@ -237,11 +237,6 @@ class UIViewModel @Inject constructor(
// We consider hasWifi = ESP32
fun isESP32() = myNodeInfo.value?.hasWifi == true
fun hasAXP(): Boolean {
val hasAXP = listOf(4, 7, 9) // mesh.proto 'HardwareModel' enums with AXP192 chip
return hasAXP.contains(nodeDB.ourNodeInfo?.user?.hwModel?.number)
}
/// hardware info about our local device (can be null)
private val _myNodeInfo = MutableLiveData<MyNodeInfo?>()
val myNodeInfo: LiveData<MyNodeInfo?> get() = _myNodeInfo
@ -360,16 +355,36 @@ class UIViewModel @Inject constructor(
}
}
fun requestShutdown() {
meshService?.requestShutdown(DataPacket.ID_LOCAL)
fun requestShutdown(idNum: Int) {
try {
meshService?.requestShutdown(idNum)
} catch (ex: RemoteException) {
errormsg("RemoteException: ${ex.message}")
}
}
fun requestReboot() {
meshService?.requestReboot(DataPacket.ID_LOCAL)
fun requestReboot(idNum: Int) {
try {
meshService?.requestReboot(idNum)
} catch (ex: RemoteException) {
errormsg("RemoteException: ${ex.message}")
}
}
fun requestFactoryReset() {
meshService?.requestFactoryReset(DataPacket.ID_LOCAL)
fun requestFactoryReset(idNum: Int) {
try {
meshService?.requestFactoryReset(idNum)
} catch (ex: RemoteException) {
errormsg("RemoteException: ${ex.message}")
}
}
fun requestNodedbReset(idNum: Int) {
try {
meshService?.requestNodedbReset(idNum)
} catch (ex: RemoteException) {
errormsg("RemoteException: ${ex.message}")
}
}
/**

Wyświetl plik

@ -1341,7 +1341,7 @@ class MeshService : Service(), Logging {
else {
discardNodeDB()
debug("Installing new node DB")
myNodeInfo = newMyNodeInfo// Install myNodeInfo as current
myNodeInfo = newMyNodeInfo // Install myNodeInfo as current
newNodes.forEach(::installNodeInfo)
newNodes.clear() // Just to save RAM ;-)
@ -1383,24 +1383,30 @@ class MeshService : Service(), Logging {
})
}
private fun requestShutdown(nodeId: String) {
sendToRadio(newMeshPacketTo(toNodeNum(nodeId)).buildAdminPacket {
private fun requestShutdown(idNum: Int) {
sendToRadio(newMeshPacketTo(idNum).buildAdminPacket {
shutdownSeconds = 5
})
}
private fun requestReboot(nodeId: String) {
sendToRadio(newMeshPacketTo(toNodeNum(nodeId)).buildAdminPacket {
private fun requestReboot(idNum: Int) {
sendToRadio(newMeshPacketTo(idNum).buildAdminPacket {
rebootSeconds = 5
})
}
private fun requestFactoryReset(nodeId: String) {
sendToRadio(newMeshPacketTo(toNodeNum(nodeId)).buildAdminPacket {
private fun requestFactoryReset(idNum: Int) {
sendToRadio(newMeshPacketTo(idNum).buildAdminPacket {
factoryReset = 1
})
}
private fun requestNodedbReset(idNum: Int) {
sendToRadio(newMeshPacketTo(idNum).buildAdminPacket {
nodedbReset = 1
})
}
/**
* Start the modern (REV2) API configuration flow
*/
@ -1721,16 +1727,20 @@ class MeshService : Service(), Logging {
stopLocationRequests()
}
override fun requestShutdown(nodeId: String) = toRemoteExceptions {
this@MeshService.requestShutdown(nodeId)
override fun requestShutdown(idNum: Int) = toRemoteExceptions {
this@MeshService.requestShutdown(idNum)
}
override fun requestReboot(nodeId: String) = toRemoteExceptions {
this@MeshService.requestReboot(nodeId)
override fun requestReboot(idNum: Int) = toRemoteExceptions {
this@MeshService.requestReboot(idNum)
}
override fun requestFactoryReset(nodeId: String) = toRemoteExceptions {
this@MeshService.requestFactoryReset(nodeId)
override fun requestFactoryReset(idNum: Int) = toRemoteExceptions {
this@MeshService.requestFactoryReset(idNum)
}
override fun requestNodedbReset(idNum: Int) = toRemoteExceptions {
this@MeshService.requestNodedbReset(idNum)
}
}
}

Wyświetl plik

@ -55,9 +55,6 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
binding.lsSleepView.isEnabled = connected && model.config.power.isPowerSaving
binding.positionBroadcastSwitch.isEnabled = connected
binding.lsSleepSwitch.isEnabled = connected && model.isESP32()
binding.shutdownButton.isEnabled = connected && model.hasAXP()
binding.rebootButton.isEnabled = connected
binding.factoryResetButton.isEnabled = connected
}
binding.positionBroadcastPeriodEditText.on(EditorInfo.IME_ACTION_DONE) {
@ -111,41 +108,5 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
debug("User changed isPowerSaving to $isChecked")
}
}
binding.shutdownButton.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setMessage("${getString(R.string.shutdown)}?")
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(getString(R.string.okay)) { _, _ ->
debug("User clicked requestShutdown")
model.requestShutdown()
}
.show()
}
binding.rebootButton.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setMessage("${getString(R.string.reboot)}?")
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(getString(R.string.okay)) { _, _ ->
debug("User clicked requestReboot")
model.requestReboot()
}
.show()
}
binding.factoryResetButton.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.are_you_sure_factory_reset)
.setMessage(R.string.factory_reset_description)
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(R.string.okay) { _, _ ->
model.requestFactoryReset()
}
.show()
}
}
}

Wyświetl plik

@ -379,12 +379,9 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener, OnSeek
val label = it.name + " " + formatAgo(it.expire)
marker = MarkerWithLabel(map, label)
marker.title = it.name
marker.snippet = it.description
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
marker.position = GeoPoint(it.latitudeI.toDouble(), it.longitudeI.toDouble())
marker.icon = ContextCompat.getDrawable(
requireActivity(),
R.drawable.ic_baseline_location_on_24
)
}
marker
}

Wyświetl plik

@ -3,8 +3,10 @@ package com.geeksville.mesh.ui
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
@ -12,13 +14,14 @@ import androidx.fragment.app.activityViewModels
import androidx.fragment.app.setFragmentResult
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.NodeInfo
import com.geeksville.mesh.R
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.databinding.AdapterNodeLayoutBinding
import com.geeksville.mesh.databinding.NodelistFragmentBinding
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.util.formatAgo
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import java.net.URLEncoder
@ -35,6 +38,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
// 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
class ViewHolder(itemView: AdapterNodeLayoutBinding) : RecyclerView.ViewHolder(itemView.root) {
val chipNode = itemView.chipNode
val nodeNameView = itemView.nodeNameView
val distanceView = itemView.distanceView
val coordsView = itemView.coordsView
@ -47,6 +51,90 @@ class UsersFragment : ScreenFragment("Users"), Logging {
private val nodesAdapter = object : RecyclerView.Adapter<ViewHolder>() {
private var nodes = arrayOf<NodeInfo>()
private fun popup(view: View, position: Int) {
val node = nodes[position]
val user = node.user
val showAdmin = position == 0 // TODO add admin channel check
val popup = PopupMenu(requireContext(), view)
popup.inflate(R.menu.menu_nodes)
popup.menu.findItem(R.id.direct_message).isVisible = position > 0
popup.menu.setGroupVisible(R.id.group_admin, showAdmin)
popup.setOnMenuItemClickListener { item: MenuItem ->
when (item.itemId) {
R.id.direct_message -> {
if (position > 0 && user != null) {
debug("calling MessagesFragment filter: 0${user.id}")
setFragmentResult(
"requestKey",
bundleOf(
"contactKey" to "0${user.id}",
"contactName" to user.longName
)
)
parentFragmentManager.beginTransaction()
.replace(R.id.mainActivityLayout, MessagesFragment())
.addToBackStack(null)
.commit()
}
}
R.id.reboot -> {
MaterialAlertDialogBuilder(requireContext())
.setTitle("${getString(R.string.reboot)}\n${user?.longName}?")
.setIcon(R.drawable.ic_twotone_warning_24)
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(getString(R.string.okay)) { _, _ ->
debug("User clicked requestReboot")
model.requestReboot(node.num)
}
.show()
}
R.id.shutdown -> {
MaterialAlertDialogBuilder(requireContext())
.setTitle("${getString(R.string.shutdown)}\n${user?.longName}?")
.setIcon(R.drawable.ic_twotone_warning_24)
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(getString(R.string.okay)) { _, _ ->
debug("User clicked requestShutdown")
model.requestShutdown(node.num)
}
.show()
}
R.id.factory_reset -> {
MaterialAlertDialogBuilder(requireContext())
.setTitle("${getString(R.string.factory_reset)}\n${user?.longName}?")
.setIcon(R.drawable.ic_twotone_warning_24)
.setMessage(R.string.factory_reset_description)
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(R.string.okay) { _, _ ->
debug("User clicked requestFactoryReset")
model.requestFactoryReset(node.num)
}
.show()
}
R.id.nodedb_reset -> {
MaterialAlertDialogBuilder(requireContext())
.setTitle("${getString(R.string.nodedb_reset)}\n${user?.longName}?")
.setIcon(R.drawable.ic_twotone_warning_24)
.setMessage(R.string.nodedb_reset_description)
.setNeutralButton(R.string.cancel) { _, _ ->
}
.setPositiveButton(getString(R.string.okay)) { _, _ ->
debug("User clicked requestNodedbReset")
model.requestNodedbReset(node.num)
}
.show()
}
}
true
}
popup.show()
}
/**
* Called when RecyclerView needs a new [ViewHolder] of the given type to represent
* an item.
@ -110,7 +198,9 @@ class UsersFragment : ScreenFragment("Users"), Logging {
*/
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val n = nodes[position]
val name = n.user?.longName ?: n.user?.id ?: "Unknown node"
val user = n.user
holder.chipNode.text = user?.shortName ?: "UNK"
val name = user?.longName ?: "Unknown node"
holder.nodeNameView.text = name
val pos = n.validPosition
@ -165,25 +255,15 @@ class UsersFragment : ScreenFragment("Users"), Logging {
holder.signalView.visibility = View.INVISIBLE
}
}
holder.chipNode.setOnClickListener {
popup(it, position)
}
holder.itemView.setOnLongClickListener {
val node = n.user
if (position > 0 && node != null) {
debug("calling MessagesFragment filter:${node.id}")
setFragmentResult(
"requestKey",
bundleOf("contactKey" to "0${node.id}", "contactName" to name)
)
parentFragmentManager.beginTransaction()
.replace(R.id.mainActivityLayout, MessagesFragment())
.addToBackStack(null)
.commit()
}
popup(it, position)
true
}
}
private var nodes = arrayOf<NodeInfo>()
/// Called when our node DB changes
fun onNodesChanged(nodesIn: Array<NodeInfo>) {
if (nodesIn.size > 1)
@ -210,10 +290,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
holder.batteryPctView.text = text
holder.powerIcon.setImageDrawable(context?.let {
ContextCompat.getDrawable(
it,
image
)
ContextCompat.getDrawable(it, image)
})
}

Wyświetl plik

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,4c-4.41,0 -8,3.59 -8,8s3.59,8 8,8 8,-3.59 8,-8 -3.59,-8 -8,-8zM13,18h-2v-2h2v2zM13,15h-2c0,-3.25 3,-3 3,-5 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,10c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,2.5 -3,2.75 -3,5z"
android:fillAlpha=".3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M11,16h2v2h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
</vector>

Wyświetl plik

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,5c-3.87,0 -7,3.13 -7,7h2c0,-2.76 2.24,-5 5,-5s5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM13,14.29c0.88,-0.39 1.5,-1.26 1.5,-2.29 0,-1.38 -1.12,-2.5 -2.5,-2.5S9.5,10.62 9.5,12c0,1.02 0.62,1.9 1.5,2.29v3.3L7.59,21 9,22.41l3,-3 3,3L16.41,21 13,17.59v-3.3zM12,1C5.93,1 1,5.93 1,12h2c0,-4.97 4.03,-9 9,-9s9,4.03 9,9h2c0,-6.07 -4.93,-11 -11,-11z"/>
</vector>

Wyświetl plik

@ -1,18 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,16c-2.69,0 -5.77,1.28 -6,2h12c-0.2,-0.71 -3.3,-2 -6,-2z"
android:fillAlpha=".3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M12,8m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:fillAlpha=".3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4zM6,18c0.22,-0.72 3.31,-2 6,-2 2.7,0 5.8,1.29 6,2L6,18zM12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,6c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2z"/>
</vector>

Wyświetl plik

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillAlpha="0.3"
android:fillColor="@android:color/white"
android:pathData="M4.47,19h15.06L12,5.99 4.47,19zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"
android:strokeAlpha="0.3" />
<path
android:fillColor="@android:color/white"
android:pathData="M1,21h22L12,2 1,21zM4.47,19L12,5.99 19.53,19L4.47,19zM11,16h2v2h-2zM11,10h2v4h-2z" />
</vector>

Wyświetl plik

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M7.72,17.7l3.47,-1.53 0.81,-0.36 0.81,0.36 3.47,1.53L12,7.27z"
android:fillAlpha=".3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M4.5,20.29l0.71,0.71L12,18l6.79,3 0.71,-0.71L12,2 4.5,20.29zM12.81,16.17l-0.81,-0.36 -0.81,0.36 -3.47,1.53L12,7.27l4.28,10.43 -3.47,-1.53z"/>
</vector>

Wyświetl plik

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M17,4h3v16h-3L17,4zM5,14h3v6L5,20v-6zM11,9h3v11h-3L11,9z"/>
</vector>

Wyświetl plik

@ -18,10 +18,11 @@
<com.google.android.material.chip.Chip
android:id="@+id/shortName"
android:layout_width="wrap_content"
android:layout_width="72dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/some_username"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Wyświetl plik

@ -15,19 +15,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
<com.google.android.material.chip.Chip
android:id="@+id/chip_node"
android:layout_width="72dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:contentDescription="@string/user_avatar"
android:scaleType="center"
android:scaleX="1.5"
android:scaleY="1.5"
app:layout_constraintEnd_toEndOf="@+id/distance_view"
app:layout_constraintStart_toStartOf="@+id/distance_view"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_twotone_person_24" />
android:layout_margin="8dp"
android:text="@string/some_username"
android:textAlignment="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/nodeNameView"
@ -35,32 +31,27 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/unknown_username"
app:layout_constraintStart_toEndOf="@+id/distance_view"
app:layout_constraintTop_toTopOf="@+id/imageView" />
app:layout_constraintStart_toEndOf="@+id/chip_node"
app:layout_constraintTop_toTopOf="@+id/chip_node" />
<TextView
android:id="@+id/distance_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_margin="8dp"
android:text="@string/sample_distance"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
app:layout_constraintEnd_toEndOf="@+id/chip_node"
app:layout_constraintStart_toStartOf="@+id/chip_node"
app:layout_constraintTop_toBottomOf="@+id/chip_node" />
<TextView
android:id="@+id/coords_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_margin="8dp"
android:text="@string/sample_coords"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toEndOf="@+id/distance_view"
app:layout_constraintStart_toEndOf="@+id/chip_node"
app:layout_constraintTop_toBottomOf="@+id/nodeNameView"
app:layout_constraintVertical_bias="0.0" />
@ -68,10 +59,10 @@
android:id="@+id/batteryIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="@+id/batteryPercentageView"
app:layout_constraintEnd_toStartOf="@+id/batteryPercentageView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toTopOf="@+id/batteryPercentageView"
app:srcCompat="@drawable/ic_battery_full_24" />
<TextView
@ -80,48 +71,46 @@
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="100%"
app:layout_constraintBottom_toBottomOf="@+id/batteryIcon"
app:layout_constraintBottom_toBottomOf="@+id/nodeNameView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/batteryIcon" />
app:layout_constraintTop_toTopOf="@+id/nodeNameView" />
<ImageView
android:id="@+id/lastCommIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@id/batteryIcon"
app:layout_constraintBottom_toTopOf="@id/signalView"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="@+id/lastConnectionView"
app:layout_constraintEnd_toStartOf="@+id/lastConnectionView"
app:layout_constraintTop_toTopOf="@+id/lastConnectionView"
app:srcCompat="@drawable/ic_antenna_24" />
<TextView
android:id="@+id/lastConnectionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_margin="8dp"
android:text="11h01 PM"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/lastCommIcon"
app:layout_constraintBottom_toBottomOf="@+id/coords_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/lastCommIcon" />
app:layout_constraintTop_toTopOf="@+id/coords_view" />
<TextView
android:id="@+id/signalView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_margin="8dp"
android:text="rssi:-40 snr:-8"
app:layout_constraintBottom_toTopOf="@id/envMetrics"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/lastConnectionView"
app:layout_constraintBottom_toTopOf="@id/envMetrics" />
app:layout_constraintTop_toBottomOf="@id/lastConnectionView" />
<TextView
android:id="@+id/envMetrics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_margin="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

Wyświetl plik

@ -66,38 +66,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/lsSleepView" />
<com.google.android.material.button.MaterialButton
android:id="@+id/shutdownButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="4dp"
android:text="@string/shutdown"
app:layout_constraintEnd_toStartOf="@id/rebootButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/lsSleepView" />
<com.google.android.material.button.MaterialButton
android:id="@+id/rebootButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="16dp"
android:text="@string/reboot"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/shutdownButton"
app:layout_constraintTop_toTopOf="@id/shutdownButton" />
<com.google.android.material.button.MaterialButton
android:id="@+id/factoryResetButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/factory_reset"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/shutdownButton" />
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -58,7 +58,6 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:entries="@array/regions"
android:theme="@style/AppTheme.Spinner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/regionLabel"

Wyświetl plik

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/direct_message"
android:title="@string/direct_message"
app:showAsAction="withText" />
<group android:id="@+id/group_admin">
<item
android:id="@+id/reboot"
android:title="@string/reboot"
app:showAsAction="withText" />
<item
android:id="@+id/shutdown"
android:title="@string/shutdown"
app:showAsAction="withText" />
<item
android:id="@+id/factory_reset"
android:title="@string/factory_reset"
app:showAsAction="withText" />
<item
android:id="@+id/nodedb_reset"
android:title="@string/nodedb_reset"
app:showAsAction="withText" />
</group>
</menu>

Wyświetl plik

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="regions">
<!-- FIXME - better to get this through reflection -->
<item>Unset</item>
<item>US</item>
<item>EU433</item>
<item>EU868</item>
<item>CN</item>
<item>JP</item>
<item>ANZ</item>
<item>KR</item>
<item>TW</item>
<item>RU</item>
<item>IN</item>
<item>TH</item>
</array>
</resources>

Wyświetl plik

@ -151,8 +151,10 @@
<string name="mode_instant">Instantly send</string>
<string name="warning_default_psk">Empty channel names use the default encryption key (any device on %s can read your messages).</string>
<string name="factory_reset">Factory reset</string>
<string name="are_you_sure_factory_reset">Are you sure you want to factory reset?</string>
<string name="factory_reset_description">This will clear all device configuration you have done.</string>
<string name="bluetooth_disabled">Bluetooth disabled.</string>
<string name="permission_missing_31">Meshtastic needs Nearby devices permission to find and connect to devices via Bluetooth. You can turn it off when not in use.</string>
<string name="direct_message">Direct Message</string>
<string name="nodedb_reset">NodeDB reset</string>
<string name="nodedb_reset_description">This will clear all nodes from this list.</string>
</resources>