diff --git a/core/crash/src/main/java/ru/tech/imageresizershrinker/core/crash/CrashActivity.kt b/core/crash/src/main/java/ru/tech/imageresizershrinker/core/crash/CrashActivity.kt index 65a5c3592..41e391872 100644 --- a/core/crash/src/main/java/ru/tech/imageresizershrinker/core/crash/CrashActivity.kt +++ b/core/crash/src/main/java/ru/tech/imageresizershrinker/core/crash/CrashActivity.kt @@ -21,7 +21,6 @@ import android.content.Intent import android.graphics.Bitmap import android.os.Build import android.os.Bundle -import androidx.activity.compose.setContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState import androidx.compose.foundation.interaction.MutableInteractionSource @@ -92,6 +91,7 @@ import ru.tech.imageresizershrinker.core.ui.theme.White import ru.tech.imageresizershrinker.core.ui.theme.outlineVariant import ru.tech.imageresizershrinker.core.ui.utils.helper.AppActivityClass import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.copyToClipboard +import ru.tech.imageresizershrinker.core.ui.utils.provider.setContentWithWindowSizeClass import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedFloatingActionButton import ru.tech.imageresizershrinker.core.ui.widget.haptics.rememberCustomHapticFeedback @@ -117,7 +117,7 @@ class CrashActivity : CrashHandler() { "Device: ${Build.MODEL} (${Build.BRAND} - ${Build.DEVICE}), SDK: ${Build.VERSION.SDK_INT} (${Build.VERSION.RELEASE}), App: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\n\n" val body = "$deviceInfo$ex" - setContent { + setContentWithWindowSizeClass { val toastHostState = rememberToastHostState() val scope = rememberCoroutineScope() diff --git a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/animation/AnimationSpecs.kt b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/animation/AnimationSpecs.kt new file mode 100644 index 000000000..27f7855b7 --- /dev/null +++ b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/animation/AnimationSpecs.kt @@ -0,0 +1,57 @@ +/* + * ImageToolbox is an image editor for android + * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * You should have received a copy of the Apache License + * along with this program. If not, see . + */ + +package ru.tech.imageresizershrinker.core.ui.utils.animation + +import androidx.compose.animation.core.AnimationConstants.DefaultDurationMillis +import androidx.compose.animation.core.Easing +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.SpringSpec +import androidx.compose.animation.core.TweenSpec +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue + +object ImageToolboxUiFlags { + var disableAnimations: Boolean by mutableStateOf(true) +} + +@Stable +fun tweenSpec( + durationMillis: Int = DefaultDurationMillis, + delayMillis: Int = 0, + easing: Easing = FastOutSlowInEasing +): TweenSpec = tween( + durationMillis = if (ImageToolboxUiFlags.disableAnimations) 0 else durationMillis, + delayMillis = delayMillis, + easing = easing +) + +@Stable +fun springSpec( + dampingRatio: Float = Spring.DampingRatioNoBouncy, + stiffness: Float = Spring.StiffnessMedium, + visibilityThreshold: T? = null +): SpringSpec = spring( + dampingRatio = if (ImageToolboxUiFlags.disableAnimations) 1f else dampingRatio, + stiffness = if (ImageToolboxUiFlags.disableAnimations) 0f else stiffness, + visibilityThreshold = visibilityThreshold +) diff --git a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/helper/Ripple.kt b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/helper/Ripple.kt index cfd7b0a04..8a14ab907 100644 --- a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/helper/Ripple.kt +++ b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/helper/Ripple.kt @@ -18,9 +18,9 @@ package ru.tech.imageresizershrinker.core.ui.utils.helper import androidx.compose.foundation.Indication -import androidx.compose.material.LocalContentColor import androidx.compose.material.RippleDefaults -import androidx.compose.material.ripple +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.unit.Dp diff --git a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedAlertDialog.kt b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedAlertDialog.kt index bdde12047..efde1e79a 100644 --- a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedAlertDialog.kt +++ b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedAlertDialog.kt @@ -21,8 +21,6 @@ import androidx.activity.compose.PredictiveBackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.Spring import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn @@ -68,6 +66,8 @@ import androidx.compose.ui.unit.dp import com.t8rin.modalsheet.FullscreenPopup import kotlinx.coroutines.delay import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState +import ru.tech.imageresizershrinker.core.ui.utils.animation.springSpec +import ru.tech.imageresizershrinker.core.ui.utils.animation.tweenSpec import ru.tech.imageresizershrinker.core.ui.widget.modifier.alertDialogBorder @Composable @@ -172,8 +172,8 @@ fun BasicEnhancedAlertDialog( LaunchedEffect(Unit) { animateIn = true } AnimatedVisibility( visible = animateIn && visible, - enter = fadeIn(), - exit = fadeOut(), + enter = fadeIn(springSpec()), + exit = fadeOut(springSpec()), ) { val alpha = 0.5f * animatedScale @@ -186,16 +186,16 @@ fun BasicEnhancedAlertDialog( } AnimatedVisibility( visible = animateIn && visible, - enter = fadeIn(tween(300)) + scaleIn( + enter = fadeIn(tweenSpec(300)) + scaleIn( initialScale = .8f, - animationSpec = spring( + animationSpec = springSpec( dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessMediumLow ) ), - exit = fadeOut(tween(300)) + scaleOut( + exit = fadeOut(tweenSpec(300)) + scaleOut( targetScale = .8f, - animationSpec = spring( + animationSpec = springSpec( dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessMediumLow ) diff --git a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedModalBottomSheet.kt b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedModalBottomSheet.kt index a7b705c69..e67ef2657 100644 --- a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedModalBottomSheet.kt +++ b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/enhanced/EnhancedModalBottomSheet.kt @@ -22,7 +22,6 @@ import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope @@ -63,6 +62,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState import ru.tech.imageresizershrinker.core.ui.utils.animation.FancyTransitionEasing +import ru.tech.imageresizershrinker.core.ui.utils.animation.tweenSpec import ru.tech.imageresizershrinker.core.ui.utils.provider.ProvideContainerDefaults import ru.tech.imageresizershrinker.core.ui.widget.modifier.autoElevatedBorder import ru.tech.imageresizershrinker.core.ui.widget.modifier.drawHorizontalStroke @@ -385,9 +385,10 @@ object EnhancedBottomSheetDefaults { @Composable get() = MaterialTheme.colorScheme.scrim.copy(0.32f) - val animationSpec: AnimationSpec = tween( - durationMillis = 600, - easing = FancyTransitionEasing - ) + val animationSpec: AnimationSpec + get() = tweenSpec( + durationMillis = 600, + easing = FancyTransitionEasing + ) } \ No newline at end of file diff --git a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/preferences/PreferenceItemOverload.kt b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/preferences/PreferenceItemOverload.kt index 7a9c074e8..04bc76290 100644 --- a/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/preferences/PreferenceItemOverload.kt +++ b/core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/preferences/PreferenceItemOverload.kt @@ -22,7 +22,6 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable @@ -64,7 +63,6 @@ import ru.tech.imageresizershrinker.core.ui.shapes.IconShapeDefaults import ru.tech.imageresizershrinker.core.ui.utils.provider.ProvideContainerDefaults import ru.tech.imageresizershrinker.core.ui.widget.modifier.container -@OptIn(ExperimentalFoundationApi::class) @Composable fun PreferenceItemOverload( onClick: (() -> Unit)? = null, diff --git a/feature/media-picker/src/main/java/ru/tech/imageresizershrinker/feature/media_picker/presentation/MediaPickerActivity.kt b/feature/media-picker/src/main/java/ru/tech/imageresizershrinker/feature/media_picker/presentation/MediaPickerActivity.kt index ad564d659..dad9efd2d 100644 --- a/feature/media-picker/src/main/java/ru/tech/imageresizershrinker/feature/media_picker/presentation/MediaPickerActivity.kt +++ b/feature/media-picker/src/main/java/ru/tech/imageresizershrinker/feature/media_picker/presentation/MediaPickerActivity.kt @@ -19,7 +19,6 @@ package ru.tech.imageresizershrinker.feature.media_picker.presentation import android.content.Intent import android.net.Uri import android.os.Bundle -import androidx.activity.compose.setContent import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.SideEffect import androidx.compose.runtime.rememberCoroutineScope @@ -45,6 +44,7 @@ import ru.tech.imageresizershrinker.core.ui.utils.confetti.rememberConfettiHostS import ru.tech.imageresizershrinker.core.ui.utils.helper.ColorSchemeName import ru.tech.imageresizershrinker.core.ui.utils.helper.toClipData import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalImageLoader +import ru.tech.imageresizershrinker.core.ui.utils.provider.setContentWithWindowSizeClass import ru.tech.imageresizershrinker.core.ui.widget.haptics.rememberCustomHapticFeedback import ru.tech.imageresizershrinker.core.ui.widget.other.SecureModeHandler import ru.tech.imageresizershrinker.feature.media_picker.domain.model.AllowedMedia @@ -70,7 +70,7 @@ class MediaPickerActivity : M3Activity() { } else { getString(R.string.pick_single_media) } - setContent { + setContentWithWindowSizeClass { val settingsState = component.settingsState.toUiState( allEmojis = Emoji.allIcons(), allIconShapes = IconShapeDefaults.shapes,