Rewrite popups and bottom sheets to not use popup windows
Popup windows are too unrealiable
This commit is contained in:
parent
cbcd9cbfc7
commit
d7c9936014
@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.imePadding
|
|||||||
import androidx.compose.foundation.layout.offset
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.systemBars
|
import androidx.compose.foundation.layout.systemBars
|
||||||
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.shape.CornerSize
|
import androidx.compose.foundation.shape.CornerSize
|
||||||
@ -65,6 +66,7 @@ import androidx.compose.ui.window.Popup
|
|||||||
import androidx.compose.ui.window.PopupPositionProvider
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
import androidx.compose.ui.window.PopupProperties
|
import androidx.compose.ui.window.PopupProperties
|
||||||
import de.mm20.launcher2.ui.ktx.toPixels
|
import de.mm20.launcher2.ui.ktx.toPixels
|
||||||
|
import de.mm20.launcher2.ui.overlays.Overlay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -159,20 +161,11 @@ fun BottomSheetDialog(
|
|||||||
val positionProvider = remember(insets, density) {
|
val positionProvider = remember(insets, density) {
|
||||||
BottomSheetPositionProvider(insets, density)
|
BottomSheetPositionProvider(insets, density)
|
||||||
}
|
}
|
||||||
Popup(
|
Overlay(zIndex = 9999f) {
|
||||||
popupPositionProvider = positionProvider,
|
|
||||||
properties = PopupProperties(
|
|
||||||
dismissOnBackPress = dismissible(),
|
|
||||||
dismissOnClickOutside = dismissible(),
|
|
||||||
usePlatformDefaultWidth = false,
|
|
||||||
focusable = true,
|
|
||||||
clippingEnabled = false,
|
|
||||||
),
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
) {
|
|
||||||
BoxWithConstraints(
|
BoxWithConstraints(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
.systemBarsPadding()
|
||||||
.imePadding(),
|
.imePadding(),
|
||||||
propagateMinConstraints = true,
|
propagateMinConstraints = true,
|
||||||
contentAlignment = Alignment.BottomCenter
|
contentAlignment = Alignment.BottomCenter
|
||||||
|
|||||||
@ -55,6 +55,7 @@ import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
|
|||||||
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||||
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
||||||
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
||||||
|
import de.mm20.launcher2.ui.overlays.OverlayHost
|
||||||
import de.mm20.launcher2.ui.theme.LauncherTheme
|
import de.mm20.launcher2.ui.theme.LauncherTheme
|
||||||
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
|
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
@ -160,7 +161,7 @@ abstract class SharedLauncherActivity(
|
|||||||
systemUiController.isNavigationBarVisible = !hideNav
|
systemUiController.isNavigationBarVisible = !hideNav
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
OverlayHost(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(if (dimBackground) Color.Black.copy(alpha = 0.30f) else Color.Transparent),
|
.background(if (dimBackground) Color.Black.copy(alpha = 0.30f) else Color.Transparent),
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import android.app.PendingIntent
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.expandIn
|
import androidx.compose.animation.expandIn
|
||||||
import androidx.compose.animation.shrinkOut
|
import androidx.compose.animation.shrinkOut
|
||||||
@ -58,6 +59,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.lerp
|
||||||
import androidx.compose.ui.unit.roundToIntRect
|
import androidx.compose.ui.unit.roundToIntRect
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@ -428,7 +430,7 @@ fun AppItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun AppItemGridPopup(
|
fun AppItemGridPopup(
|
||||||
app: LauncherApp,
|
app: LauncherApp,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
@ -452,8 +454,8 @@ fun AppItemGridPopup(
|
|||||||
transformOrigin = TransformOrigin(1f, 0f)
|
transformOrigin = TransformOrigin(1f, 0f)
|
||||||
)
|
)
|
||||||
.offset(
|
.offset(
|
||||||
x = 16.dp * (1 - animationProgress).pow(10),
|
x = lerp(16.dp, 0.dp, animationProgress),
|
||||||
y = -16.dp * (1 - animationProgress),
|
y = lerp(-16.dp, 0.dp, animationProgress)
|
||||||
),
|
),
|
||||||
app = app,
|
app = app,
|
||||||
onBack = onDismiss
|
onBack = onDismiss
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package de.mm20.launcher2.ui.launcher.search.calendar
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.expandIn
|
import androidx.compose.animation.expandIn
|
||||||
@ -301,7 +302,7 @@ fun CalendarItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun CalendarItemGridPopup(
|
fun CalendarItemGridPopup(
|
||||||
calendar: CalendarEvent,
|
calendar: CalendarEvent,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -1,24 +1,30 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.common.grid
|
package de.mm20.launcher2.ui.launcher.search.common.grid
|
||||||
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
import android.util.Log
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.Animatable
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.absoluteOffset
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.ime
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.systemBars
|
||||||
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
|
import androidx.compose.foundation.layout.union
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -27,18 +33,18 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.boundsInWindow
|
import androidx.compose.ui.layout.boundsInWindow
|
||||||
|
import androidx.compose.ui.layout.layout
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.Density
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Popup
|
|
||||||
import androidx.compose.ui.window.PopupProperties
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import de.mm20.launcher2.search.SavableSearchable
|
import de.mm20.launcher2.search.SavableSearchable
|
||||||
import de.mm20.launcher2.search.Searchable
|
import de.mm20.launcher2.search.Searchable
|
||||||
import de.mm20.launcher2.search.data.AppShortcut
|
import de.mm20.launcher2.search.data.AppShortcut
|
||||||
@ -51,7 +57,6 @@ import de.mm20.launcher2.search.data.Wikipedia
|
|||||||
import de.mm20.launcher2.ui.component.LauncherCard
|
import de.mm20.launcher2.ui.component.LauncherCard
|
||||||
import de.mm20.launcher2.ui.component.LocalIconShape
|
import de.mm20.launcher2.ui.component.LocalIconShape
|
||||||
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||||
import de.mm20.launcher2.ui.ktx.toDp
|
|
||||||
import de.mm20.launcher2.ui.ktx.toPixels
|
import de.mm20.launcher2.ui.ktx.toPixels
|
||||||
import de.mm20.launcher2.ui.launcher.search.apps.AppItemGridPopup
|
import de.mm20.launcher2.ui.launcher.search.apps.AppItemGridPopup
|
||||||
import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItemGridPopup
|
import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItemGridPopup
|
||||||
@ -65,9 +70,10 @@ import de.mm20.launcher2.ui.launcher.search.wikipedia.WikipediaItemGridPopup
|
|||||||
import de.mm20.launcher2.ui.launcher.transitions.EnterHomeTransitionParams
|
import de.mm20.launcher2.ui.launcher.transitions.EnterHomeTransitionParams
|
||||||
import de.mm20.launcher2.ui.launcher.transitions.HandleEnterHomeTransition
|
import de.mm20.launcher2.ui.launcher.transitions.HandleEnterHomeTransition
|
||||||
import de.mm20.launcher2.ui.locals.LocalGridSettings
|
import de.mm20.launcher2.ui.locals.LocalGridSettings
|
||||||
import de.mm20.launcher2.ui.locals.LocalWindowPosition
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
||||||
import kotlinx.coroutines.delay
|
import de.mm20.launcher2.ui.overlays.Overlay
|
||||||
|
import kotlin.math.min
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -98,7 +104,8 @@ fun GridItem(
|
|||||||
onClick = {
|
onClick = {
|
||||||
if (!launchOnPress || !viewModel.launch(context, bounds)) {
|
if (!launchOnPress || !viewModel.launch(context, bounds)) {
|
||||||
showPopup = true
|
showPopup = true
|
||||||
}},
|
}
|
||||||
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||||
showPopup = true
|
showPopup = true
|
||||||
@ -106,7 +113,8 @@ fun GridItem(
|
|||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
),
|
),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
val badge by viewModel.badge.collectAsStateWithLifecycle()
|
val badge by viewModel.badge.collectAsStateWithLifecycle()
|
||||||
val icon by viewModel.icon.collectAsStateWithLifecycle()
|
val icon by viewModel.icon.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
@ -181,132 +189,133 @@ fun GridItem(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit) {
|
fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit) {
|
||||||
var show by remember { mutableStateOf(false) }
|
val show = remember {
|
||||||
LaunchedEffect(null) {
|
MutableTransitionState(false).apply {
|
||||||
show = true
|
targetState = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LaunchedEffect(show) {
|
val animationProgress = remember { Animatable(0f) }
|
||||||
if (!show) {
|
LaunchedEffect(show.targetState) {
|
||||||
delay(300L)
|
if (!show.targetState) {
|
||||||
|
animationProgress.animateTo(0f, tween(300))
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
|
} else {
|
||||||
|
animationProgress.animateTo(1f, tween(300))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackHandler {
|
BackHandler {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val animationProgress by animateFloatAsState(if (show) 1f else 0f, tween(300))
|
Overlay(zIndex = 1f) {
|
||||||
Popup(
|
Box(
|
||||||
properties = PopupProperties(
|
modifier = Modifier
|
||||||
usePlatformDefaultWidth = false,
|
.background(MaterialTheme.colorScheme.scrim.copy(alpha = 0.32f * animationProgress.value))
|
||||||
dismissOnBackPress = true
|
.fillMaxSize()
|
||||||
),
|
.systemBarsPadding()
|
||||||
alignment = Alignment.TopCenter,
|
.imePadding()
|
||||||
onDismissRequest = {
|
.padding(horizontal = 16.dp)
|
||||||
show = false
|
.pointerInput(Unit) {
|
||||||
},
|
detectTapGestures(onPress = {
|
||||||
offset = IntOffset(-origin.left.toInt(), 0)
|
show.targetState = false
|
||||||
) {
|
})
|
||||||
CompositionLocalProvider(LocalWindowPosition provides origin.top) {
|
},
|
||||||
Box(
|
) {
|
||||||
|
LauncherCard(
|
||||||
|
elevation = 8.dp * animationProgress.value,
|
||||||
|
backgroundOpacity = 1f,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.placeOverlay(
|
||||||
|
origin.translate(
|
||||||
|
-16.dp.toPixels(),
|
||||||
|
-WindowInsets.systemBars.union(WindowInsets.ime).getTop(LocalDensity.current).toFloat()
|
||||||
|
),
|
||||||
|
animationProgress.value
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
LauncherCard(
|
when (searchable) {
|
||||||
elevation = 8.dp * animationProgress,
|
is LauncherApp -> {
|
||||||
backgroundOpacity = 1f,
|
AppItemGridPopup(
|
||||||
modifier = Modifier
|
app = searchable,
|
||||||
.padding(horizontal = 16.dp)
|
show = show,
|
||||||
.absoluteOffset(
|
animationProgress = animationProgress.value,
|
||||||
x = ((1 - animationProgress) * origin.left).toDp() - 20.dp * (1 - animationProgress),
|
origin = origin,
|
||||||
|
onDismiss = {
|
||||||
|
show.targetState = false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.wrapContentSize()
|
}
|
||||||
.padding(4.dp)
|
|
||||||
) {
|
|
||||||
when (searchable) {
|
|
||||||
is LauncherApp -> {
|
|
||||||
AppItemGridPopup(
|
|
||||||
app = searchable,
|
|
||||||
show = show,
|
|
||||||
animationProgress = animationProgress,
|
|
||||||
origin = origin,
|
|
||||||
onDismiss = {
|
|
||||||
show = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is Website -> {
|
is Website -> {
|
||||||
WebsiteItemGridPopup(
|
WebsiteItemGridPopup(
|
||||||
website = searchable,
|
website = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is Wikipedia -> {
|
is Wikipedia -> {
|
||||||
WikipediaItemGridPopup(
|
WikipediaItemGridPopup(
|
||||||
wikipedia = searchable,
|
wikipedia = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is Contact -> {
|
is Contact -> {
|
||||||
ContactItemGridPopup(
|
ContactItemGridPopup(
|
||||||
contact = searchable,
|
contact = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is File -> {
|
is File -> {
|
||||||
FileItemGridPopup(
|
FileItemGridPopup(
|
||||||
file = searchable,
|
file = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is CalendarEvent -> {
|
is CalendarEvent -> {
|
||||||
CalendarItemGridPopup(
|
CalendarItemGridPopup(
|
||||||
calendar = searchable,
|
calendar = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is AppShortcut -> {
|
is AppShortcut -> {
|
||||||
ShortcutItemGridPopup(
|
ShortcutItemGridPopup(
|
||||||
shortcut = searchable,
|
shortcut = searchable,
|
||||||
show = show,
|
show = show,
|
||||||
animationProgress = animationProgress,
|
animationProgress = animationProgress.value,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
show = false
|
show.targetState = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,3 +323,42 @@ fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Modifier.placeOverlay(
|
||||||
|
origin: Rect,
|
||||||
|
animationProgress: Float,
|
||||||
|
): Modifier {
|
||||||
|
return layout { measurable, constraints ->
|
||||||
|
val placeable = measurable.measure(constraints)
|
||||||
|
Log.d(
|
||||||
|
"MM20",
|
||||||
|
"Layout: maxWidth: ${constraints.maxWidth}, origin: $origin, placeable: ${placeable.width}"
|
||||||
|
)
|
||||||
|
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||||
|
placeable.placeRelative(
|
||||||
|
(
|
||||||
|
lerp(
|
||||||
|
origin.center.x,
|
||||||
|
constraints.maxWidth / 2f,
|
||||||
|
((placeable.width.toFloat() - origin.width) / (constraints.maxWidth.toFloat() - origin.width))
|
||||||
|
) - placeable.width / 2f).toInt(),
|
||||||
|
lerp(
|
||||||
|
origin.top,
|
||||||
|
(origin.center.y - placeable.height / 2f).coerceIn(
|
||||||
|
0f,
|
||||||
|
constraints.maxHeight.toFloat() - placeable.height.toFloat(),
|
||||||
|
),
|
||||||
|
animationProgress.pow(2f)
|
||||||
|
).toInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lerp(start: Float, stop: Float, fraction: Float): Float {
|
||||||
|
return start + fraction * (stop - start)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lerp(start: Int, stop: Int, fraction: Float): Int {
|
||||||
|
return start + (fraction * (stop - start)).toInt()
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package de.mm20.launcher2.ui.launcher.search.contacts
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.animateDp
|
import androidx.compose.animation.core.animateDp
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
@ -402,7 +403,7 @@ fun ContactItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun ContactItemGridPopup(
|
fun ContactItemGridPopup(
|
||||||
contact: Contact,
|
contact: Contact,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.files
|
package de.mm20.launcher2.ui.launcher.search.files
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.animateDp
|
import androidx.compose.animation.core.animateDp
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
@ -322,7 +323,7 @@ fun FileItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun FileItemGridPopup(
|
fun FileItemGridPopup(
|
||||||
file: File,
|
file: File,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.animateDp
|
import androidx.compose.animation.core.animateDp
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
@ -284,7 +285,7 @@ fun AppShortcutItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun ShortcutItemGridPopup(
|
fun ShortcutItemGridPopup(
|
||||||
shortcut: AppShortcut,
|
shortcut: AppShortcut,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.website
|
package de.mm20.launcher2.ui.launcher.search.website
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.expandIn
|
import androidx.compose.animation.expandIn
|
||||||
import androidx.compose.animation.shrinkOut
|
import androidx.compose.animation.shrinkOut
|
||||||
@ -154,7 +155,7 @@ fun WebsiteItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun WebsiteItemGridPopup(
|
fun WebsiteItemGridPopup(
|
||||||
website: Website,
|
website: Website,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.wikipedia
|
package de.mm20.launcher2.ui.launcher.search.wikipedia
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.expandIn
|
import androidx.compose.animation.expandIn
|
||||||
import androidx.compose.animation.shrinkOut
|
import androidx.compose.animation.shrinkOut
|
||||||
@ -161,7 +162,7 @@ fun WikipediaItem(
|
|||||||
@Composable
|
@Composable
|
||||||
fun WikipediaItemGridPopup(
|
fun WikipediaItemGridPopup(
|
||||||
wikipedia: Wikipedia,
|
wikipedia: Wikipedia,
|
||||||
show: Boolean,
|
show: MutableTransitionState<Boolean>,
|
||||||
animationProgress: Float,
|
animationProgress: Float,
|
||||||
origin: Rect,
|
origin: Rect,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
package de.mm20.launcher2.ui.overlays
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Overlay(
|
||||||
|
zIndex: Float = 0f,
|
||||||
|
overlay: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
val overlayManager = LocalOverlayManager.current
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
overlayManager.addOverlay(overlay, zIndex)
|
||||||
|
onDispose {
|
||||||
|
overlayManager.removeOverlay(overlay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package de.mm20.launcher2.ui.overlays
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.zIndex
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OverlayHost(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
contentAlignment: Alignment = Alignment.TopStart,
|
||||||
|
content: @Composable BoxScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
val overlayManager = remember { OverlayManager() }
|
||||||
|
CompositionLocalProvider(LocalOverlayManager provides overlayManager) {
|
||||||
|
Box {
|
||||||
|
Box(
|
||||||
|
contentAlignment = contentAlignment,
|
||||||
|
modifier = modifier.zIndex(0f),
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
for (overlay in overlayManager.overlays) {
|
||||||
|
Box(modifier = Modifier.zIndex(overlay.zIndex + 1f)) {
|
||||||
|
overlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val LocalOverlayManager = compositionLocalOf<OverlayManager> {
|
||||||
|
OverlayManager()
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package de.mm20.launcher2.ui.overlays
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
|
||||||
|
class OverlayManager {
|
||||||
|
val overlays = mutableStateListOf<Overlay>()
|
||||||
|
|
||||||
|
fun addOverlay(overlay: @Composable () -> Unit, zIndex: Float = 0f) {
|
||||||
|
overlays.add(Overlay(overlay, zIndex))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeOverlay(overlay: @Composable () -> Unit) {
|
||||||
|
overlays.removeAll { overlay == it.overlay }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Overlay(
|
||||||
|
val overlay: @Composable () -> Unit,
|
||||||
|
val zIndex: Float = 0f,
|
||||||
|
) {
|
||||||
|
@Composable
|
||||||
|
operator fun invoke() {
|
||||||
|
overlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ import de.mm20.launcher2.ui.base.BaseActivity
|
|||||||
import de.mm20.launcher2.ui.base.ProvideSettings
|
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||||
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
||||||
|
import de.mm20.launcher2.ui.overlays.OverlayHost
|
||||||
import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen
|
import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
|
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
|
||||||
import de.mm20.launcher2.ui.settings.backup.BackupSettingsScreen
|
import de.mm20.launcher2.ui.settings.backup.BackupSettingsScreen
|
||||||
@ -78,129 +79,132 @@ class SettingsActivity : BaseActivity() {
|
|||||||
) {
|
) {
|
||||||
ProvideSettings {
|
ProvideSettings {
|
||||||
LauncherTheme {
|
LauncherTheme {
|
||||||
AnimatedNavHost(
|
OverlayHost {
|
||||||
navController = navController,
|
AnimatedNavHost(
|
||||||
startDestination = "settings",
|
navController = navController,
|
||||||
exitTransition = { fadeOut(tween(300, 300)) },
|
startDestination = "settings",
|
||||||
enterTransition = { fadeIn(tween(200)) },
|
exitTransition = { fadeOut(tween(300, 300)) },
|
||||||
popEnterTransition = { fadeIn(tween(0)) },
|
enterTransition = { fadeIn(tween(200)) },
|
||||||
popExitTransition = { fadeOut(tween(200)) },
|
popEnterTransition = { fadeIn(tween(0)) },
|
||||||
) {
|
popExitTransition = { fadeOut(tween(200)) },
|
||||||
composable("settings") {
|
|
||||||
MainSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/appearance") {
|
|
||||||
AppearanceSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/homescreen") {
|
|
||||||
HomescreenSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/icons") {
|
|
||||||
IconsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/appearance/themes") {
|
|
||||||
ThemesSettingsScreen()
|
|
||||||
}
|
|
||||||
composable(
|
|
||||||
"settings/appearance/themes/{id}",
|
|
||||||
arguments = listOf(navArgument("id") {
|
|
||||||
nullable = false
|
|
||||||
})) {
|
|
||||||
val id = it.arguments?.getString("id")?.let {
|
|
||||||
UUID.fromString(it)
|
|
||||||
} ?: return@composable
|
|
||||||
ThemeSettingsScreen(id)
|
|
||||||
}
|
|
||||||
composable("settings/appearance/cards") {
|
|
||||||
CardsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search") {
|
|
||||||
SearchSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/gestures") {
|
|
||||||
GestureSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/unitconverter") {
|
|
||||||
UnitConverterSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/wikipedia") {
|
|
||||||
WikipediaSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/files") {
|
|
||||||
FileSearchSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/searchactions") {
|
|
||||||
SearchActionsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/hiddenitems") {
|
|
||||||
HiddenItemsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/search/tags") {
|
|
||||||
TagsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable(ROUTE_WEATHER_INTEGRATION) {
|
|
||||||
WeatherIntegrationSettingsScreen()
|
|
||||||
}
|
|
||||||
composable(ROUTE_MEDIA_INTEGRATION) {
|
|
||||||
MediaIntegrationSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/homescreen/clock") {
|
|
||||||
ClockWidgetSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/favorites") {
|
|
||||||
FavoritesSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/integrations") {
|
|
||||||
IntegrationsSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/about") {
|
|
||||||
AboutSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/about/buildinfo") {
|
|
||||||
BuildInfoSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/about/easteregg") {
|
|
||||||
EasterEggSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/debug") {
|
|
||||||
DebugSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/backup") {
|
|
||||||
BackupSettingsScreen()
|
|
||||||
}
|
|
||||||
composable("settings/debug/crashreporter") {
|
|
||||||
CrashReporterScreen()
|
|
||||||
}
|
|
||||||
composable("settings/debug/logs") {
|
|
||||||
LogScreen()
|
|
||||||
}
|
|
||||||
composable(
|
|
||||||
"settings/debug/crashreporter/report?fileName={fileName}",
|
|
||||||
arguments = listOf(navArgument("fileName") {
|
|
||||||
nullable = false
|
|
||||||
})
|
|
||||||
) {
|
) {
|
||||||
val fileName = it.arguments?.getString("fileName")
|
composable("settings") {
|
||||||
?.let {
|
MainSettingsScreen()
|
||||||
URLDecoder.decode(it, "utf8")
|
}
|
||||||
}
|
composable("settings/appearance") {
|
||||||
CrashReportScreen(fileName!!)
|
AppearanceSettingsScreen()
|
||||||
}
|
}
|
||||||
composable(
|
composable("settings/homescreen") {
|
||||||
"settings/license?library={libraryName}",
|
HomescreenSettingsScreen()
|
||||||
arguments = listOf(navArgument("libraryName") {
|
}
|
||||||
nullable = true
|
composable("settings/icons") {
|
||||||
})
|
IconsSettingsScreen()
|
||||||
) {
|
}
|
||||||
val libraryName = it.arguments?.getString("libraryName")
|
composable("settings/appearance/themes") {
|
||||||
val library = remember(libraryName) {
|
ThemesSettingsScreen()
|
||||||
if (libraryName == null) {
|
}
|
||||||
AppLicense.get(this@SettingsActivity)
|
composable(
|
||||||
} else {
|
"settings/appearance/themes/{id}",
|
||||||
OpenSourceLicenses.first { it.name == libraryName }
|
arguments = listOf(navArgument("id") {
|
||||||
}
|
nullable = false
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
val id = it.arguments?.getString("id")?.let {
|
||||||
|
UUID.fromString(it)
|
||||||
|
} ?: return@composable
|
||||||
|
ThemeSettingsScreen(id)
|
||||||
|
}
|
||||||
|
composable("settings/appearance/cards") {
|
||||||
|
CardsSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search") {
|
||||||
|
SearchSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/gestures") {
|
||||||
|
GestureSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/unitconverter") {
|
||||||
|
UnitConverterSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/wikipedia") {
|
||||||
|
WikipediaSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/files") {
|
||||||
|
FileSearchSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/searchactions") {
|
||||||
|
SearchActionsSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/hiddenitems") {
|
||||||
|
HiddenItemsSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/search/tags") {
|
||||||
|
TagsSettingsScreen()
|
||||||
|
}
|
||||||
|
composable(ROUTE_WEATHER_INTEGRATION) {
|
||||||
|
WeatherIntegrationSettingsScreen()
|
||||||
|
}
|
||||||
|
composable(ROUTE_MEDIA_INTEGRATION) {
|
||||||
|
MediaIntegrationSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/homescreen/clock") {
|
||||||
|
ClockWidgetSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/favorites") {
|
||||||
|
FavoritesSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/integrations") {
|
||||||
|
IntegrationsSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/about") {
|
||||||
|
AboutSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/about/buildinfo") {
|
||||||
|
BuildInfoSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/about/easteregg") {
|
||||||
|
EasterEggSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/debug") {
|
||||||
|
DebugSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/backup") {
|
||||||
|
BackupSettingsScreen()
|
||||||
|
}
|
||||||
|
composable("settings/debug/crashreporter") {
|
||||||
|
CrashReporterScreen()
|
||||||
|
}
|
||||||
|
composable("settings/debug/logs") {
|
||||||
|
LogScreen()
|
||||||
|
}
|
||||||
|
composable(
|
||||||
|
"settings/debug/crashreporter/report?fileName={fileName}",
|
||||||
|
arguments = listOf(navArgument("fileName") {
|
||||||
|
nullable = false
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
val fileName = it.arguments?.getString("fileName")
|
||||||
|
?.let {
|
||||||
|
URLDecoder.decode(it, "utf8")
|
||||||
|
}
|
||||||
|
CrashReportScreen(fileName!!)
|
||||||
|
}
|
||||||
|
composable(
|
||||||
|
"settings/license?library={libraryName}",
|
||||||
|
arguments = listOf(navArgument("libraryName") {
|
||||||
|
nullable = true
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
val libraryName = it.arguments?.getString("libraryName")
|
||||||
|
val library = remember(libraryName) {
|
||||||
|
if (libraryName == null) {
|
||||||
|
AppLicense.get(this@SettingsActivity)
|
||||||
|
} else {
|
||||||
|
OpenSourceLicenses.first { it.name == libraryName }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LicenseScreen(library)
|
||||||
}
|
}
|
||||||
LicenseScreen(library)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user