Skip to content

Commit

Permalink
Navigation main screens skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
sdsantos committed Jul 30, 2024
1 parent bb13929 commit 8cf60e6
Show file tree
Hide file tree
Showing 21 changed files with 404 additions and 78 deletions.
5 changes: 4 additions & 1 deletion composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ kotlin {
}
}
all {
languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
languageSettings {
optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
optIn("androidx.compose.material3.ExperimentalMaterial3Api")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package org.ooni.probe
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge

class MainActivity : ComponentActivity() {
private val app get() = applicationContext as AndroidApplication

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
App(app.dependencies)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:name="path"
android:pathData="M 520 360 L 520 120 L 840 120 L 840 360 L 520 360 Z M 120 520 L 120 120 L 440 120 L 440 520 L 120 520 Z M 520 840 L 520 440 L 840 440 L 840 840 L 520 840 Z M 120 840 L 120 600 L 440 600 L 440 840 L 120 840 Z M 200 440 L 360 440 L 360 200 L 200 200 L 200 440 Z M 600 760 L 760 760 L 760 520 L 600 520 L 600 760 Z M 600 280 L 760 280 L 760 200 L 600 200 L 600 280 Z M 200 760 L 360 760 L 360 680 L 200 680 L 200 760 Z M 360 440 Z M 600 280 Z M 600 520 Z M 360 680 Z"
android:fillColor="#000"
android:strokeWidth="1"/>
</vector>
13 changes: 13 additions & 0 deletions composeApp/src/commonMain/composeResources/drawable/ic_history.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:name="path_1"
android:pathData="M 480 840 Q 342 840 239.5 748.5 Q 137 657 122 520 L 204 520 Q 218 624 296.5 692 Q 375 760 480 760 Q 597 760 678.5 678.5 Q 760 597 760 480 Q 760 363 678.5 281.5 Q 597 200 480 200 Q 411 200 351 232 Q 291 264 250 320 L 360 320 L 360 400 L 120 400 L 120 160 L 200 160 L 200 254 Q 251 190 324.5 155 Q 398 120 480 120 Q 555 120 620.5 148.5 Q 686 177 734.5 225.5 Q 783 274 811.5 339.5 Q 840 405 840 480 Q 840 555 811.5 620.5 Q 783 686 734.5 734.5 Q 686 783 620.5 811.5 Q 555 840 480 840 Z M 592 648 L 440 496 L 440 280 L 520 280 L 520 464 L 648 592 L 592 648 Z"
android:fillColor="#000"
android:strokeWidth="1"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:name="path"
android:pathData="M 370 880 L 354 752 Q 341 747 329.5 740 Q 318 733 307 725 L 188 775 L 78 585 L 181 507 Q 180 500 180 493.5 L 180 466.5 Q 180 460 181 453 L 78 375 L 188 185 L 307 235 Q 318 227 330 220 Q 342 213 354 208 L 370 80 L 590 80 L 606 208 Q 619 213 630.5 220 Q 642 227 653 235 L 772 185 L 882 375 L 779 453 Q 780 460 780 466.5 L 780 493.5 Q 780 500 778 507 L 881 585 L 771 775 L 653 725 Q 642 733 630 740 Q 618 747 606 752 L 590 880 L 370 880 Z M 440 800 L 519 800 L 533 694 Q 564 686 590.5 670.5 Q 617 655 639 633 L 738 674 L 777 606 L 691 541 Q 696 527 698 511.5 Q 700 496 700 480 Q 700 464 698 448.5 Q 696 433 691 419 L 777 354 L 738 286 L 639 328 Q 617 305 590.5 289.5 Q 564 274 533 266 L 520 160 L 441 160 L 427 266 Q 396 274 369.5 289.5 Q 343 305 321 327 L 222 286 L 183 354 L 269 418 Q 264 433 262 448 Q 260 463 260 480 Q 260 496 262 511 Q 264 526 269 541 L 183 606 L 222 674 L 321 632 Q 343 655 369.5 670.5 Q 396 686 427 694 L 440 800 Z M 482 620 Q 540 620 581 579 Q 622 538 622 480 Q 622 422 581 381 Q 540 340 482 340 Q 423 340 382.5 381 Q 342 422 342 480 Q 342 538 382.5 579 Q 423 620 482 620 Z M 480 480 Z"
android:fillColor="#000"
android:strokeWidth="1"/>
</vector>
4 changes: 4 additions & 0 deletions composeApp/src/commonMain/composeResources/values/common.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<resources>
<string name="run_tests">Run Test</string>
<string name="back">Back</string>
<string name="dashboard">Dashboard</string>
<string name="test_results">Test Results</string>
<string name="settings">Settings</string>
</resources>
7 changes: 6 additions & 1 deletion composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import co.touchlab.kermit.Logger
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.ooni.probe.di.Dependencies
import org.ooni.probe.ui.AppTheme
import org.ooni.probe.ui.navigation.BottomNavigationBar
import org.ooni.probe.ui.navigation.Navigation

@Composable
Expand All @@ -24,7 +25,11 @@ fun App(dependencies: Dependencies) {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
Scaffold {
Scaffold(
bottomBar = {
BottomNavigationBar(navController)
},
) {
Navigation(
navController = navController,
dependencies = dependencies,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.ooni.probe.data.models

data class TestResult(
val id: Id,
) {
data class Id(val value: String)
}
13 changes: 13 additions & 0 deletions composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ package org.ooni.probe.di
import kotlinx.serialization.json.Json
import org.ooni.engine.Engine
import org.ooni.engine.OonimkallBridge
import org.ooni.probe.data.models.TestResult
import org.ooni.probe.shared.PlatformInfo
import org.ooni.probe.ui.dashboard.DashboardViewModel
import org.ooni.probe.ui.result.ResultViewModel
import org.ooni.probe.ui.results.ResultsViewModel

class Dependencies(
val platformInfo: PlatformInfo,
private val oonimkallBridge: OonimkallBridge,
private val baseFileDir: String,
) {
// Data

private val json by lazy {
Json {
encodeDefaults = true
Expand All @@ -20,8 +24,17 @@ class Dependencies(
}

// Engine

private val engine by lazy { Engine(oonimkallBridge, json, baseFileDir) }

// ViewModels

val dashboardViewModel get() = DashboardViewModel(engine)

fun resultsViewModel(goToResult: (TestResult.Id) -> Unit) = ResultsViewModel(goToResult)

fun resultViewModel(
resultId: TestResult.Id,
onBack: () -> Unit,
) = ResultViewModel(resultId, onBack)
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package org.ooni.probe.ui.dashboard

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
Expand All @@ -18,49 +14,39 @@ import androidx.compose.ui.Modifier
import ooniprobe.composeapp.generated.resources.Res
import ooniprobe.composeapp.generated.resources.app_name
import ooniprobe.composeapp.generated.resources.logo
import ooniprobe.composeapp.generated.resources.run_tests
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.ooni.probe.ui.AppTheme

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DashboardScreen(
state: DashboardViewModel.State,
onEvent: (DashboardViewModel.Event) -> Unit,
) {
Scaffold(
topBar = {
TopAppBar(
title = {
Text(stringResource(Res.string.app_name))
},
)
},
) { contentPadding ->
Column {
TopAppBar(
title = { Text(stringResource(Res.string.app_name)) },
)

Column(
modifier = Modifier.padding(contentPadding),
verticalArrangement = Arrangement.Center,
) {
Button(
onClick = { onEvent(DashboardViewModel.Event.StartClick) },
enabled = !state.isRunning,
) {
// Text(stringResource(Res.string.run_tests))
Text("Run Tests")
}
Image(
painterResource(Res.drawable.logo),
contentDescription = stringResource(Res.string.app_name),
modifier = Modifier.align(Alignment.CenterHorizontally),
)

Image(
painterResource(Res.drawable.logo),
contentDescription = "OONI Probe Logo",
modifier = Modifier.align(Alignment.CenterHorizontally),
)
Text(
text = state.log,
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
)
Button(
onClick = { onEvent(DashboardViewModel.Event.StartClick) },
enabled = !state.isRunning,
) {
Text(stringResource(Res.string.run_tests))
}

Text(
text = state.log,
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.ooni.probe.ui.navigation

import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.currentBackStackEntryAsState
import ooniprobe.composeapp.generated.resources.Res
import ooniprobe.composeapp.generated.resources.dashboard
import ooniprobe.composeapp.generated.resources.ic_dashboard
import ooniprobe.composeapp.generated.resources.ic_history
import ooniprobe.composeapp.generated.resources.ic_settings
import ooniprobe.composeapp.generated.resources.settings
import ooniprobe.composeapp.generated.resources.test_results
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource

@Composable
fun BottomNavigationBar(navController: NavController) {
val entry by navController.currentBackStackEntryAsState()
val currentRoute = entry?.destination?.route ?: return

// Only show the bottom app on the main screens
if (!MAIN_NAVIGATION_SCREENS.map { it.route }.contains(currentRoute)) return

NavigationBar {
MAIN_NAVIGATION_SCREENS.forEach { screen ->
NavigationBarItem(
icon = {
Icon(
painterResource(screen.iconRes),
contentDescription = stringResource(screen.titleRes),
)
},
label = { Text(stringResource(screen.titleRes)) },
selected = currentRoute == screen.route,
onClick = {
navController.navigate(screen.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
navController.graph.findStartDestination().route?.let {
popUpTo(it) {
saveState = true
}
}
// Avoid multiple copies of the same destination when
// re-selecting the same item
launchSingleTop = true
// Restore state when re-selecting a previously selected item
restoreState = true
}
},
)
}
}
}

private val Screen.titleRes
get() =
when (this) {
Screen.Dashboard -> Res.string.dashboard
Screen.Results -> Res.string.test_results
Screen.Settings -> Res.string.settings
else -> throw IllegalArgumentException("Only main screens allowed in bottom navigation")
}

private val Screen.iconRes
get() =
when (this) {
Screen.Dashboard -> Res.drawable.ic_dashboard
Screen.Results -> Res.drawable.ic_history
Screen.Settings -> Res.drawable.ic_settings
else -> throw IllegalArgumentException("Only main screens allowed in bottom navigation")
}

private val MAIN_NAVIGATION_SCREENS = listOf(Screen.Dashboard, Screen.Results, Screen.Settings)
Loading

0 comments on commit 8cf60e6

Please sign in to comment.