diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 09752af..e1d869d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -149,6 +149,7 @@ dependencies { implementation(libs.microg) implementation(libs.smali) implementation(libs.baksmali) + implementation(libs.compose.shimmer) implementation(variantOf(libs.zip) { artifactType("aar") }) } diff --git a/app/src/main/kotlin/com/aliucord/manager/manager/PreferencesManager.kt b/app/src/main/kotlin/com/aliucord/manager/manager/PreferencesManager.kt index 39024b6..639b781 100644 --- a/app/src/main/kotlin/com/aliucord/manager/manager/PreferencesManager.kt +++ b/app/src/main/kotlin/com/aliucord/manager/manager/PreferencesManager.kt @@ -8,7 +8,7 @@ import com.aliucord.manager.ui.components.Theme class PreferencesManager(preferences: SharedPreferences) : BasePreferenceManager(preferences) { var theme by enumPreference("theme", Theme.DARK) - var dynamicColor by booleanPreference("dynamic_color", true) + var dynamicColor by booleanPreference("dynamic_color", false) var devMode by booleanPreference("dev_mode", false) var downloader by enumPreference("downloader", DownloadManagerProvider.getDefaultDownloader()) var installer by enumPreference("installer", InstallerSetting.PM) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt index 915a9f0..adae987 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.* import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -33,6 +34,7 @@ import com.aliucord.manager.ui.screens.plugins.PluginsScreen import com.aliucord.manager.ui.util.DiscordVersion import com.aliucord.manager.ui.util.paddings.PaddingValuesSides import com.aliucord.manager.ui.util.paddings.exclude +import kotlin.math.* class HomeScreen : Screen { override val key = "Home" @@ -42,6 +44,7 @@ class HomeScreen : Screen { val navigator = LocalNavigator.currentOrThrow val model = getScreenModel() + // FIXME: not refreshing after completing install? // Refresh installations list when the screen changes or activity resumes LifecycleResumeEffect(key1 = "INSTALLATIONS_REFRESH") { model.fetchInstallations() @@ -76,16 +79,15 @@ class HomeScreen : Screen { topBar = { HomeAppBar() }, ) { padding -> when (model.installations) { - is InstallsState.Fetching, - is InstallsState.Fetched, - -> PresentInstallsContent( + is InstallsState.Fetched -> PresentInstallsContent( model = model, padding = padding, onClickInstall = onClickInstall, ) + InstallsState.Fetching -> LoadingInstallsContent(padding = padding) + InstallsState.None -> NoInstallsContent( - supportedVersion = model.supportedVersion, onClickInstall = onClickInstall, modifier = Modifier .padding(padding.exclude(PaddingValuesSides.Bottom)), @@ -108,6 +110,19 @@ class HomeScreen : Screen { } } +@Composable +fun LoadingInstallsContent(padding: PaddingValues) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxSize() + .padding(padding) + .padding(top = 16.dp, start = 16.dp, end = 16.dp) + ) { + ProjectHeader() + } +} + @Composable fun PresentInstallsContent( model: HomeModel, @@ -134,7 +149,6 @@ fun PresentInstallsContent( onClick = onClickInstall, modifier = Modifier .fillMaxWidth() - .padding(top = 10.dp) ) } @@ -171,7 +185,6 @@ fun PresentInstallsContent( @Composable fun NoInstallsContent( - supportedVersion: DiscordVersion, onClickInstall: () -> Unit, modifier: Modifier = Modifier, ) { @@ -180,7 +193,7 @@ fun NoInstallsContent( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier .fillMaxSize() - .padding(top = 16.dp, start = 16.dp, end = 16.dp), + .padding(16.dp), ) { ProjectHeader() @@ -188,22 +201,18 @@ fun NoInstallsContent( secondaryInstall = false, onClick = onClickInstall, modifier = Modifier + .padding(12.dp) + .height(height = 50.dp) .fillMaxWidth() - .padding(top = 10.dp) - ) - - AnimatedVersionDisplay( - version = supportedVersion, - modifier = Modifier.padding(bottom = 30.dp), ) Column( - verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically), + verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .alpha(.7f) - .padding(bottom = 90.dp) .fillMaxSize() + .padding(bottom = 80.dp) ) { Text( text = """ /ᐠﹷ ‸ ﹷ ᐟ\ノ""", @@ -214,6 +223,7 @@ fun NoInstallsContent( Text( text = stringResource(R.string.installs_no_installs), style = MaterialTheme.typography.labelLarge, + modifier = Modifier.padding(start = 10.dp), ) } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstallButton.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstallButton.kt index 8d48f21..3e37d26 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstallButton.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstallButton.kt @@ -1,15 +1,49 @@ package com.aliucord.manager.ui.screens.home.components +import androidx.compose.animation.core.* import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.* import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.aliucord.manager.R +import com.aliucord.manager.ui.util.thenIf +import com.valentinilk.shimmer.* + +private val shimmerTheme = defaultShimmerTheme.copy( + shimmerWidth = 150.dp, + animationSpec = infiniteRepeatable( + animation = shimmerSpec( + durationMillis = 2000, + easing = LinearEasing, + delayMillis = 3500, + ), + repeatMode = RepeatMode.Restart, + initialStartOffset = StartOffset(1000), + ), + blendMode = BlendMode.Lighten, + shaderColors = listOf( + Color.White.copy(alpha = 0.00f), + Color.White.copy(alpha = 0.50f), + Color.White.copy(alpha = 1.00f), + Color.White.copy(alpha = 0.50f), + Color.White.copy(alpha = 0.00f), + ), + shaderColorStops = listOf( + 0.0f, + 0.25f, + 0.5f, + 0.75f, + 1.0f, + ), +) @Composable fun InstallButton( @@ -18,31 +52,37 @@ fun InstallButton( onClick: () -> Unit, modifier: Modifier = Modifier, ) { - FilledTonalIconButton( - shape = MaterialTheme.shapes.medium, - colors = IconButtonDefaults.filledTonalIconButtonColors( - containerColor = if (secondaryInstall) { - MaterialTheme.colorScheme.secondaryContainer - } else { - MaterialTheme.colorScheme.primary - }, - ), - enabled = enabled, - onClick = onClick, - modifier = modifier, + CompositionLocalProvider( + LocalShimmerTheme provides shimmerTheme ) { - Row( - horizontalArrangement = Arrangement.spacedBy(6.dp), - verticalAlignment = Alignment.CenterVertically, + FilledTonalIconButton( + shape = RectangleShape, + colors = IconButtonDefaults.filledTonalIconButtonColors( + containerColor = if (secondaryInstall) { + MaterialTheme.colorScheme.secondaryContainer + } else { + MaterialTheme.colorScheme.primary + }, + ), + enabled = enabled, + onClick = onClick, + modifier = modifier + .clip(MaterialTheme.shapes.medium) + .thenIf(!secondaryInstall) { shimmer() } ) { - Icon( - painter = painterResource(R.drawable.ic_add), - contentDescription = null, - ) - Text( - text = stringResource(R.string.action_add_install), - style = MaterialTheme.typography.labelLarge, - ) + Row( + horizontalArrangement = Arrangement.spacedBy(6.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painter = painterResource(R.drawable.ic_add), + contentDescription = null, + ) + Text( + text = stringResource(R.string.action_add_install), + style = MaterialTheme.typography.labelLarge, + ) + } } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstalledItemCard.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstalledItemCard.kt index 5f59aa2..98798c5 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstalledItemCard.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/components/InstalledItemCard.kt @@ -8,7 +8,8 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.* +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -35,12 +36,7 @@ fun InstalledItemCard( defaultElevation = 3.dp, ), modifier = modifier - .width(IntrinsicSize.Max) - .shadow( - clip = false, - elevation = 2.dp, - shape = MaterialTheme.shapes.medium, - ) + .width(IntrinsicSize.Max), ) { Column( verticalArrangement = Arrangement.spacedBy(24.dp), diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de951fb..7dd3465 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,7 +15,7 @@ Dismiss Install Uninstall - Add Installation + New Aliucord Installation Update Clear Launch diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b6b29be..255a4d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,6 +20,7 @@ kotlinx-immutable = "0.3.8" kotlinx-serialization = "1.8.0" ktor = "3.0.3" microg = "0.3.6.244735" +shimmer = "1.3.1" smali = "3.0.9" voyager = "1.0.1" zip = "2.1.1" @@ -84,6 +85,9 @@ smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } baksmali = { module = "com.android.tools.smali:smali-baksmali", version.ref = "smali" } zip = { module = "io.github.diamondminer88:zip-android", version.ref = "zip" } # Only use the "aar" artifact +# Other +compose-shimmer = { module = "com.valentinilk.shimmer:compose-shimmer", version.ref = "shimmer" } + [bundles] accompanist = [ "accompanist-permissions",