Rewrite popup animations, fix crash
This commit is contained in:
parent
039f49749f
commit
57c081229b
@ -2,15 +2,11 @@ package de.mm20.launcher2.ui.launcher.search.apps
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@ -20,9 +16,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredHeight
|
||||
import androidx.compose.foundation.layout.requiredSize
|
||||
import androidx.compose.foundation.layout.requiredWidth
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
@ -52,6 +46,7 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
@ -62,6 +57,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import coil.compose.AsyncImage
|
||||
@ -74,7 +70,6 @@ import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||
import de.mm20.launcher2.ui.component.SubmenuToolbarAction
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -85,7 +80,6 @@ import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||
import de.mm20.launcher2.ui.modifier.scale
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
fun AppItem(
|
||||
@ -438,41 +432,30 @@ fun AppItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
slideInHorizontally(
|
||||
tween(300),
|
||||
initialOffsetX = { -it + origin.width.roundToInt() }) with
|
||||
slideOutHorizontally(
|
||||
tween(300),
|
||||
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
AppItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 84f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress).pow(10),
|
||||
y = -16.dp * (1 - animationProgress),
|
||||
),
|
||||
app = app,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
AppItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 84f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress).pow(10),
|
||||
y = -16.dp * (1 - animationProgress),
|
||||
),
|
||||
app = app,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,24 +2,17 @@ package de.mm20.launcher2.ui.launcher.search.calendar
|
||||
|
||||
import android.content.Context
|
||||
import android.text.format.DateUtils
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredHeight
|
||||
import androidx.compose.foundation.layout.requiredWidth
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
@ -51,6 +44,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import de.mm20.launcher2.search.data.CalendarEvent
|
||||
import de.mm20.launcher2.ui.R
|
||||
@ -58,7 +52,6 @@ import de.mm20.launcher2.ui.animation.animateTextStyleAsState
|
||||
import de.mm20.launcher2.ui.component.DefaultToolbarAction
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -313,32 +306,25 @@ fun CalendarItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
fadeIn(snap()) with
|
||||
fadeOut(snap(400)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
CalendarItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Color(calendar.color).copy(alpha = 1f - animationProgress)),
|
||||
calendar = calendar,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
CalendarItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Color(calendar.color).copy(alpha = 1f - animationProgress)),
|
||||
calendar = calendar,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,24 +2,17 @@ package de.mm20.launcher2.ui.launcher.search.contacts
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.core.animateDp
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredHeight
|
||||
import androidx.compose.foundation.layout.requiredWidth
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
@ -51,6 +44,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import de.mm20.launcher2.ktx.tryStartActivity
|
||||
@ -64,7 +58,6 @@ import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.icons.Telegram
|
||||
import de.mm20.launcher2.ui.icons.WhatsApp
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -386,38 +379,31 @@ fun ContactItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
fadeIn(snap()) with
|
||||
fadeOut(snap(400)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
ContactItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 48f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(0f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = -16.dp * (1 - animationProgress),
|
||||
y = -16.dp * (1 - animationProgress)
|
||||
),
|
||||
contact = contact,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.TopStart,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.TopStart,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
ContactItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 48f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(0f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = -16.dp * (1 - animationProgress),
|
||||
y = -16.dp * (1 - animationProgress)
|
||||
),
|
||||
contact = contact,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,39 @@
|
||||
package de.mm20.launcher2.ui.launcher.search.files
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateDp
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.Delete
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
import androidx.compose.material.icons.rounded.OpenInNew
|
||||
import androidx.compose.material.icons.rounded.Share
|
||||
import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.material.icons.rounded.StarOutline
|
||||
import androidx.compose.material.icons.rounded.Visibility
|
||||
import androidx.compose.material.icons.rounded.VisibilityOff
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
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.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
@ -19,9 +43,9 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.search.data.File
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.animation.animateTextStyleAsState
|
||||
@ -29,7 +53,6 @@ import de.mm20.launcher2.ui.component.DefaultToolbarAction
|
||||
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -40,7 +63,6 @@ import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||
import de.mm20.launcher2.ui.modifier.scale
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
fun FileItem(
|
||||
@ -265,11 +287,14 @@ fun FileItem(
|
||||
onBack()
|
||||
lifecycleOwner.lifecycleScope.launch {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = context.getString(R.string.msg_item_hidden, file.label),
|
||||
message = context.getString(
|
||||
R.string.msg_item_hidden,
|
||||
file.label
|
||||
),
|
||||
actionLabel = context.getString(R.string.action_undo),
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
if(result == SnackbarResult.ActionPerformed) {
|
||||
)
|
||||
if (result == SnackbarResult.ActionPerformed) {
|
||||
viewModel.unhide()
|
||||
}
|
||||
}
|
||||
@ -302,43 +327,32 @@ fun FileItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
slideInHorizontally(
|
||||
tween(300),
|
||||
initialOffsetX = { -it + origin.width.roundToInt() }) with
|
||||
slideOutHorizontally(
|
||||
tween(300),
|
||||
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
FileItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 48f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress),
|
||||
y = -16.dp * (1 - animationProgress)
|
||||
),
|
||||
file = file,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
FileItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 48f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress),
|
||||
y = -16.dp * (1 - animationProgress)
|
||||
),
|
||||
file = file,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,13 +4,41 @@ package de.mm20.launcher2.ui.launcher.search.shortcut
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateDp
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.Delete
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
import androidx.compose.material.icons.rounded.Info
|
||||
import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.material.icons.rounded.StarOutline
|
||||
import androidx.compose.material.icons.rounded.Visibility
|
||||
import androidx.compose.material.icons.rounded.VisibilityOff
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
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.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.graphics.TransformOrigin
|
||||
@ -19,9 +47,9 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ktx.tryStartActivity
|
||||
import de.mm20.launcher2.search.data.AppShortcut
|
||||
import de.mm20.launcher2.search.data.LauncherShortcut
|
||||
@ -32,7 +60,6 @@ import de.mm20.launcher2.ui.component.DefaultToolbarAction
|
||||
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -43,7 +70,6 @@ import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||
import de.mm20.launcher2.ui.modifier.scale
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
fun AppShortcutItem(
|
||||
@ -263,43 +289,32 @@ fun ShortcutItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
slideInHorizontally(
|
||||
tween(300),
|
||||
initialOffsetX = { -it + origin.width.roundToInt() }) with
|
||||
slideOutHorizontally(
|
||||
tween(300),
|
||||
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
AppShortcutItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 84f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress).pow(10),
|
||||
y = -16.dp * (1 - animationProgress),
|
||||
),
|
||||
shortcut = shortcut,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.TopEnd,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
AppShortcutItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.scale(
|
||||
1 - (1 - LocalGridSettings.current.iconSize / 84f) * (1 - animationProgress),
|
||||
transformOrigin = TransformOrigin(1f, 0f)
|
||||
)
|
||||
.offset(
|
||||
x = 16.dp * (1 - animationProgress).pow(10),
|
||||
y = -16.dp * (1 - animationProgress),
|
||||
),
|
||||
shortcut = shortcut,
|
||||
showDetails = true,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,29 +1,41 @@
|
||||
package de.mm20.launcher2.ui.launcher.search.website
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.*
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
import androidx.compose.material.icons.rounded.Share
|
||||
import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.material.icons.rounded.StarOutline
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import coil.compose.AsyncImage
|
||||
import de.mm20.launcher2.search.data.Website
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.DefaultToolbarAction
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -59,7 +71,8 @@ fun WebsiteItem(
|
||||
.background(MaterialTheme.colorScheme.secondaryContainer),
|
||||
model = website.image,
|
||||
contentScale = ContentScale.Crop,
|
||||
contentDescription = null)
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
@ -111,7 +124,7 @@ fun WebsiteItem(
|
||||
toolbarActions.add(
|
||||
DefaultToolbarAction(
|
||||
label = stringResource(R.string.menu_share),
|
||||
icon= Icons.Rounded.Share,
|
||||
icon = Icons.Rounded.Share,
|
||||
action = {
|
||||
website.share(context)
|
||||
}
|
||||
@ -146,29 +159,22 @@ fun WebsiteItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
fadeIn(tween(200)) with
|
||||
fadeOut(tween(200, 200)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
WebsiteItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
website = website,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
WebsiteItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
website = website,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,29 +1,41 @@
|
||||
package de.mm20.launcher2.ui.launcher.search.wikipedia
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.*
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
import androidx.compose.material.icons.rounded.Share
|
||||
import androidx.compose.material.icons.rounded.Star
|
||||
import androidx.compose.material.icons.rounded.StarOutline
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.compose.ui.unit.roundToIntRect
|
||||
import coil.compose.AsyncImage
|
||||
import de.mm20.launcher2.search.data.Wikipedia
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.DefaultToolbarAction
|
||||
import de.mm20.launcher2.ui.component.Toolbar
|
||||
import de.mm20.launcher2.ui.component.ToolbarAction
|
||||
import de.mm20.launcher2.ui.ktx.toDp
|
||||
import de.mm20.launcher2.ui.ktx.toPixels
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
import de.mm20.launcher2.ui.launcher.search.listItemViewModel
|
||||
@ -154,29 +166,22 @@ fun WikipediaItemGridPopup(
|
||||
origin: Rect,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = show,
|
||||
transitionSpec = {
|
||||
fadeIn(tween(200)) with
|
||||
fadeOut(tween(200, 200)) using
|
||||
SizeTransform { _, _ ->
|
||||
tween(300)
|
||||
}
|
||||
}
|
||||
) { targetState ->
|
||||
if (targetState) {
|
||||
WikipediaItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
wikipedia = wikipedia,
|
||||
onBack = onDismiss
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.requiredWidth(origin.width.toDp())
|
||||
.requiredHeight(origin.height.toDp())
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
show,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(300),
|
||||
expandFrom = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
exit = shrinkOut(
|
||||
animationSpec = tween(300),
|
||||
shrinkTowards = Alignment.Center,
|
||||
) { origin.roundToIntRect().size },
|
||||
) {
|
||||
WikipediaItem(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
wikipedia = wikipedia,
|
||||
onBack = onDismiss
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user