compose: Initial migration of AppDetails* logic to compose [1/*]

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2025-03-25 15:19:11 +08:00
parent 9ccbd62df0
commit f6f858e9f5
61 changed files with 2528 additions and 509 deletions

View File

@@ -74,6 +74,19 @@ fun Context.share(app: App) {
}
}
fun Context.mailTo(email: String) {
try {
val sendIntent = Intent().apply {
action = Intent.ACTION_SENDTO
data = "mailto:".toUri()
putExtra(Intent.EXTRA_EMAIL, email)
}
startActivity(Intent.createChooser(sendIntent, getString(R.string.details_dev_email)))
} catch (exception: Exception) {
Log.e(TAG, "Failed to email", exception)
}
}
fun Context.openInfo(packageName: String) {
try {
val intent = Intent(

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.aurora.extensions
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
/**
* Gets viewModel from the parent composable if exists
*/
@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.parentViewModel(navController: NavController): T {
val navGraphRoute = navController.graph.findStartDestination().route ?: return hiltViewModel()
val parentEntry = remember(this) { navController.getBackStackEntry(navGraphRoute) }
return hiltViewModel<T>(parentEntry)
}

View File

@@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.aurora.extensions
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.IntSize
/**
* Modifier for composable to play shimmer animation
* @param toShow Whether to play shimmer animation
*/
fun Modifier.shimmer(toShow: Boolean): Modifier {
return composed {
if (toShow) {
val shimmerColors = listOf(
Color.LightGray.copy(alpha = 0.6f),
Color.LightGray.copy(alpha = 0.2f),
Color.LightGray.copy(alpha = 0.6f)
)
var size by remember { mutableStateOf(IntSize.Zero) }
val transition = rememberInfiniteTransition()
val transitionAnimation = transition.animateFloat(
initialValue = 0f,
targetValue = 1000f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse
)
)
background(
brush = Brush.linearGradient(
colors = shimmerColors,
start = Offset.Zero,
end = Offset(x = transitionAnimation.value, y = transitionAnimation.value)
)
).onGloballyPositioned { size = it.size }
} else {
Modifier
}
}
}

View File

@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.aurora.extensions
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp
/**
* Text style for composable with very small text
*/
val Typography.bodyVerySmall: TextStyle
@Composable
get() = MaterialTheme.typography.bodySmall.copy(fontSize = 10.sp)