diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 585073e..035d35d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -54,7 +54,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = "1.4.7" + kotlinCompilerExtensionVersion = "1.5.0" } packaging { @@ -87,7 +87,7 @@ dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1") implementation("androidx.activity:activity-compose:1.7.2") - val composeBom = platform("androidx.compose:compose-bom:2023.05.01") + val composeBom = platform("androidx.compose:compose-bom:2023.08.00") implementation(composeBom) implementation("androidx.compose.foundation:foundation") implementation("androidx.compose.material:material-icons-extended") @@ -97,28 +97,39 @@ dependencies { debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") - val cameraxVersion = "1.2.2" + implementation("androidx.emoji2:emoji2-views-helper") { + version { + strictly("1.4.0-beta05") + } + } + implementation("androidx.emoji2:emoji2") { + version { + strictly("1.4.0-beta05") + } + } + + val cameraxVersion = "1.2.3" implementation("androidx.camera:camera-core:$cameraxVersion") implementation("androidx.camera:camera-camera2:$cameraxVersion") implementation("androidx.camera:camera-view:$cameraxVersion") implementation("androidx.camera:camera-lifecycle:$cameraxVersion") - val roomVersion = "2.5.0" + val roomVersion = "2.5.2" implementation("androidx.room:room-common:$roomVersion") implementation("androidx.room:room-ktx:$roomVersion") ksp("androidx.room:room-compiler:$roomVersion") implementation("androidx.datastore:datastore-preferences:1.0.0") - implementation("com.github.X1nto.taxi:taxi:1.3.0") + implementation("dev.olshevski.navigation:reimagined:1.5.0-beta01") implementation("commons-codec:commons-codec:1.15") implementation("com.google.zxing:core:3.5.0") - implementation("io.coil-kt:coil-compose:2.3.0") + implementation("io.coil-kt:coil-compose:2.4.0") - implementation("io.insert-koin:koin-androidx-compose:3.4.3") + implementation("io.insert-koin:koin-androidx-compose:3.4.5") val accompanistVersion = "0.30.1" implementation("com.google.accompanist:accompanist-systemuicontroller:$accompanistVersion") diff --git a/app/src/main/java/com/xinto/mauth/ui/MainActivity.kt b/app/src/main/java/com/xinto/mauth/ui/MainActivity.kt index d24d4b9..f1c8601 100644 --- a/app/src/main/java/com/xinto/mauth/ui/MainActivity.kt +++ b/app/src/main/java/com/xinto/mauth/ui/MainActivity.kt @@ -4,16 +4,15 @@ import android.os.Bundle import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.animation.AnimatedContentScope +import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.animation.with +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen @@ -31,9 +30,11 @@ import com.xinto.mauth.ui.screen.home.HomeScreen import com.xinto.mauth.ui.screen.qrscan.QrScanScreen import com.xinto.mauth.ui.screen.settings.SettingsScreen import com.xinto.mauth.ui.theme.MauthTheme -import com.xinto.taxi.BackstackNavigator -import com.xinto.taxi.Taxi -import com.xinto.taxi.rememberBackstackNavigator +import dev.olshevski.navigation.reimagined.AnimatedNavHost +import dev.olshevski.navigation.reimagined.navigate +import dev.olshevski.navigation.reimagined.pop +import dev.olshevski.navigation.reimagined.rememberNavController +import dev.olshevski.navigation.reimagined.replaceAll import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.koin.android.ext.android.inject @@ -68,102 +69,96 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - val navigator = - rememberBackstackNavigator(MauthDestination.Home) + val navigator = rememberNavController(MauthDestination.Home) LaunchedEffect(intent.data) { val accountInfo = parseUriToAccountInfo(intent.data.toString()) if (accountInfo != null) { - navigator.push(MauthDestination.AddAccount(accountInfo)) + navigator.navigate(MauthDestination.AddAccount(accountInfo)) } } - Main(navigator) - } - } - } - } -} - -@Composable -fun Main(navigator: BackstackNavigator) { - Taxi( - navigator = navigator, - transitionSpec = { - when { - targetState.isFullscreenDialog -> { - slideIntoContainer( - towards = AnimatedContentScope.SlideDirection.Up, - animationSpec = spring( - dampingRatio = Spring.DampingRatioLowBouncy, - stiffness = Spring.StiffnessLow - ) - ) with fadeOut() - } - initialState.isFullscreenDialog -> { - fadeIn() with slideOutOfContainer( - towards = AnimatedContentScope.SlideDirection.Down, - animationSpec = spring( - stiffness = Spring.StiffnessVeryLow - ) - ) - } - else -> fadeIn() with fadeOut() - } - } - ) { screen -> - when (screen) { - is MauthDestination.Home -> { - HomeScreen( - onAddAccountManually = { - navigator.push(MauthDestination.AddAccount(DomainAccountInfo.DEFAULT)) - }, - onAddAccountViaScanning = { - navigator.push(MauthDestination.QrScanner) - }, - onAddAccountFromImage = { - navigator.push(MauthDestination.AddAccount(it)) - }, - onSettingsClick = { - navigator.push(MauthDestination.Settings) - }, - onAccountEdit = { - navigator.push(MauthDestination.EditAccount(it)) - } - ) - } - is MauthDestination.QrScanner -> { - QrScanScreen( - onBack = { - navigator.pop() - }, - onScan = { - navigator.replace(MauthDestination.AddAccount(it)) - } - ) - } - is MauthDestination.Settings -> { - SettingsScreen( - onBack = { - navigator.pop() - } - ) - } - is MauthDestination.AddAccount -> { - AddAccountScreen( - prefilled = screen.params, - onExit = { - navigator.pop() - } - ) - } - is MauthDestination.EditAccount -> { - EditAccountScreen( - id = screen.id, - onExit = { - navigator.pop() + AnimatedNavHost( + controller = navigator, + transitionSpec = { action, initial, target -> + when { + target.isFullscreenDialog -> { + slideIntoContainer( + towards = AnimatedContentTransitionScope.SlideDirection.Up, + animationSpec = spring( + dampingRatio = Spring.DampingRatioLowBouncy, + stiffness = Spring.StiffnessLow + ) + ) togetherWith fadeOut() + } + initial.isFullscreenDialog -> { + fadeIn() togetherWith slideOutOfContainer( + towards = AnimatedContentTransitionScope.SlideDirection.Down, + animationSpec = spring( + stiffness = Spring.StiffnessVeryLow + ) + ) + } + else -> fadeIn() togetherWith fadeOut() + } + } + ) { screen -> + when (screen) { + is MauthDestination.Home -> { + HomeScreen( + onAddAccountManually = { + navigator.navigate(MauthDestination.AddAccount(DomainAccountInfo.DEFAULT)) + }, + onAddAccountViaScanning = { + navigator.navigate(MauthDestination.QrScanner) + }, + onAddAccountFromImage = { + navigator.navigate(MauthDestination.AddAccount(it)) + }, + onSettingsClick = { + navigator.navigate(MauthDestination.Settings) + }, + onAccountEdit = { + navigator.navigate(MauthDestination.EditAccount(it)) + } + ) + } + is MauthDestination.QrScanner -> { + QrScanScreen( + onBack = { + navigator.pop() + }, + onScan = { + navigator.replaceAll(MauthDestination.AddAccount(it)) + } + ) + } + is MauthDestination.Settings -> { + SettingsScreen( + onBack = { + navigator.pop() + } + ) + } + is MauthDestination.AddAccount -> { + AddAccountScreen( + prefilled = screen.params, + onExit = { + navigator.pop() + } + ) + } + is MauthDestination.EditAccount -> { + EditAccountScreen( + id = screen.id, + onExit = { + navigator.pop() + } + ) + } + } } - ) + } } } } diff --git a/app/src/main/java/com/xinto/mauth/ui/navigation/MauthDestination.kt b/app/src/main/java/com/xinto/mauth/ui/navigation/MauthDestination.kt index abbeb5f..abc67d8 100644 --- a/app/src/main/java/com/xinto/mauth/ui/navigation/MauthDestination.kt +++ b/app/src/main/java/com/xinto/mauth/ui/navigation/MauthDestination.kt @@ -1,27 +1,27 @@ package com.xinto.mauth.ui.navigation +import android.os.Parcelable import com.xinto.mauth.domain.account.model.DomainAccountInfo -import com.xinto.taxi.Destination import kotlinx.parcelize.Parcelize -import java.util.* +import java.util.UUID -sealed class MauthDestination(val isFullscreenDialog: Boolean = false) : Destination { +sealed class MauthDestination(val isFullscreenDialog: Boolean = false) : Parcelable { @Parcelize - object Home : MauthDestination() + data object Home : MauthDestination() @Parcelize - object QrScanner : MauthDestination() + data object QrScanner : MauthDestination() @Parcelize - class AddAccount( + data class AddAccount( val params: DomainAccountInfo ) : MauthDestination(isFullscreenDialog = true) @Parcelize - class EditAccount( + data class EditAccount( val id: UUID, ) : MauthDestination(isFullscreenDialog = true) @Parcelize - object Settings : MauthDestination() + data object Settings : MauthDestination() } \ No newline at end of file diff --git a/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt b/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt index 460ee4f..da5e8b4 100644 --- a/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt +++ b/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt @@ -202,9 +202,10 @@ fun AccountScreenSuccess( AnimatedContent( targetState = type, transitionSpec = { - slideIntoContainer(AnimatedContentScope.SlideDirection.Up) + fadeIn() with - slideOutOfContainer(AnimatedContentScope.SlideDirection.Up) + fadeOut() - } + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeIn() with + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeOut() + }, + label = "HOTP/TOTP" ) { when (it) { OtpType.Totp -> { diff --git a/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeAccountCard.kt b/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeAccountCard.kt index 74833c8..a9b2ac5 100644 --- a/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeAccountCard.kt +++ b/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeAccountCard.kt @@ -167,13 +167,14 @@ private fun RealtimeInformation( targetState = code, transitionSpec = { if (initialState.first == targetState.first) { - slideIntoContainer(AnimatedContentScope.SlideDirection.Up) + fadeIn() with - slideOutOfContainer(AnimatedContentScope.SlideDirection.Up) + fadeOut() + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeIn() with + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeOut() } else { - slideIntoContainer(AnimatedContentScope.SlideDirection.Down) + fadeIn() with - slideOutOfContainer(AnimatedContentScope.SlideDirection.Down) + fadeOut() + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Down) + fadeIn() with + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Down) + fadeOut() } - } + }, + label = "Code" ) { (show, code) -> val showAwareCode = if (show) code else "•".repeat(code.length) Text(showAwareCode, style = MaterialTheme.typography.titleLarge) diff --git a/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeBottomBar.kt b/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeBottomBar.kt index b49db3c..6ac918a 100644 --- a/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeBottomBar.kt +++ b/app/src/main/java/com/xinto/mauth/ui/screen/home/component/HomeBottomBar.kt @@ -25,8 +25,8 @@ fun HomeBottomBar( AnimatedContent( targetState = isSelectionActive, transitionSpec = { - slideIntoContainer(AnimatedContentScope.SlideDirection.Up) + fadeIn() with - slideOutOfContainer(AnimatedContentScope.SlideDirection.Up) + fadeOut() + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeIn() with + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) + fadeOut() }, label = "Actions" ) { isSelectionActive -> diff --git a/build.gradle.kts b/build.gradle.kts index 5b19222..c427817 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.android.application") version "8.0.2" apply false - kotlin("android") version "1.8.21" apply false - id("com.google.devtools.ksp") version "1.8.21-1.0.11" apply false + id("com.android.application") version "8.1.0" apply false + kotlin("android") version "1.9.0" apply false + id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false } \ No newline at end of file