Skip to content

Commit 96c0bc8

Browse files
author
sds100
committed
Merge branch 'feature/35-tutorial-on-basics-of-map-codes-when-' into develop
2 parents f9a7849 + ca5c356 commit 96c0bc8

16 files changed

Lines changed: 750 additions & 68 deletions

File tree

app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ dependencies {
9696
implementation "androidx.compose.foundation:foundation:1.3.0-rc01"
9797
implementation 'com.google.accompanist:accompanist-permissions:0.24.10-beta'
9898
implementation "com.google.accompanist:accompanist-systemuicontroller:0.17.0"
99+
implementation "com.google.accompanist:accompanist-pager:0.25.1"
100+
implementation "com.google.accompanist:accompanist-pager-indicators:0.25.1"
99101
implementation "androidx.datastore:datastore-preferences:1.0.0"
100102
implementation "androidx.core:core-splashscreen:1.0.0"
101103
implementation "androidx.compose.material3:material3-window-size-class:1.0.0-rc01"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (C) 2022, Stichting Mapcode Foundation (http://www.mapcode.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mapcode
18+
19+
import androidx.lifecycle.ViewModel
20+
import androidx.lifecycle.viewModelScope
21+
import com.mapcode.data.Keys
22+
import com.mapcode.data.PreferenceRepository
23+
import dagger.hilt.android.lifecycle.HiltViewModel
24+
import kotlinx.coroutines.flow.SharingStarted
25+
import kotlinx.coroutines.flow.StateFlow
26+
import kotlinx.coroutines.flow.map
27+
import kotlinx.coroutines.flow.stateIn
28+
import javax.inject.Inject
29+
30+
@HiltViewModel
31+
class AppViewModel @Inject constructor(
32+
private val preferences: PreferenceRepository
33+
) : ViewModel() {
34+
val showOnboarding: StateFlow<Boolean> = preferences.get(Keys.finishedOnboarding)
35+
.map {
36+
if (it == null) {
37+
true
38+
} else {
39+
!it
40+
}
41+
}.stateIn(viewModelScope, SharingStarted.Eagerly, false)
42+
43+
fun onFinishOnboarding() {
44+
preferences.set(Keys.finishedOnboarding, true)
45+
}
46+
}

app/src/main/java/com/mapcode/MapcodeNavHost.kt

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,27 @@
1717
package com.mapcode
1818

1919
import androidx.compose.foundation.layout.fillMaxSize
20-
import androidx.compose.foundation.layout.statusBarsPadding
20+
import androidx.compose.material.MaterialTheme
2121
import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
2222
import androidx.compose.material3.windowsizeclass.WindowSizeClass
2323
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
2424
import androidx.compose.runtime.Composable
25+
import androidx.compose.runtime.SideEffect
26+
import androidx.compose.runtime.collectAsState
27+
import androidx.compose.runtime.getValue
2528
import androidx.compose.ui.Modifier
29+
import androidx.compose.ui.graphics.Color
2630
import androidx.hilt.navigation.compose.hiltViewModel
2731
import androidx.navigation.NavHostController
32+
import com.google.accompanist.systemuicontroller.rememberSystemUiController
2833
import com.mapcode.destinations.FavouritesScreenDestination
2934
import com.mapcode.destinations.MapScreenDestination
35+
import com.mapcode.destinations.OnboardingScreenDestination
3036
import com.mapcode.favourites.FavouritesScreen
3137
import com.mapcode.map.LayoutType
3238
import com.mapcode.map.MapScreen
3339
import com.mapcode.map.MapViewModel
40+
import com.mapcode.onboarding.OnboardingScreen
3441
import com.ramcosta.composedestinations.DestinationsNavHost
3542
import com.ramcosta.composedestinations.manualcomposablecalls.composable
3643
import com.ramcosta.composedestinations.scope.resultBackNavigator
@@ -43,6 +50,18 @@ fun MapcodeNavHost(
4350
mapViewModel: MapViewModel,
4451
windowSizeClass: WindowSizeClass
4552
) {
53+
val systemUiController = rememberSystemUiController()
54+
val useDarkIcons = MaterialTheme.colors.isLight
55+
56+
SideEffect {
57+
systemUiController.setStatusBarColor(
58+
color = Color.Transparent,
59+
darkIcons = useDarkIcons
60+
)
61+
62+
systemUiController.setNavigationBarColor(color = Color.Black, darkIcons = false)
63+
}
64+
4665
val layoutType: LayoutType = when {
4766
windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact
4867
&& windowSizeClass.widthSizeClass < WindowWidthSizeClass.Expanded -> LayoutType.VerticalInfoArea
@@ -55,10 +74,20 @@ fun MapcodeNavHost(
5574
else -> LayoutType.HorizontalInfoArea
5675
}
5776

77+
val appViewModel: AppViewModel = hiltViewModel()
78+
val showOnboarding: Boolean by appViewModel.showOnboarding.collectAsState()
79+
80+
val startDestination = if (showOnboarding) {
81+
OnboardingScreenDestination
82+
} else {
83+
MapScreenDestination
84+
}
85+
5886
DestinationsNavHost(
5987
navController = navController,
6088
navGraph = NavGraphs.root,
61-
modifier = modifier
89+
modifier = modifier,
90+
startRoute = startDestination
6291
) {
6392
composable(MapScreenDestination) {
6493
MapScreen(
@@ -72,12 +101,18 @@ fun MapcodeNavHost(
72101

73102
composable(FavouritesScreenDestination) {
74103
FavouritesScreen(
75-
modifier = Modifier
76-
.fillMaxSize()
77-
.statusBarsPadding(),
104+
modifier = Modifier.fillMaxSize(),
78105
viewModel = hiltViewModel(),
79106
resultBackNavigator = resultBackNavigator()
80107
)
81108
}
109+
110+
composable(OnboardingScreenDestination) {
111+
OnboardingScreen(
112+
modifier = Modifier.fillMaxSize(),
113+
viewModel = appViewModel,
114+
navigator = destinationsNavigator
115+
)
116+
}
82117
}
83118
}

app/src/main/java/com/mapcode/data/Keys.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@
1616

1717
package com.mapcode.data
1818

19-
import androidx.datastore.preferences.core.Preferences
20-
import androidx.datastore.preferences.core.doublePreferencesKey
21-
import androidx.datastore.preferences.core.floatPreferencesKey
22-
import androidx.datastore.preferences.core.stringSetPreferencesKey
19+
import androidx.datastore.preferences.core.*
2320

2421
object Keys {
2522
val lastLocationLatitude: Preferences.Key<Double> = doublePreferencesKey("last_location_lat")
2623
val lastLocationLongitude: Preferences.Key<Double> = doublePreferencesKey("last_location_long")
2724
val lastLocationZoom: Preferences.Key<Float> = floatPreferencesKey("last_location_zoom")
2825
val favourites: Preferences.Key<Set<String>> = stringSetPreferencesKey("favourites")
26+
val finishedOnboarding: Preferences.Key<Boolean> = booleanPreferencesKey("finished_onboarding")
2927
}

app/src/main/java/com/mapcode/favourites/FavouritesScreen.kt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import androidx.compose.ui.Modifier
3333
import androidx.compose.ui.res.stringResource
3434
import androidx.compose.ui.tooling.preview.Preview
3535
import androidx.compose.ui.unit.dp
36-
import com.google.accompanist.systemuicontroller.rememberSystemUiController
3736
import com.mapcode.R
3837
import com.mapcode.theme.MapcodeColor
3938
import com.mapcode.util.Location
@@ -74,14 +73,6 @@ private fun FavouritesScreen(
7473
onDeleteFavourite: (String) -> Unit = {},
7574
onChangeFavouriteName: (String, String) -> Unit = { _, _ -> },
7675
) {
77-
val systemUiController = rememberSystemUiController()
78-
val systemBarColor = MaterialTheme.colors.primary
79-
80-
DisposableEffect(systemUiController, systemBarColor) {
81-
systemUiController.setNavigationBarColor(color = systemBarColor)
82-
onDispose {}
83-
}
84-
8576
Scaffold(
8677
modifier = modifier,
8778
scaffoldState = rememberScaffoldState(),

app/src/main/java/com/mapcode/map/InfoScreenPart.kt

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -334,25 +334,13 @@ private fun HorizontalInfoArea(
334334
onDeleteFavouriteClick = onDeleteFavouriteClick,
335335
isFavouriteLocation = state.isFavouriteLocation
336336
)
337-
Row(Modifier.padding(top = 8.dp)) {
338-
TerritoryBox(
339-
modifier = Modifier
340-
.weight(0.5f)
341-
.padding(end = 8.dp)
342-
.clickable { onTerritoryClick() },
343-
index = state.mapcodeUi.number,
344-
count = state.mapcodeUi.count,
345-
territoryName = state.mapcodeUi.territoryFullName
346-
)
347-
MapcodeBox(
348-
Modifier
349-
.weight(0.5f)
350-
.padding(start = 8.dp)
351-
.clickable { onMapcodeClick() },
352-
state.mapcodeUi.code,
353-
state.mapcodeUi.territoryShortName
354-
)
355-
}
337+
338+
MapcodeButtons(
339+
modifier = Modifier.padding(top = 8.dp),
340+
state = state.mapcodeUi,
341+
onTerritoryClick = onTerritoryClick,
342+
onMapcodeClick = onMapcodeClick
343+
)
356344

357345
Row(
358346
Modifier
@@ -389,7 +377,7 @@ private fun HorizontalInfoArea(
389377
* The box that shows the territory.
390378
*/
391379
@Composable
392-
private fun TerritoryBox(
380+
fun TerritoryBox(
393381
modifier: Modifier = Modifier,
394382
index: Int,
395383
count: Int,
@@ -566,7 +554,7 @@ private fun HeaderWithIcon(modifier: Modifier = Modifier, text: String, icon: Im
566554
* The box that shows the mapcode.
567555
*/
568556
@Composable
569-
private fun MapcodeBox(
557+
fun MapcodeBox(
570558
modifier: Modifier = Modifier,
571559
code: String,
572560
territory: String?
@@ -600,4 +588,31 @@ private fun MapcodeBox(
600588
Text(text = styledString)
601589
}
602590
}
591+
}
592+
593+
@Composable
594+
fun MapcodeButtons(
595+
modifier: Modifier = Modifier,
596+
state: MapcodeUi,
597+
onTerritoryClick: () -> Unit,
598+
onMapcodeClick: () -> Unit
599+
) {
600+
Row(modifier) {
601+
TerritoryBox(
602+
modifier = Modifier
603+
.weight(0.5f)
604+
.clickable { onTerritoryClick() },
605+
index = state.number,
606+
count = state.count,
607+
territoryName = state.territoryFullName
608+
)
609+
Spacer(Modifier.width(16.dp))
610+
MapcodeBox(
611+
modifier = Modifier
612+
.weight(0.5f)
613+
.clickable { onMapcodeClick() },
614+
code = state.code,
615+
territory = state.territoryShortName
616+
)
617+
}
603618
}

app/src/main/java/com/mapcode/map/MapScreen.kt

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import androidx.compose.ui.unit.dp
4343
import com.google.accompanist.permissions.ExperimentalPermissionsApi
4444
import com.google.accompanist.permissions.PermissionStatus
4545
import com.google.accompanist.permissions.rememberMultiplePermissionsState
46-
import com.google.accompanist.systemuicontroller.rememberSystemUiController
4746
import com.google.android.gms.maps.CameraUpdateFactory
4847
import com.google.android.gms.maps.model.LatLng
4948
import com.google.maps.android.compose.*
@@ -62,7 +61,7 @@ import com.ramcosta.composedestinations.result.NavResult
6261
import com.ramcosta.composedestinations.result.ResultRecipient
6362
import kotlinx.coroutines.launch
6463

65-
@Destination(start = true)
64+
@Destination
6665
@Composable
6766
fun MapScreen(
6867
modifier: Modifier = Modifier,
@@ -145,17 +144,6 @@ fun MapScreen(
145144
}
146145
}
147146

148-
val systemUiController = rememberSystemUiController()
149-
val useDarkIcons = MaterialTheme.colors.isLight
150-
151-
DisposableEffect(systemUiController, useDarkIcons) {
152-
systemUiController.setSystemBarsColor(
153-
color = Color.Transparent,
154-
darkIcons = useDarkIcons
155-
)
156-
onDispose {}
157-
}
158-
159147
resultRecipient.onNavResult { result ->
160148
if (result is NavResult.Value) {
161149
val location = result.value

app/src/main/java/com/mapcode/map/MapViewModel.kt

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,7 @@ class MapViewModel @Inject constructor(
6969
if (mapcode == null) {
7070
MapcodeUi("", "", "", 0, 0)
7171
} else {
72-
val territoryName = if (mapcode.territory == Territory.AAA) {
73-
null
74-
} else {
75-
mapcode.territory.name
76-
}
77-
78-
MapcodeUi(
79-
mapcode.code,
80-
territoryName,
81-
mapcode.territory.fullName,
82-
mapcodeIndex + 1,
83-
mapcodes.size
84-
)
72+
MapcodeUi.fromMapcode(mapcode, mapcodeIndex, mapcodes.size)
8573
}
8674
}
8775

app/src/main/java/com/mapcode/map/MapcodeUi.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package com.mapcode.map
1818

19+
import com.mapcode.Mapcode
20+
import com.mapcode.Territory
21+
1922
data class MapcodeUi(
2023
val code: String,
2124
/**
@@ -37,4 +40,22 @@ data class MapcodeUi(
3740
* How many different territories have mapcodes for this location.
3841
*/
3942
val count: Int
40-
)
43+
) {
44+
companion object {
45+
fun fromMapcode(mapcode: Mapcode, index: Int, numMapcodes: Int): MapcodeUi {
46+
val territoryName = if (mapcode.territory == Territory.AAA) {
47+
null
48+
} else {
49+
mapcode.territory.name
50+
}
51+
52+
return MapcodeUi(
53+
mapcode.code,
54+
territoryName,
55+
mapcode.territory.fullName,
56+
index + 1,
57+
numMapcodes
58+
)
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)