finally got a fully working base
This commit is contained in:
parent
975a8b9d8c
commit
3553659155
6 changed files with 199 additions and 46 deletions
|
@ -6,18 +6,22 @@ import androidx.activity.compose.setContent
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import pet.catcomm.ui.compose.BottomBar
|
||||
import pet.catcomm.ui.compose.Intro
|
||||
import pet.catcomm.ui.compose.Peers
|
||||
import pet.catcomm.ui.compose.SettingsPanel
|
||||
import pet.catcomm.ui.compose.TopBar
|
||||
import pet.catcomm.ui.theme.CatCommTheme
|
||||
import pet.catcomm.ui.viewmodel.DataStoreViewModel
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -30,8 +34,11 @@ class MainActivity : ComponentActivity() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun CatCommApp() {
|
||||
fun CatCommApp(
|
||||
dataStoreViewModel: DataStoreViewModel = viewModel(factory = DataStoreViewModel.Factory),
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
val shouldShowIntro = dataStoreViewModel.settings.username.collectAsState().value == ""
|
||||
|
||||
val currentBackStack by navController.currentBackStackEntryAsState()
|
||||
val currentCCBackStackDestination = currentBackStack?.destination
|
||||
|
@ -39,24 +46,34 @@ fun CatCommApp() {
|
|||
navBarTabs.find { tab -> tab.route == currentCCBackStackDestination?.route }
|
||||
|
||||
CatCommTheme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopBar(tabTitle = currentCCDestination?.label)
|
||||
},
|
||||
bottomBar = {
|
||||
BottomBar(
|
||||
pages = navBarTabs,
|
||||
currentPageRoute = currentCCDestination?.route,
|
||||
onSelect = { selected ->
|
||||
navController.navigateSingleTo(selected.route)
|
||||
if (shouldShowIntro) {
|
||||
Intro(
|
||||
onConfirm = { name ->
|
||||
if (name != "") {
|
||||
dataStoreViewModel.changeUsername(name)
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopBar(tabTitle = currentCCDestination?.label)
|
||||
},
|
||||
bottomBar = {
|
||||
BottomBar(
|
||||
pages = navBarTabs,
|
||||
currentPageRoute = currentCCDestination?.route,
|
||||
onSelect = { selected ->
|
||||
navController.navigateSingleTo(selected.route)
|
||||
}
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
CatCommNavHost(
|
||||
navController = navController,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
CatCommNavHost(
|
||||
navController = navController,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,17 +82,23 @@ fun CatCommApp() {
|
|||
fun CatCommNavHost(
|
||||
navController: NavHostController,
|
||||
modifier: Modifier = Modifier,
|
||||
dataStoreViewModel: DataStoreViewModel = viewModel(factory = DataStoreViewModel.Factory),
|
||||
) {
|
||||
val settings = dataStoreViewModel.settings
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Overview.route,
|
||||
modifier = modifier,
|
||||
) {
|
||||
composable(route = Overview.route) {
|
||||
Peers()
|
||||
Peers(settings)
|
||||
}
|
||||
composable(route = Settings.route) {
|
||||
SettingsPanel()
|
||||
SettingsPanel(
|
||||
settings = settings,
|
||||
onSave = { dataStoreViewModel.changeUsername(it.username) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
117
app/src/main/java/pet/catcomm/ui/compose/Intro.kt
Normal file
117
app/src/main/java/pet/catcomm/ui/compose/Intro.kt
Normal file
|
@ -0,0 +1,117 @@
|
|||
package pet.catcomm.ui.compose
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.BasicAlertDialog
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import pet.catcomm.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun Intro(
|
||||
onConfirm: (name: String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(8.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(stringResource(R.string.intro_enter_a_username_label))
|
||||
|
||||
var username by rememberSaveable { mutableStateOf("") }
|
||||
var error by rememberSaveable { mutableStateOf("") }
|
||||
|
||||
TextField(
|
||||
value = username,
|
||||
onValueChange = {
|
||||
username = it
|
||||
if (it != "" && error != "") {
|
||||
error = ""
|
||||
}
|
||||
},
|
||||
label = { Text(stringResource(R.string.intro_label_username_field)) },
|
||||
placeholder = { Text(stringResource(R.string.intro_placeholder_username_field)) },
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
supportingText = { Text(error) },
|
||||
isError = error != "",
|
||||
singleLine = true,
|
||||
)
|
||||
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
if (username == "") {
|
||||
error = "You need one."
|
||||
} else {
|
||||
onConfirm(username)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.padding(top = 32.dp),
|
||||
) {
|
||||
Text("Start CatComm")
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
var openDialog by remember { mutableStateOf(false) }
|
||||
|
||||
if (openDialog) {
|
||||
BasicAlertDialog(
|
||||
onDismissRequest = { openDialog = false },
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.padding(16.dp).fillMaxWidth().height(120.dp),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Use your words, bottom",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.Center),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextButton(
|
||||
onClick = { openDialog = true }
|
||||
) {
|
||||
Text("Need help choosing?")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,15 +10,12 @@ import androidx.compose.material3.CardDefaults
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import kotlinx.coroutines.delay
|
||||
import pet.catcomm.ui.theme.CatCommTheme
|
||||
import pet.catcomm.ui.viewmodel.DataStoreViewModel
|
||||
import pet.catcomm.ui.viewmodel.CatCommSettings
|
||||
|
||||
@Composable
|
||||
fun Peer(name: String, modifier: Modifier = Modifier) {
|
||||
|
@ -46,16 +43,10 @@ fun PeerPreview() {
|
|||
|
||||
@Composable
|
||||
fun Peers(
|
||||
settings: CatCommSettings,
|
||||
modifier: Modifier = Modifier,
|
||||
dataStoreViewModel: DataStoreViewModel = viewModel(factory = DataStoreViewModel.Factory),
|
||||
) {
|
||||
val username = dataStoreViewModel.username.collectAsStateWithLifecycle("")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
// Test: it'll change the username setting after 2s and this should refresh the UI as expected
|
||||
delay(2000)
|
||||
dataStoreViewModel.changeUsername("woof")
|
||||
}
|
||||
val username = settings.username.collectAsStateWithLifecycle("")
|
||||
|
||||
LazyColumn(modifier = modifier.padding(vertical = 4.dp)) {
|
||||
items(items = listOf("nyx", "1686a", "8098", username.value)) { name ->
|
||||
|
@ -63,11 +54,3 @@ fun Peers(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun PeersPreview() {
|
||||
CatCommTheme {
|
||||
Peers()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -14,16 +15,21 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import pet.catcomm.ui.viewmodel.CatCommSettings
|
||||
|
||||
data class SettingsForm(val username: String)
|
||||
|
||||
@Composable
|
||||
fun SettingsPanel(
|
||||
modifier: Modifier = Modifier
|
||||
settings: CatCommSettings,
|
||||
onSave: (SettingsForm) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var usernameState by rememberSaveable { mutableStateOf("") }
|
||||
var usernameState by rememberSaveable { mutableStateOf(settings.username.value) }
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
) {
|
||||
TextField(
|
||||
value = usernameState,
|
||||
|
@ -31,7 +37,23 @@ fun SettingsPanel(
|
|||
modifier = modifier.fillMaxWidth(),
|
||||
label = { Text("Username") },
|
||||
placeholder = { Text("i mean, you??") },
|
||||
singleLine = true,
|
||||
)
|
||||
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
onSave(
|
||||
SettingsForm(
|
||||
usernameState
|
||||
)
|
||||
)
|
||||
},
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
) {
|
||||
Text("Save settings")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,16 @@ private const val PREFERENCES = "settings"
|
|||
|
||||
const val SETTINGS_USERNAME_KEY = "cat_comm_username"
|
||||
|
||||
data class CatCommSettings(val username: StateFlow<String>)
|
||||
|
||||
class DataStoreViewModel(
|
||||
private val prefs: SharedPreferences,
|
||||
) : ViewModel(), OnSharedPreferenceChangeListener {
|
||||
private var _username: MutableStateFlow<String> =
|
||||
MutableStateFlow(prefs.getString(SETTINGS_USERNAME_KEY, "")!!)
|
||||
val username: StateFlow<String>
|
||||
get() = _username.asStateFlow()
|
||||
|
||||
val settings: CatCommSettings
|
||||
get() = CatCommSettings(_username.asStateFlow())
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (sharedPreferences != prefs) {
|
||||
|
@ -42,8 +45,10 @@ class DataStoreViewModel(
|
|||
}
|
||||
|
||||
fun changeUsername(new: String) {
|
||||
prefs.edit(true) {
|
||||
putString(SETTINGS_USERNAME_KEY, new)
|
||||
if (_username.value != new && new != "") {
|
||||
prefs.edit(true) {
|
||||
putString(SETTINGS_USERNAME_KEY, new)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,4 +2,7 @@
|
|||
<string name="app_name">CatComm</string>
|
||||
<string name="comms_tab_label">Comms</string>
|
||||
<string name="settings_tab_label">Settings</string>
|
||||
<string name="intro_enter_a_username_label">To start, enter a username</string>
|
||||
<string name="intro_placeholder_username_field">puppy :3</string>
|
||||
<string name="intro_label_username_field">Your username?</string>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Reference in a new issue