Rewrite popup animations, fix crash

This commit is contained in:
MM20 2023-08-11 12:58:29 +02:00
parent 039f49749f
commit 57c081229b
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
7 changed files with 279 additions and 284 deletions

View File

@ -2,15 +2,11 @@ package de.mm20.launcher2.ui.launcher.search.apps
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Intent import android.content.Intent
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeOut import androidx.compose.animation.expandIn
import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.shrinkOut
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.with
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box 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.fillMaxWidth
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.requiredHeight
import androidx.compose.foundation.layout.requiredSize import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
@ -52,6 +46,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect 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.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.roundToIntRect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import coil.compose.AsyncImage 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.SubmenuToolbarAction
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel 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 de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt
@Composable @Composable
fun AppItem( fun AppItem(
@ -438,21 +432,17 @@ fun AppItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
slideInHorizontally( animationSpec = tween(300),
tween(300), expandFrom = Alignment.TopEnd,
initialOffsetX = { -it + origin.width.roundToInt() }) with ) { origin.roundToIntRect().size },
slideOutHorizontally( exit = shrinkOut(
tween(300), animationSpec = tween(300),
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using shrinkTowards = Alignment.TopEnd,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) ) {
}
}
) { targetState ->
if (targetState) {
AppItem( AppItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -467,12 +457,5 @@ fun AppItemGridPopup(
app = app, app = app,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -2,24 +2,17 @@ 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.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkOut
import androidx.compose.animation.with
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding 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.Icons
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Edit 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.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.roundToIntRect
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.search.data.CalendarEvent import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.ui.R 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.DefaultToolbarAction
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel import de.mm20.launcher2.ui.launcher.search.listItemViewModel
@ -313,17 +306,17 @@ fun CalendarItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
fadeIn(snap()) with animationSpec = tween(300),
fadeOut(snap(400)) using expandFrom = Alignment.Center,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) exit = shrinkOut(
} animationSpec = tween(300),
} shrinkTowards = Alignment.Center,
) { targetState -> ) { origin.roundToIntRect().size },
if (targetState) { ) {
CalendarItem( CalendarItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -332,13 +325,6 @@ fun CalendarItemGridPopup(
showDetails = true, showDetails = true,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -2,24 +2,17 @@ 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.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.core.animateDp import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.fadeIn import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkOut
import androidx.compose.animation.with
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
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.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons 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.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.roundToIntRect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.ktx.tryStartActivity 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.component.ToolbarAction
import de.mm20.launcher2.ui.icons.Telegram import de.mm20.launcher2.ui.icons.Telegram
import de.mm20.launcher2.ui.icons.WhatsApp 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel import de.mm20.launcher2.ui.launcher.search.listItemViewModel
@ -386,17 +379,17 @@ fun ContactItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
fadeIn(snap()) with animationSpec = tween(300),
fadeOut(snap(400)) using expandFrom = Alignment.TopStart,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) exit = shrinkOut(
} animationSpec = tween(300),
} shrinkTowards = Alignment.TopStart,
) { targetState -> ) { origin.roundToIntRect().size },
if (targetState) { ) {
ContactItem( ContactItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -412,12 +405,5 @@ fun ContactItemGridPopup(
showDetails = true, showDetails = true,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -1,15 +1,39 @@
package de.mm20.launcher2.ui.launcher.search.files 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.animateDp
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition 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.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.* import androidx.compose.material.icons.rounded.Delete
import androidx.compose.runtime.* 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect 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.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.roundToIntRect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.search.data.File import de.mm20.launcher2.search.data.File
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.animation.animateTextStyleAsState 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.ShapedLauncherIcon
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel 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 de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.DecimalFormat import java.text.DecimalFormat
import kotlin.math.roundToInt
@Composable @Composable
fun FileItem( fun FileItem(
@ -265,7 +287,10 @@ fun FileItem(
onBack() onBack()
lifecycleOwner.lifecycleScope.launch { lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar( 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), actionLabel = context.getString(R.string.action_undo),
duration = SnackbarDuration.Short, duration = SnackbarDuration.Short,
) )
@ -302,21 +327,17 @@ fun FileItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
slideInHorizontally( animationSpec = tween(300),
tween(300), expandFrom = Alignment.TopEnd,
initialOffsetX = { -it + origin.width.roundToInt() }) with ) { origin.roundToIntRect().size },
slideOutHorizontally( exit = shrinkOut(
tween(300), animationSpec = tween(300),
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using shrinkTowards = Alignment.TopEnd,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) ) {
}
}
) { targetState ->
if (targetState) {
FileItem( FileItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -332,13 +353,6 @@ fun FileItemGridPopup(
showDetails = true, showDetails = true,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -4,13 +4,41 @@ package de.mm20.launcher2.ui.launcher.search.shortcut
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.provider.Settings import android.provider.Settings
import androidx.compose.animation.* import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.* import androidx.compose.animation.core.animateDp
import androidx.compose.foundation.layout.* 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.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.* import androidx.compose.material.icons.rounded.Delete
import androidx.compose.runtime.* 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.Modifier
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.TransformOrigin 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.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.roundToIntRect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.data.AppShortcut import de.mm20.launcher2.search.data.AppShortcut
import de.mm20.launcher2.search.data.LauncherShortcut 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.ShapedLauncherIcon
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel 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 de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt
@Composable @Composable
fun AppShortcutItem( fun AppShortcutItem(
@ -263,21 +289,17 @@ fun ShortcutItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
slideInHorizontally( animationSpec = tween(300),
tween(300), expandFrom = Alignment.TopEnd,
initialOffsetX = { -it + origin.width.roundToInt() }) with ) { origin.roundToIntRect().size },
slideOutHorizontally( exit = shrinkOut(
tween(300), animationSpec = tween(300),
targetOffsetX = { -it + origin.width.roundToInt() }) + fadeOut(snap(400)) using shrinkTowards = Alignment.TopEnd,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) ) {
}
}
) { targetState ->
if (targetState) {
AppShortcutItem( AppShortcutItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -293,13 +315,6 @@ fun ShortcutItemGridPopup(
showDetails = true, showDetails = true,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -1,29 +1,41 @@
package de.mm20.launcher2.ui.launcher.search.website 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.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable 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.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.MaterialTheme
import androidx.compose.material3.Text 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.Modifier
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.compose.ui.unit.roundToIntRect
import coil.compose.AsyncImage import coil.compose.AsyncImage
import de.mm20.launcher2.search.data.Website 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.DefaultToolbarAction
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel import de.mm20.launcher2.ui.launcher.search.listItemViewModel
@ -59,7 +71,8 @@ fun WebsiteItem(
.background(MaterialTheme.colorScheme.secondaryContainer), .background(MaterialTheme.colorScheme.secondaryContainer),
model = website.image, model = website.image,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
contentDescription = null) contentDescription = null
)
} }
Column( Column(
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
@ -146,29 +159,22 @@ fun WebsiteItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
fadeIn(tween(200)) with animationSpec = tween(300),
fadeOut(tween(200, 200)) using expandFrom = Alignment.Center,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) exit = shrinkOut(
} animationSpec = tween(300),
} shrinkTowards = Alignment.Center,
) { targetState -> ) { origin.roundToIntRect().size },
if (targetState) { ) {
WebsiteItem( WebsiteItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth(), .fillMaxWidth(),
website = website, website = website,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }

View File

@ -1,29 +1,41 @@
package de.mm20.launcher2.ui.launcher.search.wikipedia 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.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable 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.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.MaterialTheme
import androidx.compose.material3.Text 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.Modifier
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.compose.ui.unit.roundToIntRect
import coil.compose.AsyncImage import coil.compose.AsyncImage
import de.mm20.launcher2.search.data.Wikipedia import de.mm20.launcher2.search.data.Wikipedia
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.DefaultToolbarAction import de.mm20.launcher2.ui.component.DefaultToolbarAction
import de.mm20.launcher2.ui.component.Toolbar import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import de.mm20.launcher2.ui.launcher.search.listItemViewModel import de.mm20.launcher2.ui.launcher.search.listItemViewModel
@ -154,29 +166,22 @@ fun WikipediaItemGridPopup(
origin: Rect, origin: Rect,
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
AnimatedContent( AnimatedVisibility(
targetState = show, show,
transitionSpec = { enter = expandIn(
fadeIn(tween(200)) with animationSpec = tween(300),
fadeOut(tween(200, 200)) using expandFrom = Alignment.Center,
SizeTransform { _, _ -> ) { origin.roundToIntRect().size },
tween(300) exit = shrinkOut(
} animationSpec = tween(300),
} shrinkTowards = Alignment.Center,
) { targetState -> ) { origin.roundToIntRect().size },
if (targetState) { ) {
WikipediaItem( WikipediaItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth(), .fillMaxWidth(),
wikipedia = wikipedia, wikipedia = wikipedia,
onBack = onDismiss onBack = onDismiss
) )
} else {
Box(
modifier = Modifier
.requiredWidth(origin.width.toDp())
.requiredHeight(origin.height.toDp())
)
}
} }
} }