WIP is a little better

pull/12/head
geeksville 2020-04-07 10:40:01 -07:00
rodzic 9491a74fc6
commit 5403b15044
11 zmienionych plików z 156 dodań i 107 usunięć

Wyświetl plik

@ -21,9 +21,9 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.ui.core.setContent import androidx.ui.core.setContent
import androidx.ui.foundation.Text
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.geeksville.android.GeeksvilleApplication
import com.geeksville.android.Logging import com.geeksville.android.Logging
import com.geeksville.android.ServiceClient import com.geeksville.android.ServiceClient
import com.geeksville.mesh.model.MessagesState import com.geeksville.mesh.model.MessagesState
@ -31,7 +31,7 @@ import com.geeksville.mesh.model.NodeDB
import com.geeksville.mesh.model.TextMessage import com.geeksville.mesh.model.TextMessage
import com.geeksville.mesh.model.UIState import com.geeksville.mesh.model.UIState
import com.geeksville.mesh.service.* import com.geeksville.mesh.service.*
import com.geeksville.mesh.ui.ScanState import com.geeksville.mesh.ui.*
import com.geeksville.util.Exceptions import com.geeksville.util.Exceptions
import com.geeksville.util.exceptionReporter import com.geeksville.util.exceptionReporter
import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignIn
@ -109,23 +109,31 @@ fun androidx.fragment.app.Fragment.setComposable(
} }
} }
class ComposeFragment(id: Int, private val content: @Composable() () -> Unit) : Fragment(), /**
* A fragment that represents a current 'screen' in our app.
*
* Useful for tracking analytics
*/
open class ScreenFragment(private val screenName: String) : Fragment() {
override fun onResume() {
super.onResume()
GeeksvilleApplication.analytics.sendScreenView(screenName)
}
override fun onPause() {
GeeksvilleApplication.analytics.endScreenView()
super.onPause()
}
}
class ComposeFragment(screenName: String, id: Int, private val content: @Composable() () -> Unit) :
ScreenFragment(screenName),
Logging { Logging {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? = ): View? =
setComposable(id, content) setComposable(id, content)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
debug("view w=${view.width}, h=${view.height}")
}
override fun onStart() {
super.onStart()
debug("view w=${view?.width}, h=${view?.height}")
}
} }
@ -144,9 +152,56 @@ class MainActivity : AppCompatActivity(), Logging,
bluetoothManager.adapter bluetoothManager.adapter
} }
private val tabsAdapter = object : FragmentStateAdapter(this) { /*
<!-- Screen.messages -> MessagesContent()
Screen.settings -> SettingsContent()
Screen.users -> UsersContent()
Screen.channel -> ChannelContent(UIState.getChannel())
Screen.map -> MapContent() -->
override fun getItemCount(): Int = 2 /--
<com.google.android.material.tabs.TabItem
android:icon="@drawable/ic_twotone_message_24"
android:text="Messages"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<com.google.android.material.tabs.TabItem
android:icon="@drawable/ic_twotone_settings_applications_24"
android:text="Settings"
android:layout_height="wrap_content"
android:layout_width="wrap_content" /> -->
*/
data class TabInfo(val text: String, val icon: Int, val content: Fragment)
// private val tabIndexes = generateSequence(0) { it + 1 } FIXME, instead do withIndex or zip? to get the ids below, also stop duplicating strings
private val tabInfos = arrayOf(
TabInfo(
"Messages",
R.drawable.ic_twotone_message_24,
ComposeFragment("Messages", 1) { MessagesContent() }),
TabInfo(
"Settings",
R.drawable.ic_twotone_settings_applications_24,
ComposeFragment("Settings", 2) { SettingsContent() }),
TabInfo(
"Users",
R.drawable.ic_twotone_people_24,
ComposeFragment("Users", 3) { UsersContent() }),
TabInfo(
"Channel",
R.drawable.ic_twotone_contactless_24,
ComposeFragment("Channel", 4) { ChannelContent(UIState.getChannel()) }),
TabInfo(
"Map",
R.drawable.ic_twotone_map_24,
ComposeFragment("Map", 5) { MapContent() })
)
private
val tabsAdapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int = tabInfos.size
override fun createFragment(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
// Return a NEW fragment instance in createFragment(int) // Return a NEW fragment instance in createFragment(int)
@ -155,9 +210,7 @@ class MainActivity : AppCompatActivity(), Logging,
// Our object is just an integer :-P // Our object is just an integer :-P
putInt(ARG_OBJECT, position + 1) putInt(ARG_OBJECT, position + 1)
} */ } */
return ComposeFragment(position + 1) { return tabInfos[position].content
Text("Jetpack Compose")
}
} }
} }
@ -255,7 +308,11 @@ class MainActivity : AppCompatActivity(), Logging,
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT) startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
} }
} else { } else {
Toast.makeText(this, "Error - this app requires bluetooth", Toast.LENGTH_LONG) Toast.makeText(
this,
"Error - this app requires bluetooth",
Toast.LENGTH_LONG
)
.show() .show()
} }
@ -289,7 +346,8 @@ class MainActivity : AppCompatActivity(), Logging,
val pager = findViewById<ViewPager2>(R.id.pager) val pager = findViewById<ViewPager2>(R.id.pager)
pager.adapter = tabsAdapter pager.adapter = tabsAdapter
TabLayoutMediator(tab_layout, pager) { tab, position -> TabLayoutMediator(tab_layout, pager) { tab, position ->
tab.text = "OBJECT ${(position + 1)}" tab.text = tabInfos[position].text
tab.icon = getDrawable(tabInfos[position].icon)
}.attach() }.attach()
} }
@ -323,7 +381,11 @@ class MainActivity : AppCompatActivity(), Logging,
/** /**
* Dispatch incoming result to the correct fragment. * Dispatch incoming result to the correct fragment.
*/ */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...); // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
@ -350,7 +412,8 @@ class MainActivity : AppCompatActivity(), Logging,
} */ } */
} }
private var receiverRegistered = false private
var receiverRegistered = false
private fun registerMeshReceiver() { private fun registerMeshReceiver() {
logAssert(!receiverRegistered) logAssert(!receiverRegistered)
@ -418,14 +481,17 @@ class MainActivity : AppCompatActivity(), Logging,
} }
} }
private val meshServiceReceiver = object : BroadcastReceiver() { private
val meshServiceReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) = exceptionReporter { override fun onReceive(context: Context, intent: Intent) =
exceptionReporter {
debug("Received from mesh service $intent") debug("Received from mesh service $intent")
when (intent.action) { when (intent.action) {
MeshService.ACTION_NODE_CHANGE -> { MeshService.ACTION_NODE_CHANGE -> {
val info: NodeInfo = intent.getParcelableExtra(EXTRA_NODEINFO)!! val info: NodeInfo =
intent.getParcelableExtra(EXTRA_NODEINFO)!!
debug("UI nodechange $info") debug("UI nodechange $info")
// We only care about nodes that have user info // We only care about nodes that have user info
@ -436,15 +502,20 @@ class MainActivity : AppCompatActivity(), Logging,
MeshService.ACTION_RECEIVED_DATA -> { MeshService.ACTION_RECEIVED_DATA -> {
debug("TODO rxdata") debug("TODO rxdata")
val sender = intent.getStringExtra(EXTRA_SENDER)!! val sender =
val payload = intent.getByteArrayExtra(EXTRA_PAYLOAD)!! intent.getStringExtra(EXTRA_SENDER)!!
val payload =
intent.getByteArrayExtra(EXTRA_PAYLOAD)!!
val typ = intent.getIntExtra(EXTRA_TYP, -1) val typ = intent.getIntExtra(EXTRA_TYP, -1)
when (typ) { when (typ) {
MeshProtos.Data.Type.CLEAR_TEXT_VALUE -> { MeshProtos.Data.Type.CLEAR_TEXT_VALUE -> {
// FIXME - use the real time from the packet // 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... // FIXME - don't just slam in a new list each time, it probably causes extra drawing. Figure out how to be Compose smarter...
val msg = TextMessage(sender, payload.toString(utf8)) val msg = TextMessage(
sender,
payload.toString(utf8)
)
MessagesState.addMessage(msg) MessagesState.addMessage(msg)
} }
@ -466,7 +537,9 @@ class MainActivity : AppCompatActivity(), Logging,
} }
private val mesh = object : ServiceClient<com.geeksville.mesh.IMeshService>({ private
val mesh = object :
ServiceClient<com.geeksville.mesh.IMeshService>({
com.geeksville.mesh.IMeshService.Stub.asInterface(it) com.geeksville.mesh.IMeshService.Stub.asInterface(it)
}) { }) {
override fun onConnected(service: com.geeksville.mesh.IMeshService) { override fun onConnected(service: com.geeksville.mesh.IMeshService) {
@ -476,7 +549,8 @@ class MainActivity : AppCompatActivity(), Logging,
registerMeshReceiver() registerMeshReceiver()
// We won't receive a notify for the initial state of connection, so we force an update here // We won't receive a notify for the initial state of connection, so we force an update here
val connectionState = MeshService.ConnectionState.valueOf(service.connectionState()) val connectionState =
MeshService.ConnectionState.valueOf(service.connectionState())
onMeshConnectionChanged(connectionState) onMeshConnectionChanged(connectionState)
debug("connected to mesh service, isConnected=${UIState.isConnected.value}") debug("connected to mesh service, isConnected=${UIState.isConnected.value}")
@ -522,7 +596,8 @@ class MainActivity : AppCompatActivity(), Logging,
bindMeshService() bindMeshService()
val bonded = RadioInterfaceService.getBondedDeviceAddress(this) != null val bonded =
RadioInterfaceService.getBondedDeviceAddress(this) != null
/* FIXME - not yet working /* FIXME - not yet working
if (!bonded) if (!bonded)
AppStatus.currentScreen = Screen.settings AppStatus.currentScreen = Screen.settings

Wyświetl plik

@ -1,12 +1,10 @@
package com.geeksville.mesh.ui package com.geeksville.mesh.ui
import androidx.compose.Composable
import androidx.compose.onCommit
import com.geeksville.android.GeeksvilleApplication
/** /**
* Track compose screen visibility * Track compose screen visibility
*/ */
/*
@Composable @Composable
fun analyticsScreen(name: String) { fun analyticsScreen(name: String) {
onCommit(AppStatus.currentScreen) { onCommit(AppStatus.currentScreen) {
@ -16,4 +14,4 @@ fun analyticsScreen(name: String) {
GeeksvilleApplication.analytics.endScreenView() GeeksvilleApplication.analytics.endScreenView()
} }
} }
} } */

Wyświetl plik

@ -1,21 +1,6 @@
package com.geeksville.mesh.ui package com.geeksville.mesh.ui
import androidx.annotation.DrawableRes /*
import androidx.compose.Composable
import androidx.ui.core.Modifier
import androidx.ui.foundation.Text
import androidx.ui.foundation.shape.corner.RoundedCornerShape
import androidx.ui.graphics.Color
import androidx.ui.layout.*
import androidx.ui.material.Divider
import androidx.ui.material.MaterialTheme
import androidx.ui.material.Surface
import androidx.ui.material.TextButton
import androidx.ui.tooling.preview.Preview
import androidx.ui.unit.dp
import com.geeksville.mesh.R
@Composable @Composable
fun AppDrawer( fun AppDrawer(
currentScreen: ScreenInfo, currentScreen: ScreenInfo,
@ -111,4 +96,4 @@ fun previewDrawer() {
currentScreen = AppStatus.currentScreen, currentScreen = AppStatus.currentScreen,
closeDrawer = { } closeDrawer = { }
) )
} } */

Wyświetl plik

@ -73,8 +73,8 @@ fun BTScanScreen() {
val bluetoothAdapter = val bluetoothAdapter =
(context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
analyticsScreen(name = "settings") // FIXME - remove onCommit now that we have a fragement to run in
onCommit(AppStatus.currentScreen) { onCommit() {
ScanState.debug("BTScan component active") ScanState.debug("BTScan component active")
ScanUIState.selectedMacAddr = RadioInterfaceService.getBondedDeviceAddress(context) ScanUIState.selectedMacAddr = RadioInterfaceService.getBondedDeviceAddress(context)

Wyświetl plik

@ -23,7 +23,6 @@ object ChannelLog : Logging
@Composable @Composable
fun ChannelContent(channel: Channel?) { fun ChannelContent(channel: Channel?) {
analyticsScreen(name = "channel")
val typography = MaterialTheme.typography val typography = MaterialTheme.typography
val context = ContextAmbient.current val context = ContextAmbient.current

Wyświetl plik

@ -75,11 +75,10 @@ private val mapLifecycleCallbacks = object : Application.ActivityLifecycleCallba
@Composable @Composable
fun MapContent() { fun MapContent() {
analyticsScreen(name = "map")
val context = ContextAmbient.current val context = ContextAmbient.current
onCommit(AppStatus.currentScreen) { // FIXME - remove onCommit
onCommit() {
onDispose { onDispose {
// We no longer care about activity lifecycle // We no longer care about activity lifecycle
(context.applicationContext as Application).unregisterActivityLifecycleCallbacks( (context.applicationContext as Application).unregisterActivityLifecycleCallbacks(

Wyświetl plik

@ -1,19 +1,14 @@
package com.geeksville.mesh.ui package com.geeksville.mesh.ui
import androidx.compose.Composable import androidx.ui.material.lightColorPalette
import androidx.compose.state
import androidx.ui.foundation.Text
import androidx.ui.material.*
import androidx.ui.tooling.preview.Preview
import com.geeksville.android.Logging import com.geeksville.android.Logging
import com.geeksville.mesh.R
import com.geeksville.mesh.model.UIState
object UILog : Logging object UILog : Logging
val palette = lightColorPalette() // darkColorPalette() val palette = lightColorPalette() // darkColorPalette()
/*
@Composable @Composable
fun MeshApp() { fun MeshApp() {
val (drawerState, onDrawerStateChange) = state { DrawerState.Closed } val (drawerState, onDrawerStateChange) = state { DrawerState.Closed }
@ -73,3 +68,4 @@ private fun AppContent(openDrawer: () -> Unit) {
} }
//} //}
} }
*/

Wyświetl plik

@ -67,8 +67,6 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) {
@Composable @Composable
fun MessagesContent() { fun MessagesContent() {
analyticsScreen(name = "messages")
Column(modifier = LayoutSize.Fill) { Column(modifier = LayoutSize.Fill) {
val sidePad = 8.dp val sidePad = 8.dp

Wyświetl plik

@ -1,9 +1,6 @@
package com.geeksville.mesh.ui package com.geeksville.mesh.ui
import androidx.compose.Model /*
import com.geeksville.mesh.R
data class ScreenInfo(val icon: Int, val label: String) data class ScreenInfo(val icon: Int, val label: String)
// defines the screens we have in the app // defines the screens we have in the app
@ -28,3 +25,4 @@ object AppStatus {
fun navigateTo(destination: ScreenInfo) { fun navigateTo(destination: ScreenInfo) {
AppStatus.currentScreen = destination AppStatus.currentScreen = destination
} }
*/

Wyświetl plik

@ -27,8 +27,6 @@ fun getInitials(name: String): String {
@Composable @Composable
fun UsersContent() { fun UsersContent() {
analyticsScreen(name = "users")
Column { Column {
Row { Row {
fun connected() = UIState.isConnected.value != MeshService.ConnectionState.DISCONNECTED fun connected() = UIState.isConnected.value != MeshService.ConnectionState.DISCONNECTED

Wyświetl plik

@ -32,6 +32,8 @@
Screen.channel -> ChannelContent(UIState.getChannel()) Screen.channel -> ChannelContent(UIState.getChannel())
Screen.map -> MapContent() --> Screen.map -> MapContent() -->
/--
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem
android:icon="@drawable/ic_twotone_message_24" android:icon="@drawable/ic_twotone_message_24"
android:text="Messages" android:text="Messages"
@ -43,6 +45,7 @@
android:text="Settings" android:text="Settings"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" /> android:layout_width="wrap_content" />
-->
</com.google.android.material.tabs.TabLayout> </com.google.android.material.tabs.TabLayout>