feat(HomeScreen): better empty page layout
This commit is contained in:
parent
af98fc6e99
commit
5eeeb4fb45
7 changed files with 98 additions and 47 deletions
|
|
@ -149,6 +149,7 @@ dependencies {
|
|||
implementation(libs.microg)
|
||||
implementation(libs.smali)
|
||||
implementation(libs.baksmali)
|
||||
implementation(libs.compose.shimmer)
|
||||
implementation(variantOf(libs.zip) { artifactType("aar") })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<DownloaderSetting>("downloader", DownloadManagerProvider.getDefaultDownloader())
|
||||
var installer by enumPreference<InstallerSetting>("installer", InstallerSetting.PM)
|
||||
|
|
|
|||
|
|
@ -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<HomeModel>()
|
||||
|
||||
// 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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<string name="action_dismiss">Dismiss</string>
|
||||
<string name="action_install">Install</string>
|
||||
<string name="action_uninstall">Uninstall</string>
|
||||
<string name="action_add_install">Add Installation</string>
|
||||
<string name="action_add_install">New Aliucord Installation</string>
|
||||
<string name="action_update">Update</string>
|
||||
<string name="action_clear">Clear</string>
|
||||
<string name="action_launch">Launch</string>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue