Skip to content

Commit cb8043b

Browse files
committed
feat: implement "Tweaks" settings feature and UI
- Create a comprehensive "Tweaks" settings screen organized into sections: Appearance, Network, Installation, Updates, and Storage. - Implement theme customization including dark mode selection, Amoled black theme toggle, dynamic color support, and custom font options. - Add network proxy configuration support (HTTP, SOCKS, and System) with host, port, and authentication settings. - Implement Android-specific installation settings, including Shizuku integration for silent installs and auto-update toggles. - Add storage management features to view and clear the downloaded APK cache. - Implement repository visibility tweaks, such as "auto-detect clipboard links" and "hide seen repositories." - Integrate the Tweaks screen into the main navigation graph and bottom navigation bar. - Add `TweaksViewModel` to manage state for settings persistence, Shizuku availability tracking, and cache size calculation. - Introduce reusable UI components like `SectionHeader`, `ToggleSettingCard`, and `ExpressiveCard` for a consistent settings layout.
1 parent b0f8d21 commit cb8043b

18 files changed

Lines changed: 2414 additions & 8 deletions

File tree

composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/BottomNavigationUtils.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
package zed.rainxch.githubstore.app.navigation
22

33
import androidx.compose.material.icons.Icons
4-
import androidx.compose.material.icons.filled.Apps
5-
import androidx.compose.material.icons.filled.Home
6-
import androidx.compose.material.icons.filled.Person2
7-
import androidx.compose.material.icons.filled.Search
8-
import androidx.compose.material.icons.outlined.Apps
9-
import androidx.compose.material.icons.outlined.Home
10-
import androidx.compose.material.icons.outlined.Person2
11-
import androidx.compose.material.icons.outlined.Search
4+
import androidx.compose.material.icons.filled.*
5+
import androidx.compose.material.icons.outlined.*
126
import androidx.compose.ui.graphics.vector.ImageVector
137
import org.jetbrains.compose.resources.StringResource
148
import zed.rainxch.core.domain.getPlatform
@@ -49,6 +43,12 @@ object BottomNavigationUtils {
4943
iconFilled = Icons.Filled.Person2,
5044
screen = GithubStoreGraph.ProfileScreen,
5145
),
46+
BottomNavigationItem(
47+
titleRes = Res.string.bottom_nav_profile_tweaks,
48+
iconOutlined = Icons.Outlined.Settings,
49+
iconFilled = Icons.Filled.Settings,
50+
screen = GithubStoreGraph.TweaksScreen,
51+
),
5252
)
5353

5454
fun allowedScreens(): List<GithubStoreGraph> =

composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/GithubStoreGraph.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ sealed interface GithubStoreGraph {
2929
@Serializable
3030
data object ProfileScreen : GithubStoreGraph
3131

32+
@Serializable
33+
data object TweaksScreen : GithubStoreGraph
34+
3235
@Serializable
3336
data object FavouritesScreen : GithubStoreGraph
3437

core/presentation/src/commonMain/composeResources/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@
394394
<string name="bottom_nav_search_title">Search</string>
395395
<string name="bottom_nav_apps_title">Apps</string>
396396
<string name="bottom_nav_profile_title">Profile</string>
397+
<string name="bottom_nav_profile_tweaks">Tweaks</string>
397398

398399
<string name="forked_repository">Fork</string>
399400

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
plugins {
2+
alias(libs.plugins.convention.cmp.feature)
3+
}
4+
5+
kotlin {
6+
sourceSets {
7+
commonMain {
8+
dependencies {
9+
implementation(libs.kotlin.stdlib)
10+
11+
implementation(projects.core.domain)
12+
implementation(projects.core.presentation)
13+
implementation(projects.feature.profile.domain)
14+
15+
implementation(libs.androidx.compose.ui.tooling.preview)
16+
implementation(compose.components.resources)
17+
18+
implementation(libs.liquid)
19+
}
20+
}
21+
22+
androidMain {
23+
dependencies {
24+
}
25+
}
26+
27+
jvmMain {
28+
dependencies {
29+
}
30+
}
31+
}
32+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package zed.rainxch.tweaks.presentation
2+
3+
import zed.rainxch.core.domain.model.AppTheme
4+
import zed.rainxch.core.domain.model.FontTheme
5+
import zed.rainxch.core.domain.model.InstallerType
6+
import zed.rainxch.tweaks.presentation.model.ProxyType
7+
8+
sealed interface TweaksAction {
9+
data object OnNavigateBackClick : TweaksAction
10+
11+
data class OnThemeColorSelected(
12+
val themeColor: AppTheme,
13+
) : TweaksAction
14+
15+
data class OnAmoledThemeToggled(
16+
val enabled: Boolean,
17+
) : TweaksAction
18+
19+
data class OnDarkThemeChange(
20+
val isDarkTheme: Boolean?,
21+
) : TweaksAction
22+
23+
data class OnFontThemeSelected(
24+
val fontTheme: FontTheme,
25+
) : TweaksAction
26+
27+
data class OnLiquidGlassEnabledChange(
28+
val enabled: Boolean,
29+
) : TweaksAction
30+
31+
data class OnScrollbarToggled(
32+
val enabled: Boolean,
33+
) : TweaksAction
34+
35+
data class OnProxyTypeSelected(
36+
val type: ProxyType,
37+
) : TweaksAction
38+
39+
data class OnProxyHostChanged(
40+
val host: String,
41+
) : TweaksAction
42+
43+
data class OnProxyPortChanged(
44+
val port: String,
45+
) : TweaksAction
46+
47+
data class OnProxyUsernameChanged(
48+
val username: String,
49+
) : TweaksAction
50+
51+
data class OnProxyPasswordChanged(
52+
val password: String,
53+
) : TweaksAction
54+
55+
data object OnProxyPasswordVisibilityToggle : TweaksAction
56+
57+
data object OnProxySave : TweaksAction
58+
59+
data class OnInstallerTypeSelected(
60+
val type: InstallerType,
61+
) : TweaksAction
62+
63+
data object OnRequestShizukuPermission : TweaksAction
64+
65+
data class OnAutoUpdateToggled(
66+
val enabled: Boolean,
67+
) : TweaksAction
68+
69+
data class OnUpdateCheckIntervalChanged(
70+
val hours: Long,
71+
) : TweaksAction
72+
73+
data class OnIncludePreReleasesToggled(
74+
val enabled: Boolean,
75+
) : TweaksAction
76+
77+
data class OnAutoDetectClipboardToggled(
78+
val enabled: Boolean,
79+
) : TweaksAction
80+
81+
data class OnHideSeenToggled(
82+
val enabled: Boolean,
83+
) : TweaksAction
84+
85+
data object OnClearSeenRepos : TweaksAction
86+
87+
data object OnRefreshCacheSize : TweaksAction
88+
89+
data object OnClearCacheClick : TweaksAction
90+
91+
data object OnClearDownloadsConfirm : TweaksAction
92+
93+
data object OnClearDownloadsDismiss : TweaksAction
94+
95+
data object OnHelpClick : TweaksAction
96+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package zed.rainxch.tweaks.presentation
2+
3+
sealed interface TweaksEvent {
4+
data object OnProxySaved : TweaksEvent
5+
6+
data class OnProxySaveError(
7+
val message: String,
8+
) : TweaksEvent
9+
10+
data object OnCacheCleared : TweaksEvent
11+
12+
data class OnCacheClearError(
13+
val message: String,
14+
) : TweaksEvent
15+
16+
data object OnSeenHistoryCleared : TweaksEvent
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package zed.rainxch.tweaks.presentation
2+
3+
import zed.rainxch.core.domain.model.AppTheme
4+
import zed.rainxch.core.domain.model.FontTheme
5+
import zed.rainxch.core.domain.model.InstallerType
6+
import zed.rainxch.core.domain.model.ShizukuAvailability
7+
import zed.rainxch.tweaks.presentation.model.ProxyType
8+
9+
data class TweaksState(
10+
val selectedThemeColor: AppTheme = AppTheme.OCEAN,
11+
val selectedFontTheme: FontTheme = FontTheme.CUSTOM,
12+
val isAmoledThemeEnabled: Boolean = false,
13+
val isDarkTheme: Boolean? = null,
14+
val versionName: String = "",
15+
val proxyType: ProxyType = ProxyType.NONE,
16+
val proxyHost: String = "",
17+
val proxyPort: String = "",
18+
val proxyUsername: String = "",
19+
val proxyPassword: String = "",
20+
val isProxyPasswordVisible: Boolean = false,
21+
val autoDetectClipboardLinks: Boolean = true,
22+
val cacheSize: String = "",
23+
val isClearDownloadsDialogVisible: Boolean = false,
24+
val installerType: InstallerType = InstallerType.DEFAULT,
25+
val shizukuAvailability: ShizukuAvailability = ShizukuAvailability.UNAVAILABLE,
26+
val autoUpdateEnabled: Boolean = false,
27+
val updateCheckIntervalHours: Long = 6L,
28+
val includePreReleases: Boolean = false,
29+
val isLiquidGlassEnabled: Boolean = true,
30+
val isHideSeenEnabled: Boolean = false,
31+
val isScrollbarEnabled: Boolean = false,
32+
)

0 commit comments

Comments
 (0)