refactor: UI code refactors

This commit is contained in:
Mathew Tkachuk committed 2025-03-08 16:47:41 +03:00
1 parent 0aad2646fe
commit 47a2f5815d
7 files changed
+179 -161

No files matched your search

@@ -1,8 +1,5 @@
package moe.crx.ovrport.ui package moe.crx.ovrport.ui
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -21,16 +18,14 @@ import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import moe.crx.ovrport.AndroidPlatform import moe.crx.ovrport.AndroidPlatform
import moe.crx.ovrport.getCurrentVersion import moe.crx.ovrport.getCurrentVersion
import moe.crx.ovrport.patch.Patch
import moe.crx.ovrport.getPlatform import moe.crx.ovrport.getPlatform
import moe.crx.ovrport.model.GithubRelease import moe.crx.ovrport.model.GithubRelease
import moe.crx.ovrport.patch.Constants import moe.crx.ovrport.patch.Constants
import moe.crx.ovrport.patch.Patch
import moe.crx.ovrport.ui.theme.OverportTheme import moe.crx.ovrport.ui.theme.OverportTheme
import moe.crx.ovrport.utils.HttpUtil
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import overportapp.composeapp.generated.resources.Res import overportapp.composeapp.generated.resources.Res
@@ -82,11 +77,7 @@ fun AppContent(
} }
}, },
actions = { actions = {
AnimatedVisibility( FadeVisibility(versionToUpdate?.name != null && versionToUpdate?.name != getCurrentVersion()) {
versionToUpdate?.name != null && versionToUpdate?.name != getCurrentVersion(),
enter = fadeIn(),
exit = fadeOut()
) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip(
RoundedCornerShape(16.dp) RoundedCornerShape(16.dp)
@@ -115,21 +106,13 @@ fun AppContent(
val inProgress = viewModel.working val inProgress = viewModel.working
val isPatcherVisible = viewModel.isApkLoaded() && !inProgress val isPatcherVisible = viewModel.isApkLoaded() && !inProgress
AnimatedVisibility( FadeVisibility(!isPatcherVisible) {
!isPatcherVisible,
enter = fadeIn(),
exit = fadeOut()
) {
StartingCard(innerPadding, inProgress) { StartingCard(innerPadding, inProgress) {
onOpen() onOpen()
} }
} }
AnimatedVisibility( FadeVisibility(isPatcherVisible) {
isPatcherVisible,
enter = fadeIn(),
exit = fadeOut()
) {
ApplicationInfoCard( ApplicationInfoCard(
innerPadding, innerPadding,
viewModel.currentAppName(), viewModel.currentAppName(),
@@ -0,0 +1,52 @@
package moe.crx.ovrport.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Widgets
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import overportapp.composeapp.generated.resources.Res
import overportapp.composeapp.generated.resources.unknown_package
@Composable
fun ApplicationInfo(
applicationName: String? = "Application",
applicationPackage: String? = "com.company.application",
applicationVersion: String? = "1.0.0",
applicationIcon: ImageBitmap? = null,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (applicationIcon == null) {
Icon(
Icons.Default.Widgets,
contentDescription = null,
modifier = Modifier.size(48.dp)
)
} else {
Image(
applicationIcon,
contentDescription = null,
modifier = Modifier.size(48.dp).clip(RoundedCornerShape(8.dp))
)
}
Column(
modifier = Modifier.height(48.dp),
verticalArrangement = Arrangement.Center
) {
Text("$applicationName ($applicationVersion)")
Text(
applicationPackage ?: stringResource(Res.string.unknown_package),
)
}
}
}
@@ -1,103 +1,22 @@
package moe.crx.ovrport.ui package moe.crx.ovrport.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button
import androidx.compose.material.icons.Icons import androidx.compose.material3.Checkbox
import androidx.compose.material.icons.filled.Widgets import androidx.compose.material3.ListItem
import androidx.compose.material3.* import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import moe.crx.ovrport.patch.Constants.LOADING_COMPATIBILITY
import moe.crx.ovrport.patch.Patch import moe.crx.ovrport.patch.Patch
import moe.crx.ovrport.patch.PatchStore import moe.crx.ovrport.patch.PatchStore
import moe.crx.ovrport.patch.getCompatibilityStatus
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview import org.jetbrains.compose.ui.tooling.preview.Preview
import overportapp.composeapp.generated.resources.Res
import overportapp.composeapp.generated.resources.unknown_package
@Composable
fun ApplicationInfo(
applicationName: String? = "Application",
applicationPackage: String? = "com.company.application",
applicationVersion: String? = "1.0.0",
applicationIcon: ImageBitmap? = null,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (applicationIcon == null) {
Icon(
Icons.Default.Widgets,
contentDescription = null,
modifier = Modifier.size(48.dp)
)
} else {
Image(
applicationIcon,
contentDescription = null,
modifier = Modifier.size(48.dp).clip(RoundedCornerShape(8.dp))
)
}
Column(
modifier = Modifier.height(48.dp),
verticalArrangement = Arrangement.Center
) {
Text("$applicationName ($applicationVersion)")
Text(
applicationPackage ?: stringResource(Res.string.unknown_package),
)
}
}
}
@Composable
fun ApplicationStatus(
applicationName: String? = "Application",
applicationPackage: String? = "",
) {
var statusInfo by remember(applicationPackage) { mutableStateOf(LOADING_COMPATIBILITY) }
val urlHandler = LocalUriHandler.current
LaunchedEffect(applicationPackage) {
withContext(Dispatchers.IO) {
statusInfo = getCompatibilityStatus(applicationName, applicationPackage)
}
}
Card(colors = CardDefaults.cardColors(statusInfo.status.cardColor, statusInfo.status.contentColor)) {
Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip(
RoundedCornerShape(16.dp)
).clickable {
urlHandler.openUri(statusInfo.url)
}) {
Icon(
statusInfo.status.icon,
contentDescription = null,
modifier = Modifier.padding(16.dp),
)
Text(
stringResource(statusInfo.status.nameResource),
fontSize = 18.sp,
modifier = Modifier.padding(0.dp, 16.dp, 16.dp, 16.dp),
)
}
}
}
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
@@ -0,0 +1,57 @@
package moe.crx.ovrport.ui
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import moe.crx.ovrport.patch.Constants.LOADING_COMPATIBILITY
import moe.crx.ovrport.patch.getCompatibilityStatus
import org.jetbrains.compose.resources.stringResource
@Composable
fun ApplicationStatus(
applicationName: String? = "Application",
applicationPackage: String? = "",
) {
var statusInfo by remember(applicationPackage) { mutableStateOf(LOADING_COMPATIBILITY) }
val urlHandler = LocalUriHandler.current
LaunchedEffect(applicationPackage) {
withContext(Dispatchers.IO) {
statusInfo = getCompatibilityStatus(applicationName, applicationPackage)
}
}
Card(colors = CardDefaults.cardColors(statusInfo.status.cardColor, statusInfo.status.contentColor)) {
Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip(
RoundedCornerShape(16.dp)
).clickable {
urlHandler.openUri(statusInfo.url)
}) {
Icon(
statusInfo.status.icon,
contentDescription = null,
modifier = Modifier.padding(16.dp),
)
Text(
stringResource(statusInfo.status.nameResource),
fontSize = 18.sp,
modifier = Modifier.padding(0.dp, 16.dp, 16.dp, 16.dp),
)
}
}
}
@@ -0,0 +1,37 @@
package moe.crx.ovrport.ui
import androidx.compose.animation.core.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bolt
import androidx.compose.material3.Icon
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import kotlinx.coroutines.delay
@Composable
fun BreathingIcon(modifier: Modifier, duration: Int = 1500) {
var isFaded by remember { mutableStateOf(false) }
val alpha by animateFloatAsState(
targetValue = if (isFaded) 0.2f else 1f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = duration, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
),
label = ""
)
LaunchedEffect(Unit) {
while (true) {
isFaded = !isFaded
delay(duration.toLong())
}
}
Icon(
Icons.Default.Bolt,
contentDescription = null,
modifier = modifier.alpha(alpha)
)
}
@@ -0,0 +1,20 @@
package moe.crx.ovrport.ui
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
@Composable
fun FadeVisibility(
condition: Boolean,
block: @Composable AnimatedVisibilityScope.() -> Unit
) {
AnimatedVisibility(
condition,
enter = fadeIn(),
exit = fadeOut(),
content = block
)
}
@@ -1,36 +1,14 @@
package moe.crx.ovrport.ui package moe.crx.ovrport.ui
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bolt
import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Download
import androidx.compose.material3.Card import androidx.compose.material3.*
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
@@ -39,7 +17,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import moe.crx.ovrport.AndroidPlatform import moe.crx.ovrport.AndroidPlatform
import moe.crx.ovrport.getPlatform import moe.crx.ovrport.getPlatform
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
@@ -125,30 +102,3 @@ fun StartingCard(
} }
} }
} }
@Composable
fun BreathingIcon(modifier: Modifier, duration: Int = 1500) {
var isFaded by remember { mutableStateOf(false) }
val alpha by animateFloatAsState(
targetValue = if (isFaded) 0.2f else 1f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = duration, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
),
label = ""
)
LaunchedEffect(Unit) {
while (true) {
isFaded = !isFaded
delay(duration.toLong())
}
}
Icon(
Icons.Default.Bolt,
contentDescription = null,
modifier = modifier.alpha(alpha)
)
}