Skip to content

Commit 474696f

Browse files
authored
refactor all! - done users list (#53)
* refactor all! * done users list * done users list * done users list * done users list * add keystore
1 parent d78c118 commit 474696f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1120
-740
lines changed

.idea/deploymentTargetDropDown.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/gradle.xml

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle.kts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import java.util.Properties
2+
13
plugins {
24
androidApplication
35
kotlinAndroid
@@ -23,6 +25,28 @@ android {
2325
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2426
}
2527

28+
signingConfigs {
29+
create("release") {
30+
val keystoreProperties = Properties().apply {
31+
load(
32+
rootProject.file("keystore/key.properties")
33+
.apply { check(exists()) }
34+
.reader()
35+
)
36+
}
37+
38+
keyAlias = keystoreProperties["keyAlias"] as String
39+
keyPassword = keystoreProperties["keyPassword"] as String
40+
storeFile = rootProject.file(keystoreProperties["storeFile"] as String)
41+
.apply { check(exists()) }
42+
storePassword = keystoreProperties["storePassword"] as String
43+
44+
// Optional, specify signing versions used
45+
enableV1Signing = true
46+
enableV2Signing = true
47+
}
48+
}
49+
2650
buildTypes {
2751
getByName("release") {
2852
isMinifyEnabled = true
@@ -31,8 +55,18 @@ android {
3155
getDefaultProguardFile("proguard-android-optimize.txt"),
3256
"proguard-rules.pro"
3357
)
58+
59+
signingConfig = signingConfigs.getByName("release")
60+
isDebuggable = false
3461
}
3562
}
63+
64+
buildFeatures {
65+
compose = true
66+
}
67+
composeOptions {
68+
kotlinCompilerExtensionVersion = deps.compose.androidxComposeCompiler
69+
}
3670
}
3771

3872
dependencies {
@@ -45,6 +79,10 @@ dependencies {
4579
)
4680
)
4781

82+
implementation(deps.androidx.appCompat)
83+
implementationCompose()
84+
85+
implementation(uiTheme)
4886
implementation(domain)
4987
implementation(data)
5088
implementation(core)

app/src/main/AndroidManifest.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@
1313
android:supportsRtl="true"
1414
android:theme="@style/Theme.AppTheme.NoActionBar">
1515

16+
<activity
17+
android:name=".MainActivity"
18+
android:exported="true">
19+
<intent-filter>
20+
<action android:name="android.intent.action.MAIN" />
21+
22+
<category android:name="android.intent.category.LAUNCHER" />
23+
</intent-filter>
24+
</activity>
25+
1626
</application>
1727

1828
</manifest>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.hoc.flowmvi
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.runtime.Stable
5+
import androidx.compose.runtime.remember
6+
import androidx.navigation.NavDestination
7+
import androidx.navigation.NavHostController
8+
import androidx.navigation.compose.currentBackStackEntryAsState
9+
import androidx.navigation.compose.rememberNavController
10+
import com.hoc.flowmvi.Screen.UsersList
11+
import com.hoc.flowmvi.ui.main.navigation.usersListNavigationRoute
12+
13+
@Composable
14+
fun rememberJetpackComposeMVICoroutinesFlowApp(
15+
navController: NavHostController = rememberNavController()
16+
): JetpackComposeMVICoroutinesFlowAppState = remember(navController) {
17+
JetpackComposeMVICoroutinesFlowAppState(navController)
18+
}
19+
20+
enum class Screen {
21+
UsersList,
22+
SearchUsers,
23+
AddNewUser;
24+
25+
val route: String
26+
get() = when (this) {
27+
UsersList -> usersListNavigationRoute
28+
SearchUsers -> TODO()
29+
AddNewUser -> TODO()
30+
}
31+
32+
companion object {
33+
/**
34+
* Use this instead of [values()] for more performant.
35+
* See [KT-48872](https://youtrack.jetbrains.com/issue/KT-48872)
36+
*/
37+
val VALUES = values().asList()
38+
}
39+
}
40+
41+
@Stable
42+
class JetpackComposeMVICoroutinesFlowAppState(
43+
val navController: NavHostController,
44+
) {
45+
private val currentDestination: NavDestination?
46+
@Composable get() = navController
47+
.currentBackStackEntryAsState().value?.destination
48+
49+
val currentScreen: Screen?
50+
@Composable get() = when (currentDestination?.route) {
51+
usersListNavigationRoute -> UsersList
52+
else -> TODO()
53+
}
54+
55+
fun onNavigateUp() {
56+
navController.navigateUp()
57+
}
58+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.hoc.flowmvi
2+
3+
import android.os.Bundle
4+
import androidx.activity.compose.setContent
5+
import androidx.appcompat.app.AppCompatActivity
6+
import androidx.compose.foundation.layout.RowScope
7+
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material3.CenterAlignedTopAppBar
10+
import androidx.compose.material3.ExperimentalMaterial3Api
11+
import androidx.compose.material3.MaterialTheme
12+
import androidx.compose.material3.Scaffold
13+
import androidx.compose.material3.SnackbarHost
14+
import androidx.compose.material3.SnackbarHostState
15+
import androidx.compose.material3.Surface
16+
import androidx.compose.material3.Text
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.ui.Modifier
21+
import androidx.navigation.compose.NavHost
22+
import com.hoc.flowmvi.core_ui.AppBarState
23+
import com.hoc.flowmvi.core_ui.ProvideSnackbarHostState
24+
import com.hoc.flowmvi.ui.main.navigation.usersListScreen
25+
import com.hoc.flowmvi.ui.theme.AppTheme
26+
import dagger.hilt.android.AndroidEntryPoint
27+
28+
@AndroidEntryPoint
29+
class MainActivity : AppCompatActivity() {
30+
override fun onCreate(savedInstanceState: Bundle?) {
31+
super.onCreate(savedInstanceState)
32+
33+
setContent {
34+
AppTheme {
35+
Surface(
36+
color = MaterialTheme.colorScheme.background,
37+
modifier = Modifier.fillMaxSize(),
38+
) {
39+
JetpackComposeMVICoroutinesFlowApp()
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
@OptIn(ExperimentalMaterial3Api::class)
47+
@Composable
48+
fun JetpackComposeMVICoroutinesFlowAppBar(
49+
title: String?,
50+
navigationIcon: @Composable () -> Unit,
51+
actions: @Composable RowScope.() -> Unit,
52+
modifier: Modifier = Modifier
53+
) {
54+
CenterAlignedTopAppBar(
55+
title = {
56+
if (title != null) {
57+
Text(text = title)
58+
}
59+
},
60+
modifier = modifier,
61+
navigationIcon = navigationIcon,
62+
actions = actions
63+
)
64+
}
65+
66+
@OptIn(ExperimentalMaterial3Api::class)
67+
@Composable
68+
private fun JetpackComposeMVICoroutinesFlowApp(
69+
startScreen: Screen = Screen.UsersList,
70+
modifier: Modifier = Modifier,
71+
appState: JetpackComposeMVICoroutinesFlowAppState = rememberJetpackComposeMVICoroutinesFlowApp(),
72+
) {
73+
val navController = appState.navController
74+
val snackbarHostState = remember { SnackbarHostState() }
75+
val (appBarState, setAppBarState) = remember { mutableStateOf<AppBarState?>(null) }
76+
77+
Scaffold(
78+
snackbarHost = { SnackbarHost(snackbarHostState) },
79+
topBar = {
80+
appBarState?.let {
81+
JetpackComposeMVICoroutinesFlowAppBar(
82+
title = it.title,
83+
actions = it.actions,
84+
navigationIcon = it.navigationIcon,
85+
)
86+
}
87+
}
88+
) { innerPadding ->
89+
ProvideSnackbarHostState(snackbarHostState = snackbarHostState) {
90+
NavHost(
91+
navController = navController,
92+
modifier = modifier.padding(innerPadding),
93+
startDestination = startScreen.route
94+
) {
95+
usersListScreen(
96+
configAppBar = setAppBarState,
97+
)
98+
}
99+
}
100+
}
101+
}
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.hoc.flowmvi.core
22

33
import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
4-
import com.hoc.flowmvi.core_ui.navigator.Navigator
54
import dagger.Binds
65
import dagger.Module
76
import dagger.hilt.InstallIn
@@ -14,8 +13,4 @@ internal abstract class CoreModule {
1413
@Binds
1514
@Singleton
1615
abstract fun coroutineDispatchers(impl: DefaultCoroutineDispatchers): CoroutineDispatchers
17-
18-
@Binds
19-
@Singleton
20-
abstract fun navigator(impl: NavigatorImpl): Navigator
2116
}

0 commit comments

Comments
 (0)