Skip to content

Commit 44512ef

Browse files
authored
Merge pull request #40 from zouhir96/feature/settings_module
feat: Create settings module.
2 parents ca04e5b + 26ac158 commit 44512ef

34 files changed

+362
-254
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ android {
1717
minSdk = libs.versions.minSdk.get().toInt()
1818
targetSdk = libs.versions.targetSdk.get().toInt()
1919
versionCode = 3
20-
versionName = "1.0.0"
20+
versionName = libs.versions.versionName.get()
2121

2222
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2323
vectorDrawables {
@@ -59,6 +59,7 @@ android {
5959
dependencies {
6060
implementation(project(":design"))
6161
implementation(project(":shared"))
62+
implementation(project(":settings"))
6263

6364
// Core
6465
implementation(libs.androidx.core.ktx)
@@ -68,14 +69,6 @@ dependencies {
6869
implementation(libs.androidx.core.splashscreen)
6970
implementation(libs.androidx.activity)
7071

71-
// Navigation
72-
implementation(libs.androidx.navigation)
73-
implementation(libs.dagger.hilt.navigation)
74-
75-
// LifeCycle
76-
implementation(libs.androidx.lifecycle.runtime.ktx)
77-
implementation(libs.androidx.lifecycle.runtime.compose)
78-
7972
// di: hilt
8073
implementation(libs.google.dagger.hilt.android)
8174
kapt(libs.google.dagger.hilt.android.compiler)

app/src/main/java/com/zrcoding/hackertab/features/home/domain/usecases/GenerateHomeViewStateUseCase.kt

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ import com.zrcoding.hackertab.features.home.domain.models.BaseModel
1515
import com.zrcoding.hackertab.features.home.presentation.CardViewState
1616
import com.zrcoding.shared.domain.models.NetworkErrors
1717
import com.zrcoding.shared.domain.models.Resource
18-
import com.zrcoding.shared.domain.models.Source
19-
import com.zrcoding.shared.domain.models.SourceName
20-
import com.zrcoding.shared.domain.models.Topic
2118
import com.zrcoding.shared.domain.repositories.ArticleRepository
22-
import com.zrcoding.shared.domain.repositories.SettingRepository
2319
import kotlinx.coroutines.ExperimentalCoroutinesApi
2420
import kotlinx.coroutines.flow.Flow
2521
import kotlinx.coroutines.flow.combine
@@ -28,7 +24,7 @@ import kotlinx.coroutines.flow.mapLatest
2824
import javax.inject.Inject
2925

3026
class GenerateHomeViewStateUseCase @Inject constructor(
31-
private val settingRepository: SettingRepository,
27+
private val settingRepository: com.zrcoding.hackertab.settings.domain.repositories.SettingRepository,
3228
private val articleRepository: ArticleRepository
3329
) {
3430
@OptIn(ExperimentalCoroutinesApi::class)
@@ -38,10 +34,10 @@ class GenerateHomeViewStateUseCase @Inject constructor(
3834
flow2 = settingRepository.observeSelectedSources(),
3935
transform = ::Pair
4036
).mapLatest { pair ->
41-
val topics = pair.first.ifEmpty { listOf(Topic.global) }
37+
val topics = pair.first.ifEmpty { listOf(com.zrcoding.hackertab.settings.domain.models.Topic.global) }
4238
pair.second.map { source ->
4339
when (source.name) {
44-
SourceName.GITHUB -> CardViewState(
40+
com.zrcoding.hackertab.settings.domain.models.SourceName.GITHUB -> CardViewState(
4541
source = source,
4642
state = createCardFlow(
4743
source = source,
@@ -52,7 +48,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
5248
)
5349
)
5450

55-
SourceName.HACKER_NEWS -> CardViewState(
51+
com.zrcoding.hackertab.settings.domain.models.SourceName.HACKER_NEWS -> CardViewState(
5652
source = source,
5753
state = createCardFlow(
5854
source = source,
@@ -64,7 +60,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
6460
)
6561
)
6662

67-
SourceName.REDDIT -> CardViewState(
63+
com.zrcoding.hackertab.settings.domain.models.SourceName.REDDIT -> CardViewState(
6864
source = source,
6965
state = createCardFlow(
7066
source = source,
@@ -75,7 +71,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
7571
)
7672
)
7773

78-
SourceName.FREE_CODE_CAMP -> CardViewState(
74+
com.zrcoding.hackertab.settings.domain.models.SourceName.FREE_CODE_CAMP -> CardViewState(
7975
source = source,
8076
state = createCardFlow(
8177
source = source,
@@ -86,7 +82,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
8682
)
8783
)
8884

89-
SourceName.CONFERENCES -> CardViewState(
85+
com.zrcoding.hackertab.settings.domain.models.SourceName.CONFERENCES -> CardViewState(
9086
source = source,
9187
state = createCardFlow(
9288
source = source,
@@ -97,7 +93,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
9793
)
9894
)
9995

100-
SourceName.DEVTO -> CardViewState(
96+
com.zrcoding.hackertab.settings.domain.models.SourceName.DEVTO -> CardViewState(
10197
source = source,
10298
state = createCardFlow(
10399
source = source,
@@ -108,7 +104,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
108104
)
109105
)
110106

111-
SourceName.HASH_NODE -> CardViewState(
107+
com.zrcoding.hackertab.settings.domain.models.SourceName.HASH_NODE -> CardViewState(
112108
source = source,
113109
state = createCardFlow(
114110
source = source,
@@ -119,7 +115,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
119115
)
120116
)
121117

122-
SourceName.PRODUCTHUNT -> CardViewState(
118+
com.zrcoding.hackertab.settings.domain.models.SourceName.PRODUCTHUNT -> CardViewState(
123119
source = source,
124120
state = createCardFlow(
125121
source = source,
@@ -131,7 +127,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
131127
)
132128
)
133129

134-
SourceName.INDIE_HACKERS -> CardViewState(
130+
com.zrcoding.hackertab.settings.domain.models.SourceName.INDIE_HACKERS -> CardViewState(
135131
source = source,
136132
state = createCardFlow(
137133
source = source,
@@ -143,7 +139,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
143139
)
144140
)
145141

146-
SourceName.LOBSTERS -> CardViewState(
142+
com.zrcoding.hackertab.settings.domain.models.SourceName.LOBSTERS -> CardViewState(
147143
source = source,
148144
state = createCardFlow(
149145
source = source,
@@ -155,7 +151,7 @@ class GenerateHomeViewStateUseCase @Inject constructor(
155151
)
156152
)
157153

158-
SourceName.MEDIUM -> CardViewState(
154+
com.zrcoding.hackertab.settings.domain.models.SourceName.MEDIUM -> CardViewState(
159155
source = source,
160156
state = createCardFlow(
161157
source = source,
@@ -171,10 +167,10 @@ class GenerateHomeViewStateUseCase @Inject constructor(
171167
}
172168

173169
private inline fun <Dto : Any, Model : BaseModel> createCardFlow(
174-
source: Source,
175-
topics: List<Topic>,
170+
source: com.zrcoding.hackertab.settings.domain.models.Source,
171+
topics: List<com.zrcoding.hackertab.settings.domain.models.Topic>,
176172
supportTags: Boolean = true,
177-
crossinline getTags: Topic.() -> List<String>,
173+
crossinline getTags: com.zrcoding.hackertab.settings.domain.models.Topic.() -> List<String>,
178174
crossinline getArticles: suspend (String) -> Resource<List<Dto>, NetworkErrors>,
179175
crossinline toModel: Dto.() -> Model,
180176
): Flow<CardViewState.State> = flow {

app/src/main/java/com/zrcoding/hackertab/features/home/presentation/HomeScreenViewState.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.zrcoding.hackertab.features.home.presentation
22

33
import androidx.compose.runtime.Stable
44
import com.zrcoding.hackertab.features.home.domain.models.BaseModel
5-
import com.zrcoding.shared.domain.models.Source
65
import kotlinx.coroutines.flow.Flow
76

87
@Stable
@@ -13,7 +12,7 @@ sealed interface HomeScreenViewState {
1312

1413
@Stable
1514
data class CardViewState(
16-
val source: Source,
15+
val source: com.zrcoding.hackertab.settings.domain.models.Source,
1716
val state: Flow<State>
1817
) {
1918
@Stable

app/src/main/java/com/zrcoding/hackertab/features/home/presentation/card/CardItems.kt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,21 @@ import com.zrcoding.hackertab.features.home.domain.models.Reddit
5151
import com.zrcoding.hackertab.features.home.domain.usecases.BuildConferenceDisplayedDateUseCase
5252
import com.zrcoding.shared.core.openUrlInBrowser
5353
import com.zrcoding.shared.core.toDate
54-
import com.zrcoding.shared.domain.models.SourceName
5554
import java.util.UUID
5655

5756
@Composable
58-
fun SourceName.ToCardItem(model: BaseModel) = when (this) {
59-
SourceName.GITHUB -> GithubItem(post = model as GithubRepo)
60-
SourceName.HACKER_NEWS -> HackerNewsItem(new = model as HackerNews)
61-
SourceName.REDDIT -> RedditItem(reddit = model as Reddit)
62-
SourceName.FREE_CODE_CAMP -> FreeCodeCampItem(post = model as FreeCodeCamp)
63-
SourceName.CONFERENCES -> ConferenceItem(conf = model as Conference)
64-
SourceName.DEVTO -> DevtoItem(devto = model as Devto)
65-
SourceName.HASH_NODE -> HashnodeItem(hashnode = model as Hashnode)
66-
SourceName.PRODUCTHUNT -> ProductHuntItem(product = model as ProductHunt)
67-
SourceName.INDIE_HACKERS -> IndieHackersItem(indieHackers = model as IndieHackers)
68-
SourceName.LOBSTERS -> LobstersItem(lobster = model as Lobster)
69-
SourceName.MEDIUM -> MediumItem(medium = model as Medium)
57+
fun com.zrcoding.hackertab.settings.domain.models.SourceName.ToCardItem(model: BaseModel) = when (this) {
58+
com.zrcoding.hackertab.settings.domain.models.SourceName.GITHUB -> GithubItem(post = model as GithubRepo)
59+
com.zrcoding.hackertab.settings.domain.models.SourceName.HACKER_NEWS -> HackerNewsItem(new = model as HackerNews)
60+
com.zrcoding.hackertab.settings.domain.models.SourceName.REDDIT -> RedditItem(reddit = model as Reddit)
61+
com.zrcoding.hackertab.settings.domain.models.SourceName.FREE_CODE_CAMP -> FreeCodeCampItem(post = model as FreeCodeCamp)
62+
com.zrcoding.hackertab.settings.domain.models.SourceName.CONFERENCES -> ConferenceItem(conf = model as Conference)
63+
com.zrcoding.hackertab.settings.domain.models.SourceName.DEVTO -> DevtoItem(devto = model as Devto)
64+
com.zrcoding.hackertab.settings.domain.models.SourceName.HASH_NODE -> HashnodeItem(hashnode = model as Hashnode)
65+
com.zrcoding.hackertab.settings.domain.models.SourceName.PRODUCTHUNT -> ProductHuntItem(product = model as ProductHunt)
66+
com.zrcoding.hackertab.settings.domain.models.SourceName.INDIE_HACKERS -> IndieHackersItem(indieHackers = model as IndieHackers)
67+
com.zrcoding.hackertab.settings.domain.models.SourceName.LOBSTERS -> LobstersItem(lobster = model as Lobster)
68+
com.zrcoding.hackertab.settings.domain.models.SourceName.MEDIUM -> MediumItem(medium = model as Medium)
7069
}
7170

7271
@Composable

app/src/main/java/com/zrcoding/hackertab/features/home/presentation/card/CardTemplate.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import androidx.compose.ui.res.stringResource
3434
import androidx.compose.ui.tooling.preview.Preview
3535
import androidx.compose.ui.unit.dp
3636
import com.zrcoding.hackertab.R
37-
import com.zrcoding.hackertab.core.icon
3837
import com.zrcoding.hackertab.design.components.ErrorMsgWithBtn
3938
import com.zrcoding.hackertab.design.components.FullScreenViewWithCenterText
4039
import com.zrcoding.hackertab.design.components.Loading
@@ -44,15 +43,15 @@ import com.zrcoding.hackertab.design.theme.HackertabTheme
4443
import com.zrcoding.hackertab.design.theme.dimension
4544
import com.zrcoding.hackertab.features.home.domain.models.BaseModel
4645
import com.zrcoding.hackertab.features.home.presentation.CardViewState
46+
import com.zrcoding.hackertab.settings.presentation.common.icon
4747
import com.zrcoding.shared.core.openUrlInBrowser
48-
import com.zrcoding.shared.domain.models.SourceName
4948

5049

5150
@Composable
5251
fun CardTemplate(
5352
modifier: Modifier = Modifier,
5453
cardUiState: CardViewState,
55-
cardItem: @Composable (SourceName, BaseModel) -> Unit,
54+
cardItem: @Composable (com.zrcoding.hackertab.settings.domain.models.SourceName, BaseModel) -> Unit,
5655
onRetryBtnClick: () -> Unit
5756
) {
5857
Card(

app/src/main/java/com/zrcoding/hackertab/features/navigation/NavHost.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import androidx.navigation.compose.composable
1212
import androidx.navigation.compose.rememberNavController
1313
import com.zrcoding.hackertab.design.theme.HackertabTheme
1414
import com.zrcoding.hackertab.features.home.presentation.HomeRoute
15-
import com.zrcoding.hackertab.features.setting.navigation.SettingNavHost
1615

1716
const val TRANSITION_DURATION = 400
1817

app/src/main/java/com/zrcoding/hackertab/features/setting/navigation/SettingNavHost.kt renamed to app/src/main/java/com/zrcoding/hackertab/features/navigation/SettingNavHost.kt

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
1-
package com.zrcoding.hackertab.features.setting.navigation
1+
package com.zrcoding.hackertab.features.navigation
22

33
import androidx.compose.animation.AnimatedContentTransitionScope
44
import androidx.compose.animation.core.tween
5-
import androidx.compose.foundation.layout.PaddingValues
65
import androidx.compose.foundation.layout.padding
7-
import androidx.compose.foundation.layout.size
8-
import androidx.compose.material.Button
9-
import androidx.compose.material.ButtonDefaults
10-
import androidx.compose.material.Icon
11-
import androidx.compose.material.MaterialTheme
126
import androidx.compose.material.Scaffold
13-
import androidx.compose.material.TopAppBar
147
import androidx.compose.runtime.Composable
158
import androidx.compose.ui.Modifier
16-
import androidx.compose.ui.res.painterResource
179
import androidx.navigation.compose.NavHost
1810
import androidx.navigation.compose.composable
1911
import androidx.navigation.compose.rememberNavController
20-
import com.zrcoding.hackertab.R
21-
import com.zrcoding.hackertab.design.theme.dimension
22-
import com.zrcoding.hackertab.features.navigation.TRANSITION_DURATION
23-
import com.zrcoding.hackertab.features.setting.master.SettingMasterScreen
24-
import com.zrcoding.hackertab.features.setting.sources.SettingSourcesRoute
25-
import com.zrcoding.hackertab.features.setting.topics.SettingTopicsRoute
12+
import com.zrcoding.hackertab.settings.presentation.master.SettingMasterScreen
13+
import com.zrcoding.hackertab.settings.presentation.master.SettingsTopBar
14+
import com.zrcoding.hackertab.settings.presentation.sources.SettingSourcesRoute
15+
import com.zrcoding.hackertab.settings.presentation.topics.SettingTopicsRoute
2616

2717
@Composable
2818
fun SettingNavHost(
@@ -31,31 +21,13 @@ fun SettingNavHost(
3121
val navController = rememberNavController()
3222
Scaffold(
3323
topBar = {
34-
TopAppBar(
35-
backgroundColor = MaterialTheme.colors.background,
36-
elevation = MaterialTheme.dimension.none
37-
) {
38-
Button(
39-
onClick = {
40-
navController.currentDestination?.route?.let {
41-
if (it == SettingScreen.SETTING_MASTER.route) {
42-
onNavigateBack()
43-
} else {
44-
navController.popBackStack()
45-
}
46-
}
47-
},
48-
modifier = Modifier.size(MaterialTheme.dimension.extraBig),
49-
shape = MaterialTheme.shapes.large,
50-
contentPadding = PaddingValues(MaterialTheme.dimension.none),
51-
colors = ButtonDefaults.outlinedButtonColors(
52-
contentColor = MaterialTheme.colors.onBackground
53-
)
54-
) {
55-
Icon(
56-
painter = painterResource(id = R.drawable.ic_baseline_arrow_back),
57-
contentDescription = "refresh button",
58-
)
24+
SettingsTopBar {
25+
navController.currentDestination?.route?.let {
26+
if (it == SettingScreen.SETTING_MASTER.route) {
27+
onNavigateBack()
28+
} else {
29+
navController.popBackStack()
30+
}
5931
}
6032
}
6133
}

app/src/main/java/com/zrcoding/hackertab/features/setting/navigation/SettingScreen.kt renamed to app/src/main/java/com/zrcoding/hackertab/features/navigation/SettingScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.zrcoding.hackertab.features.setting.navigation
1+
package com.zrcoding.hackertab.features.navigation
22

33
enum class SettingScreen(val route: String) {
44
SETTING_MASTER("setting_master"),

design/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ dependencies {
4646
api(libs.io.coil.compose)
4747
api(libs.io.coil.gif)
4848

49+
// Navigation
50+
api(libs.androidx.navigation)
51+
api(libs.dagger.hilt.navigation)
52+
53+
// LifeCycle
54+
api(libs.androidx.lifecycle.runtime.ktx)
55+
api(libs.androidx.lifecycle.runtime.compose)
56+
4957
// Tools
5058
debugApi(libs.androidx.compose.ui.tooling)
5159
}

gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ jvmTarget = "17"
44
compileSdk = "34"
55
targetSdk = "34"
66
minSdk = "23"
7+
versionName = "1.0.0"
78
depAndroidGradlePlugin = "8.3.0"
89
depGoogleServices = "4.4.1"
910
depDevtoolsKsp = "1.9.20-1.0.14"
@@ -24,6 +25,7 @@ depDatastore = '1.0.0'
2425
depRetrofit = "2.9.0"
2526
depLoggingInterceptor = "4.10.0"
2627
depRoom = "2.6.1"
28+
gson = "2.10.1"
2729

2830
[libraries]
2931

@@ -76,6 +78,7 @@ androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref =
7678
androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "depRoom" }
7779
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "depDatastore" }
7880
androidx-datastore-preferences-core = { group = "androidx.datastore", name = "datastore-preferences-core", version.ref = "depDatastore" }
81+
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
7982

8083
[plugins]
8184
android-application = { id = "com.android.application", version.ref = "depAndroidGradlePlugin" }

0 commit comments

Comments
 (0)