kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
start cleaning up models
rodzic
52deba7d4b
commit
f18ac28dc0
app/src/main/java/com/geeksville/mesh
|
@ -16,8 +16,13 @@ import androidx.core.app.ActivityCompat
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.ui.core.setContent
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.model.MessagesState
|
||||
import com.geeksville.mesh.model.NodeDB
|
||||
import com.geeksville.mesh.model.TextMessage
|
||||
import com.geeksville.mesh.model.UIState
|
||||
import com.geeksville.mesh.service.*
|
||||
import com.geeksville.mesh.ui.*
|
||||
import com.geeksville.mesh.ui.MeshApp
|
||||
import com.geeksville.mesh.ui.getInitials
|
||||
import com.geeksville.util.exceptionReporter
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||
|
@ -315,7 +320,12 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
// FIXME - use the real time from the packet
|
||||
// FIXME - don't just slam in a new list each time, it probably causes extra drawing. Figure out how to be Compose smarter...
|
||||
val modded = MessagesState.messages.value.toMutableList()
|
||||
modded.add(TextMessage(sender, payload.toString(utf8)))
|
||||
modded.add(
|
||||
TextMessage(
|
||||
sender,
|
||||
payload.toString(utf8)
|
||||
)
|
||||
)
|
||||
MessagesState.messages.value = modded
|
||||
}
|
||||
else -> TODO()
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.geeksville.mesh.model
|
||||
|
||||
import androidx.compose.mutableStateOf
|
||||
import com.geeksville.android.Logging
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* the model object for a text message
|
||||
*/
|
||||
data class TextMessage(val from: String, val text: String, val date: Date = Date())
|
||||
|
||||
|
||||
object MessagesState : Logging {
|
||||
val testTexts = listOf(
|
||||
TextMessage(
|
||||
"+16508675310",
|
||||
"I found the cache"
|
||||
),
|
||||
TextMessage(
|
||||
"+16508675311",
|
||||
"Help! I've fallen and I can't get up."
|
||||
)
|
||||
)
|
||||
|
||||
// If the following (unused otherwise) line is commented out, the IDE preview window works.
|
||||
// if left in the preview always renders as empty.
|
||||
val messages = mutableStateOf(testTexts, { a, b ->
|
||||
a.size == b.size // If the # of messages changes, consider it important for rerender
|
||||
})
|
||||
|
||||
fun addMessage(m: TextMessage) {
|
||||
val l = messages.value.toMutableList()
|
||||
l.add(m)
|
||||
messages.value = l
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.geeksville.mesh.model
|
||||
|
||||
import androidx.compose.mutableStateOf
|
||||
import com.geeksville.mesh.MeshUser
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.Position
|
||||
|
||||
object NodeDB {
|
||||
private val testPositions = arrayOf(
|
||||
Position(32.776665, -96.796989, 35), // dallas
|
||||
Position(32.960758, -96.733521, 35), // richardson
|
||||
Position(
|
||||
32.912901,
|
||||
-96.781776,
|
||||
35
|
||||
) // north dallas
|
||||
)
|
||||
|
||||
val testNodeNoPosition = NodeInfo(
|
||||
8,
|
||||
MeshUser(
|
||||
"+16508765308".format(8),
|
||||
"Kevin MesterNoLoc",
|
||||
"KLO"
|
||||
),
|
||||
null,
|
||||
12345
|
||||
)
|
||||
|
||||
val testNodes = testPositions.mapIndexed { index, it ->
|
||||
NodeInfo(
|
||||
9 + index,
|
||||
MeshUser(
|
||||
"+165087653%02d".format(9 + index),
|
||||
"Kevin Mester$index",
|
||||
"KM$index"
|
||||
),
|
||||
it,
|
||||
12345
|
||||
)
|
||||
}
|
||||
|
||||
/// The unique ID of our node
|
||||
val myId = mutableStateOf("+16508765309")
|
||||
|
||||
/// A map from nodeid to to nodeinfo
|
||||
val nodes = mutableStateOf(testNodes.map { it.user!!.id to it }.toMap())
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.geeksville.mesh.model
|
||||
|
||||
import android.util.Base64
|
||||
import androidx.compose.mutableStateOf
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
|
||||
/// FIXME - figure out how to merge this staate with the AppStatus Model
|
||||
object UIState {
|
||||
|
||||
/// Kinda ugly - created in the activity but used from Compose - figure out if there is a cleaner way GIXME
|
||||
// lateinit var googleSignInClient: GoogleSignInClient
|
||||
|
||||
|
||||
/// Are we connected to our radio device
|
||||
val isConnected = mutableStateOf(false)
|
||||
|
||||
/// various radio settings (including the channel)
|
||||
val radioConfig = mutableStateOf(MeshProtos.RadioConfig.getDefaultInstance())
|
||||
|
||||
/// our name in hte radio
|
||||
/// Note, we generate owner initials automatically for now
|
||||
val ownerName = mutableStateOf("fixme readfromprefs")
|
||||
|
||||
/// Return an URL that represents the current channel values
|
||||
val channelUrl
|
||||
get(): String {
|
||||
val channelBytes = radioConfig.value.channelSettings.toByteArray()
|
||||
val enc = Base64.encodeToString(channelBytes, Base64.URL_SAFE + Base64.NO_WRAP)
|
||||
|
||||
return "https://www.meshtastic.org/c/$enc"
|
||||
}
|
||||
}
|
|
@ -12,177 +12,175 @@ import kotlin.math.sin
|
|||
******************************************************************************/
|
||||
|
||||
|
||||
object LocationUtils {
|
||||
/**
|
||||
* Format as degrees, minutes, secs
|
||||
*
|
||||
* @param degIn
|
||||
* @param isLatitude
|
||||
* @return a string like 120deg
|
||||
*/
|
||||
fun degreesToDMS(
|
||||
_degIn: Double,
|
||||
isLatitude: Boolean
|
||||
): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn.toInt()
|
||||
val minutes = 60 * (degIn - degOut)
|
||||
val minwhole = minutes.toInt()
|
||||
val seconds = (minutes - minwhole) * 60
|
||||
return arrayOf(
|
||||
Integer.toString(degOut), Integer.toString(minwhole),
|
||||
java.lang.Double.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
/**
|
||||
* Format as degrees, minutes, secs
|
||||
*
|
||||
* @param degIn
|
||||
* @param isLatitude
|
||||
* @return a string like 120deg
|
||||
*/
|
||||
fun degreesToDMS(
|
||||
_degIn: Double,
|
||||
isLatitude: Boolean
|
||||
): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn.toInt()
|
||||
val minutes = 60 * (degIn - degOut)
|
||||
val minwhole = minutes.toInt()
|
||||
val seconds = (minutes - minwhole) * 60
|
||||
return arrayOf(
|
||||
Integer.toString(degOut), Integer.toString(minwhole),
|
||||
java.lang.Double.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
)
|
||||
}
|
||||
|
||||
fun degreesToDM(_degIn: Double, isLatitude: Boolean): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn.toInt()
|
||||
val minutes = 60 * (degIn - degOut)
|
||||
val seconds = 0
|
||||
return arrayOf(
|
||||
Integer.toString(degOut), java.lang.Double.toString(minutes),
|
||||
Integer.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
)
|
||||
}
|
||||
|
||||
fun degreesToD(_degIn: Double, isLatitude: Boolean): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn
|
||||
val minutes = 0
|
||||
val seconds = 0
|
||||
return arrayOf(
|
||||
java.lang.Double.toString(degOut), Integer.toString(minutes),
|
||||
Integer.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A not super efficent mapping from a starting lat/long + a distance at a
|
||||
* certain direction
|
||||
*
|
||||
* @param lat
|
||||
* @param longitude
|
||||
* @param distMeters
|
||||
* @param theta
|
||||
* in radians, 0 == north
|
||||
* @return an array with lat and long
|
||||
*/
|
||||
fun addDistance(
|
||||
lat: Double,
|
||||
longitude: Double,
|
||||
distMeters: Double,
|
||||
theta: Double
|
||||
): DoubleArray {
|
||||
val dx = distMeters * Math.sin(theta) // theta measured clockwise
|
||||
// from due north
|
||||
val dy = distMeters * Math.cos(theta) // dx, dy same units as R
|
||||
val dLong = dx / (111320 * Math.cos(lat)) // dx, dy in meters
|
||||
val dLat = dy / 110540 // result in degrees long/lat
|
||||
return doubleArrayOf(lat + dLat, longitude + dLong)
|
||||
}
|
||||
|
||||
fun LatLongToMeter(
|
||||
lat_a: Double,
|
||||
lng_a: Double,
|
||||
lat_b: Double,
|
||||
lng_b: Double
|
||||
): Double {
|
||||
val pk = (180 / 3.14169)
|
||||
val a1 = lat_a / pk
|
||||
val a2 = lng_a / pk
|
||||
val b1 = lat_b / pk
|
||||
val b2 = lng_b / pk
|
||||
val t1 =
|
||||
Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(
|
||||
b2
|
||||
)
|
||||
}
|
||||
|
||||
fun degreesToDM(_degIn: Double, isLatitude: Boolean): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn.toInt()
|
||||
val minutes = 60 * (degIn - degOut)
|
||||
val seconds = 0
|
||||
return arrayOf(
|
||||
Integer.toString(degOut), java.lang.Double.toString(minutes),
|
||||
Integer.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
val t2 =
|
||||
Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(
|
||||
b2
|
||||
)
|
||||
}
|
||||
val t3 = Math.sin(a1) * Math.sin(b1)
|
||||
var tt = Math.acos(t1 + t2 + t3)
|
||||
if (java.lang.Double.isNaN(tt)) tt = 0.0 // Must have been the same point?
|
||||
return 6366000 * tt
|
||||
}
|
||||
|
||||
fun degreesToD(_degIn: Double, isLatitude: Boolean): Array<String> {
|
||||
var degIn = _degIn
|
||||
val isPos = degIn >= 0
|
||||
val dirLetter =
|
||||
if (isLatitude) if (isPos) 'N' else 'S' else if (isPos) 'E' else 'W'
|
||||
degIn = Math.abs(degIn)
|
||||
val degOut = degIn
|
||||
val minutes = 0
|
||||
val seconds = 0
|
||||
return arrayOf(
|
||||
java.lang.Double.toString(degOut), Integer.toString(minutes),
|
||||
Integer.toString(seconds),
|
||||
Character.toString(dirLetter)
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Convert degrees/mins/secs to a single double
|
||||
*
|
||||
* @param degrees
|
||||
* @param minutes
|
||||
* @param seconds
|
||||
* @param isPostive
|
||||
* @return
|
||||
*/
|
||||
fun DMSToDegrees(
|
||||
degrees: Int,
|
||||
minutes: Int,
|
||||
seconds: Float,
|
||||
isPostive: Boolean
|
||||
): Double {
|
||||
return (if (isPostive) 1 else -1) * (degrees + minutes / 60.0 + seconds / 3600.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* A not super efficent mapping from a starting lat/long + a distance at a
|
||||
* certain direction
|
||||
*
|
||||
* @param lat
|
||||
* @param longitude
|
||||
* @param distMeters
|
||||
* @param theta
|
||||
* in radians, 0 == north
|
||||
* @return an array with lat and long
|
||||
*/
|
||||
fun addDistance(
|
||||
lat: Double,
|
||||
longitude: Double,
|
||||
distMeters: Double,
|
||||
theta: Double
|
||||
): DoubleArray {
|
||||
val dx = distMeters * Math.sin(theta) // theta measured clockwise
|
||||
// from due north
|
||||
val dy = distMeters * Math.cos(theta) // dx, dy same units as R
|
||||
val dLong = dx / (111320 * Math.cos(lat)) // dx, dy in meters
|
||||
val dLat = dy / 110540 // result in degrees long/lat
|
||||
return doubleArrayOf(lat + dLat, longitude + dLong)
|
||||
}
|
||||
fun DMSToDegrees(
|
||||
degrees: Double,
|
||||
minutes: Double,
|
||||
seconds: Double,
|
||||
isPostive: Boolean
|
||||
): Double {
|
||||
return (if (isPostive) 1 else -1) * (degrees + minutes / 60.0 + seconds / 3600.0)
|
||||
}
|
||||
|
||||
fun LatLongToMeter(
|
||||
lat_a: Double,
|
||||
lng_a: Double,
|
||||
lat_b: Double,
|
||||
lng_b: Double
|
||||
): Double {
|
||||
val pk = (180 / 3.14169)
|
||||
val a1 = lat_a / pk
|
||||
val a2 = lng_a / pk
|
||||
val b1 = lat_b / pk
|
||||
val b2 = lng_b / pk
|
||||
val t1 =
|
||||
Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(
|
||||
b2
|
||||
)
|
||||
val t2 =
|
||||
Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(
|
||||
b2
|
||||
)
|
||||
val t3 = Math.sin(a1) * Math.sin(b1)
|
||||
var tt = Math.acos(t1 + t2 + t3)
|
||||
if (java.lang.Double.isNaN(tt)) tt = 0.0 // Must have been the same point?
|
||||
return 6366000 * tt
|
||||
}
|
||||
/**
|
||||
* Computes the bearing in degrees between two points on Earth.
|
||||
*
|
||||
* @param lat1
|
||||
* Latitude of the first point
|
||||
* @param lon1
|
||||
* Longitude of the first point
|
||||
* @param lat2
|
||||
* Latitude of the second point
|
||||
* @param lon2
|
||||
* Longitude of the second point
|
||||
* @return Bearing between the two points in degrees. A value of 0 means due
|
||||
* north.
|
||||
*/
|
||||
fun bearing(
|
||||
lat1: Double,
|
||||
lon1: Double,
|
||||
lat2: Double,
|
||||
lon2: Double
|
||||
): Double {
|
||||
val lat1Rad = Math.toRadians(lat1)
|
||||
val lat2Rad = Math.toRadians(lat2)
|
||||
val deltaLonRad = Math.toRadians(lon2 - lon1)
|
||||
val y = sin(deltaLonRad) * cos(lat2Rad)
|
||||
val x =
|
||||
cos(lat1Rad) * sin(lat2Rad) - (sin(lat1Rad) * cos(lat2Rad)
|
||||
* Math.cos(deltaLonRad))
|
||||
return radToBearing(Math.atan2(y, x))
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert degrees/mins/secs to a single double
|
||||
*
|
||||
* @param degrees
|
||||
* @param minutes
|
||||
* @param seconds
|
||||
* @param isPostive
|
||||
* @return
|
||||
*/
|
||||
fun DMSToDegrees(
|
||||
degrees: Int,
|
||||
minutes: Int,
|
||||
seconds: Float,
|
||||
isPostive: Boolean
|
||||
): Double {
|
||||
return (if (isPostive) 1 else -1) * (degrees + minutes / 60.0 + seconds / 3600.0)
|
||||
}
|
||||
|
||||
fun DMSToDegrees(
|
||||
degrees: Double,
|
||||
minutes: Double,
|
||||
seconds: Double,
|
||||
isPostive: Boolean
|
||||
): Double {
|
||||
return (if (isPostive) 1 else -1) * (degrees + minutes / 60.0 + seconds / 3600.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the bearing in degrees between two points on Earth.
|
||||
*
|
||||
* @param lat1
|
||||
* Latitude of the first point
|
||||
* @param lon1
|
||||
* Longitude of the first point
|
||||
* @param lat2
|
||||
* Latitude of the second point
|
||||
* @param lon2
|
||||
* Longitude of the second point
|
||||
* @return Bearing between the two points in degrees. A value of 0 means due
|
||||
* north.
|
||||
*/
|
||||
fun bearing(
|
||||
lat1: Double,
|
||||
lon1: Double,
|
||||
lat2: Double,
|
||||
lon2: Double
|
||||
): Double {
|
||||
val lat1Rad = Math.toRadians(lat1)
|
||||
val lat2Rad = Math.toRadians(lat2)
|
||||
val deltaLonRad = Math.toRadians(lon2 - lon1)
|
||||
val y = sin(deltaLonRad) * cos(lat2Rad)
|
||||
val x =
|
||||
cos(lat1Rad) * sin(lat2Rad) - (sin(lat1Rad) * cos(lat2Rad)
|
||||
* Math.cos(deltaLonRad))
|
||||
return radToBearing(Math.atan2(y, x))
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an angle in radians to degrees
|
||||
*/
|
||||
fun radToBearing(rad: Double): Double {
|
||||
return (Math.toDegrees(rad) + 360) % 360
|
||||
}
|
||||
/**
|
||||
* Converts an angle in radians to degrees
|
||||
*/
|
||||
fun radToBearing(rad: Double): Double {
|
||||
return (Math.toDegrees(rad) + 360) % 360
|
||||
}
|
|
@ -18,6 +18,8 @@ import androidx.ui.tooling.preview.Preview
|
|||
import androidx.ui.unit.dp
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.NodeDB
|
||||
import com.geeksville.mesh.model.UIState
|
||||
|
||||
|
||||
object UILog : Logging
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import androidx.compose.Composable
|
||||
import androidx.compose.mutableStateOf
|
||||
import androidx.compose.state
|
||||
import androidx.ui.core.Modifier
|
||||
import androidx.ui.core.Text
|
||||
|
@ -20,37 +19,13 @@ import androidx.ui.material.surface.Surface
|
|||
import androidx.ui.text.TextStyle
|
||||
import androidx.ui.tooling.preview.Preview
|
||||
import androidx.ui.unit.dp
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.ui.MessagesState.messages
|
||||
import com.geeksville.mesh.model.MessagesState
|
||||
import com.geeksville.mesh.model.MessagesState.messages
|
||||
import com.geeksville.mesh.model.NodeDB
|
||||
import com.geeksville.mesh.model.TextMessage
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* the model object for a text message
|
||||
*/
|
||||
data class TextMessage(val from: String, val text: String, val date: Date = Date())
|
||||
|
||||
|
||||
object MessagesState : Logging {
|
||||
val testTexts = listOf(
|
||||
TextMessage("+6508675310", "I found the cache"),
|
||||
TextMessage("+6508675311", "Help! I've fallen and I can't get up.")
|
||||
)
|
||||
|
||||
// If the following (unused otherwise) line is commented out, the IDE preview window works.
|
||||
// if left in the preview always renders as empty.
|
||||
val messages = mutableStateOf(MessagesState.testTexts, { a, b ->
|
||||
a.size == b.size // If the # of messages changes, consider it important for rerender
|
||||
})
|
||||
|
||||
fun addMessage(m: TextMessage) {
|
||||
val l = messages.value.toMutableList()
|
||||
l.add(m)
|
||||
messages.value = l
|
||||
}
|
||||
}
|
||||
|
||||
private val dateFormat = SimpleDateFormat("h:mm a")
|
||||
|
||||
val TimestampEmphasis = object : Emphasis {
|
||||
|
@ -129,7 +104,12 @@ fun MessagesContent() {
|
|||
imeAction = ImeAction.Send,
|
||||
onImeActionPerformed = {
|
||||
MessagesState.info("did IME action")
|
||||
MessagesState.addMessage(TextMessage("fixme", message.value))
|
||||
MessagesState.addMessage(
|
||||
TextMessage(
|
||||
"fixme",
|
||||
message.value
|
||||
)
|
||||
)
|
||||
},
|
||||
modifier = LayoutPadding(4.dp)
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.ui.tooling.preview.Preview
|
|||
import androidx.ui.unit.dp
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.NodeDB
|
||||
import androidx.ui.core.Modifier as Modifier1
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.util.Base64
|
||||
import androidx.compose.Model
|
||||
import androidx.compose.mutableStateOf
|
||||
import com.geeksville.mesh.*
|
||||
import com.geeksville.mesh.R
|
||||
|
||||
|
||||
data class ScreenInfo(val icon: Int, val label: String)
|
||||
|
@ -22,72 +20,6 @@ object AppStatus {
|
|||
var currentScreen: ScreenInfo = Screen.messages
|
||||
}
|
||||
|
||||
object NodeDB {
|
||||
private val testPositions = arrayOf(
|
||||
Position(32.776665, -96.796989, 35), // dallas
|
||||
Position(32.960758, -96.733521, 35), // richardson
|
||||
Position(
|
||||
32.912901,
|
||||
-96.781776,
|
||||
35
|
||||
) // north dallas
|
||||
)
|
||||
|
||||
val testNodeNoPosition = NodeInfo(
|
||||
8,
|
||||
MeshUser(
|
||||
"+6508765308".format(8),
|
||||
"Kevin MesterNoLoc",
|
||||
"KLO"
|
||||
),
|
||||
null,
|
||||
12345
|
||||
)
|
||||
|
||||
val testNodes = testPositions.mapIndexed { index, it ->
|
||||
NodeInfo(
|
||||
9 + index,
|
||||
MeshUser(
|
||||
"+65087653%02d".format(9 + index),
|
||||
"Kevin Mester$index",
|
||||
"KM$index"
|
||||
),
|
||||
it,
|
||||
12345
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/// A map from nodeid to to nodeinfo
|
||||
val nodes = mutableStateOf(testNodes.map { it.user!!.id to it }.toMap())
|
||||
}
|
||||
|
||||
/// FIXME - figure out how to merge this staate with the AppStatus Model
|
||||
object UIState {
|
||||
|
||||
/// Kinda ugly - created in the activity but used from Compose - figure out if there is a cleaner way GIXME
|
||||
// lateinit var googleSignInClient: GoogleSignInClient
|
||||
|
||||
|
||||
/// Are we connected to our radio device
|
||||
val isConnected = mutableStateOf(false)
|
||||
|
||||
/// various radio settings (including the channel)
|
||||
val radioConfig = mutableStateOf(MeshProtos.RadioConfig.getDefaultInstance())
|
||||
|
||||
/// our name in hte radio
|
||||
/// Note, we generate owner initials automatically for now
|
||||
val ownerName = mutableStateOf("fixme readfromprefs")
|
||||
|
||||
/// Return an URL that represents the current channel values
|
||||
val channelUrl
|
||||
get(): String {
|
||||
val channelBytes = radioConfig.value.channelSettings.toByteArray()
|
||||
val enc = Base64.encodeToString(channelBytes, Base64.URL_SAFE + Base64.NO_WRAP)
|
||||
|
||||
return "https://www.meshtastic.org/c/$enc"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary solution pending navigation support.
|
||||
|
|
Ładowanie…
Reference in New Issue