[Compose] Upgrade to Compose Alpha 12 (#1743)
Also upgraded Mavericks and Dagger in the compose sample app
diff --git a/build.gradle b/build.gradle
index ab1533e..a180923 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,9 +2,9 @@
buildscript {
ext {
- composeVersion = '1.0.0-alpha11'
- kotlinVersion = '1.4.21-2'
- daggerVersion = '2.30.1'
+ composeVersion = '1.0.0-alpha12'
+ kotlinVersion = '1.4.30'
+ daggerVersion = '2.32'
}
repositories {
@@ -16,7 +16,7 @@
}
dependencies {
classpath 'org.ajoberstar:grgit:1.9.3'
- classpath 'com.android.tools.build:gradle:7.0.0-alpha05'
+ classpath 'com.android.tools.build:gradle:7.0.0-alpha06'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlinVersion"
classpath 'org.ajoberstar:grgit:1.9.3'
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 79f7a09..0ea3e8a 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https://services.gradle.org/distributions/gradle-6.8-all.zip
+distributionUrl=https://services.gradle.org/distributions/gradle-6.8.2-all.zip
diff --git a/lottie-compose/build.gradle b/lottie-compose/build.gradle
index 0d60d39..7cecc15 100644
--- a/lottie-compose/build.gradle
+++ b/lottie-compose/build.gradle
@@ -6,7 +6,7 @@
android {
compileSdkVersion 30
- buildToolsVersion "30.0.2"
+ buildToolsVersion "30.0.3"
defaultConfig {
minSdkVersion 21
diff --git a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt
index 8cf482e..1c7a10a 100644
--- a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt
+++ b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt
@@ -3,21 +3,14 @@
import androidx.annotation.FloatRange
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.aspectRatio
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.dispatch.withFrameNanos
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.AmbientContext
+import androidx.compose.ui.platform.LocalContext
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.LottieCompositionFactory
import com.airbnb.lottie.LottieDrawable
@@ -32,7 +25,7 @@
*/
@Composable
fun rememberLottieComposition(spec: LottieAnimationSpec): LottieCompositionResult {
- val context = AmbientContext.current
+ val context = LocalContext.current
var result: LottieCompositionResult by remember { mutableStateOf(LottieCompositionResult.Loading) }
DisposableEffect(spec) {
var isDisposed = false
diff --git a/sample-compose/build.gradle b/sample-compose/build.gradle
index dfc9d74..91745e7 100644
--- a/sample-compose/build.gradle
+++ b/sample-compose/build.gradle
@@ -34,7 +34,9 @@
"-Xallow-jvm-ir-dependencies",
"-Xskip-prerelease-check",
"-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
+ "-Xuse-experimental=androidx.compose.animation.ExperimentalAnimationApi",
"-Xopt-in=androidx.compose.material.ExperimentalMaterialApi",
+ "-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=com.airbnb.mvrx.InternalMavericksApi"
]
}
@@ -59,18 +61,18 @@
implementation project(':lottie-compose')
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.multidex:multidex:2.0.1'
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'com.google.android.material:material:1.2.1'
+ implementation 'androidx.activity:activity-ktx:1.2.0'
+ implementation 'androidx.activity:activity-compose:1.3.0-alpha02'
+ implementation 'com.google.android.material:material:1.3.0'
implementation "androidx.compose.ui:ui:$composeVersion"
implementation "androidx.compose.material:material:$composeVersion"
implementation "androidx.compose.material:material-icons-extended:$composeVersion"
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
- implementation "androidx.navigation:navigation-compose:1.0.0-alpha06"
- implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-rc01'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-rc01'
+ implementation "androidx.navigation:navigation-compose:1.0.0-alpha07"
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
- implementation "androidx.navigation:navigation-fragment-ktx:2.3.2"
- implementation "androidx.navigation:navigation-ui-ktx:2.3.2"
+ implementation "androidx.navigation:navigation-ui-ktx:2.3.3"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
@@ -78,13 +80,10 @@
implementation "com.google.dagger:dagger:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
- compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.6.0'
- kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.6.0'
-
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
- implementation "dev.chrisbanes.accompanist:accompanist-coil:0.5.0"
- implementation 'com.airbnb.android:mvrx:2.0.0-beta3'
+ implementation "dev.chrisbanes.accompanist:accompanist-coil:0.5.1"
+ implementation 'com.airbnb.android:mavericks:2.0.0'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/Ambients.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/Ambients.kt
deleted file mode 100644
index 7f2370a..0000000
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/Ambients.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.airbnb.lottie.sample.compose
-
-import androidx.activity.OnBackPressedDispatcher
-import androidx.compose.runtime.ambientOf
-
-val AmbientBackPressedDispatcher = ambientOf<OnBackPressedDispatcher> { error("No BackPressedDispatcher specified.") }
\ No newline at end of file
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/ComposeActivity.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/ComposeActivity.kt
index 318758c..ee7ae9e 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/ComposeActivity.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/ComposeActivity.kt
@@ -1,33 +1,22 @@
package com.airbnb.lottie.sample.compose
import android.os.Bundle
-import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
-import androidx.compose.material.BottomNavigation
-import androidx.compose.material.BottomNavigationItem
-import androidx.compose.material.Icon
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Text
+import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Providers
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.AmbientContext
-import androidx.compose.ui.platform.setContent
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
-import androidx.navigation.compose.KEY_ROUTE
-import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
-import androidx.navigation.compose.currentBackStackEntryAsState
-import androidx.navigation.compose.navigate
-import androidx.navigation.compose.rememberNavController
+import androidx.navigation.compose.*
import com.airbnb.lottie.compose.LottieAnimationSpec
import com.airbnb.lottie.sample.compose.lottiefiles.LottieFilesPage
import com.airbnb.lottie.sample.compose.player.PlayerPage
@@ -36,7 +25,7 @@
import com.airbnb.lottie.sample.compose.ui.LottieTheme
import com.airbnb.lottie.sample.compose.ui.Teal
import com.airbnb.lottie.sample.compose.ui.toColorSafe
-import com.airbnb.lottie.sample.compose.utils.AmbientNavController
+import com.airbnb.lottie.sample.compose.utils.LocalNavController
import com.airbnb.lottie.sample.compose.utils.getBase64String
class ComposeActivity : AppCompatActivity() {
@@ -53,8 +42,7 @@
val navController = rememberNavController()
Providers(
- AmbientNavController provides navController,
- AmbientBackPressedDispatcher provides (AmbientContext.current as ComponentActivity).onBackPressedDispatcher
+ LocalNavController provides navController,
) {
LottieTheme {
Scaffold(
@@ -71,7 +59,7 @@
BottomNavigationItem(
icon = {
Icon(
- imageVector = vectorResource(item.iconRes),
+ painter = painterResource(item.iconRes),
contentDescription = null
)
},
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/composables/SeekBar.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/composables/SeekBar.kt
deleted file mode 100644
index 8eacd76..0000000
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/composables/SeekBar.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.airbnb.lottie.sample.compose.composables
-
-import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.preferredHeight
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.gesture.DragObserver
-import androidx.compose.ui.gesture.dragGestureFilter
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-
-@Composable
-fun SeekBar(
- progress: Float,
- onProgressChanged: (Float) -> Unit,
- modifier: Modifier = Modifier,
- trackHeight: Dp = 2.dp,
- thumbRadius: Dp = 4.dp,
- unfilledTrackColor: Color = Color.LightGray,
- filledTrackColor: Color = Color.Red,
-) {
- var width = 0
- var dragStartProgress = 0f
- var dragDistanceX = 0f
- val dragObserver = remember {
- object : DragObserver {
- override fun onStart(downPosition: Offset) {
- dragStartProgress = downPosition.x / width.toFloat()
- if (width > 0) onProgressChanged(dragStartProgress)
- }
- override fun onDrag(dragDistance: Offset): Offset {
- dragDistanceX += dragDistance.x
- if (width > 0) {
- val newProgress = (dragStartProgress + dragDistanceX / width.toFloat()).coerceIn(0f, 1f)
- onProgressChanged(newProgress)
- }
- return dragDistance
- }
-
- override fun onStop(velocity: Offset) {
- dragDistanceX = 0f
- }
- }
- }
- Row(
- modifier = Modifier
- .onGloballyPositioned { width = it.size.width }
- .dragGestureFilter(dragObserver, startDragImmediately = true)
- .padding(vertical = 12.dp)
- .then(modifier)
- ) {
- Canvas(
- modifier = Modifier
- .preferredHeight(thumbRadius * 2f)
- .fillMaxWidth()
- ) {
- val thumbX = size.width * progress
- drawRect(
- color = unfilledTrackColor,
- topLeft = Offset(thumbX, size.height / 2f - trackHeight.toPx() / 2f),
- size = Size(size.width - thumbX, trackHeight.toPx())
- )
- drawRect(
- color = filledTrackColor,
- topLeft = Offset(0f, size.height / 2f - trackHeight.toPx() / 2f),
- size = Size(thumbX, trackHeight.toPx())
- )
- drawCircle(
- color = filledTrackColor,
- radius = thumbRadius.toPx(),
- center = Offset(thumbX, size.height / 2f)
- )
- }
- }
-}
-
-@Preview
-@Composable
-fun SeekBarPreview() {
- SeekBar(0.5f, {})
-}
\ No newline at end of file
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/DaggerMavericksViewModelFactory.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/DaggerMavericksViewModelFactory.kt
index 3887139..4d25a91 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/DaggerMavericksViewModelFactory.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/DaggerMavericksViewModelFactory.kt
@@ -4,7 +4,10 @@
import com.airbnb.lottie.sample.compose.LottieComposeApplication
import com.airbnb.mvrx.*
-abstract class DaggerMvRxViewModelFactory<VM : MavericksViewModel<S>, S : MavericksState>(
+inline fun <reified VM : MavericksViewModel<S>, S : MavericksState> daggerMavericksViewModelFactory() = DaggerMavericksViewModelFactory<VM, S>(VM::class.java)
+
+
+class DaggerMavericksViewModelFactory<VM : MavericksViewModel<S>, S : MavericksState>(
private val viewModelClass: Class<out MavericksViewModel<S>>
) : MavericksViewModelFactory<VM, S> {
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/MavericksModule.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/MavericksModule.kt
index 3d0fedc..6b8893b 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/MavericksModule.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/dagger/MavericksModule.kt
@@ -3,13 +3,11 @@
import com.airbnb.lottie.sample.compose.lottiefiles.LottieFilesRecentAndPopularViewModel
import com.airbnb.lottie.sample.compose.lottiefiles.LottieFilesSearchViewModel
import com.airbnb.lottie.sample.compose.showcase.ShowcaseViewModel
-import com.squareup.inject.assisted.dagger2.AssistedModule
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
-@AssistedModule
-@Module(includes = [AssistedInject_AppModule::class])
+@Module
interface AppModule {
@Binds
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesPage.kt
index 8cfe62e..a2edd2c 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesPage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesPage.kt
@@ -3,20 +3,17 @@
import androidx.annotation.StringRes
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.*
-import androidx.compose.runtime.savedinstancestate.savedInstanceState
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.platform.AmbientDensity
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.sample.compose.R
@@ -30,7 +27,7 @@
@Composable
fun LottieFilesPage() {
- var tab by savedInstanceState { LottieFilesTab.Recent }
+ var tab by rememberSaveable { mutableStateOf(LottieFilesTab.Recent) }
Column {
Marquee("LottieFiles")
@@ -74,7 +71,7 @@
onClick: () -> Unit
) {
val textWidth = remember { mutableStateOf(0) }
- val pxRatio = with(AmbientDensity.current) { 1.dp.toPx() }
+ val pxRatio = with(LocalDensity.current) { 1.dp.toPx() }
val tabWidth by animateDpAsState(if (isSelected) (textWidth.value / pxRatio).dp else 0.dp)
val tabAlpha by animateFloatAsState(if (isSelected) 1f else 0f)
Column(
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesRecentsAndPopularPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesRecentsAndPopularPage.kt
index d7d0ca8..1348d19 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesRecentsAndPopularPage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesRecentsAndPopularPage.kt
@@ -16,23 +16,23 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.navigate
-import com.airbnb.lottie.sample.compose.R
import com.airbnb.lottie.sample.compose.Route
import com.airbnb.lottie.sample.compose.api.AnimationDataV2
import com.airbnb.lottie.sample.compose.api.LottieFilesApi
import com.airbnb.lottie.sample.compose.composables.AnimationRow
import com.airbnb.lottie.sample.compose.dagger.AssistedViewModelFactory
-import com.airbnb.lottie.sample.compose.dagger.DaggerMvRxViewModelFactory
+import com.airbnb.lottie.sample.compose.dagger.daggerMavericksViewModelFactory
+import com.airbnb.lottie.sample.compose.utils.collectState
import com.airbnb.lottie.sample.compose.utils.findNavController
-import com.airbnb.lottie.sample.compose.utils.mavericksViewModelAndState
+import com.airbnb.lottie.sample.compose.utils.mavericksViewModel
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.MavericksViewModel
-import com.squareup.inject.assisted.Assisted
-import com.squareup.inject.assisted.AssistedInject
-import kotlinx.coroutines.Dispatchers
+import com.airbnb.mvrx.MavericksViewModelFactory
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@@ -67,7 +67,7 @@
fun fetchNextPage() = withState { state ->
fetchJob?.cancel()
if (state.currentPage >= state.lastPage) return@withState
- fetchJob = viewModelScope.launch(Dispatchers.IO) {
+ fetchJob = viewModelScope.launch {
val response = try {
Log.d(TAG, "Fetching page ${state.currentPage + 1}")
when (state.mode) {
@@ -92,19 +92,21 @@
fun setMode(mode: LottieFilesMode) = setState { copy(mode = mode) }
- @AssistedInject.Factory
+ @AssistedFactory
interface Factory : AssistedViewModelFactory<LottieFilesRecentAndPopularViewModel, LottieFilesRecentAndPopularState> {
override fun create(initialState: LottieFilesRecentAndPopularState): LottieFilesRecentAndPopularViewModel
}
- companion object : DaggerMvRxViewModelFactory<LottieFilesRecentAndPopularViewModel, LottieFilesRecentAndPopularState>(LottieFilesRecentAndPopularViewModel::class.java) {
+ companion object :
+ MavericksViewModelFactory<LottieFilesRecentAndPopularViewModel, LottieFilesRecentAndPopularState> by daggerMavericksViewModelFactory() {
private const val TAG = "LottieFilesVM"
}
}
@Composable
fun LottieFilesRecentAndPopularPage(mode: LottieFilesMode) {
- val (viewModel, state) = mavericksViewModelAndState<LottieFilesRecentAndPopularViewModel, LottieFilesRecentAndPopularState>()
+ val viewModel: LottieFilesRecentAndPopularViewModel = mavericksViewModel()
+ val state = viewModel.collectState()
val navController = findNavController()
SideEffect {
viewModel.setMode(mode)
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesSearchPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesSearchPage.kt
index a075b6c..37e48e2 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesSearchPage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/lottiefiles/LottieFilesSearchPage.kt
@@ -7,11 +7,7 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
-import androidx.compose.material.FloatingActionButton
-import androidx.compose.material.Icon
-import androidx.compose.material.OutlinedTextField
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
+import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Repeat
import androidx.compose.runtime.Composable
@@ -29,13 +25,16 @@
import com.airbnb.lottie.sample.compose.api.LottieFilesApi
import com.airbnb.lottie.sample.compose.composables.AnimationRow
import com.airbnb.lottie.sample.compose.dagger.AssistedViewModelFactory
-import com.airbnb.lottie.sample.compose.dagger.DaggerMvRxViewModelFactory
+import com.airbnb.lottie.sample.compose.dagger.daggerMavericksViewModelFactory
+import com.airbnb.lottie.sample.compose.utils.collectState
import com.airbnb.lottie.sample.compose.utils.findNavController
-import com.airbnb.lottie.sample.compose.utils.mavericksViewModelAndState
+import com.airbnb.lottie.sample.compose.utils.mavericksViewModel
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.MavericksViewModel
-import com.squareup.inject.assisted.Assisted
-import com.squareup.inject.assisted.AssistedInject
+import com.airbnb.mvrx.MavericksViewModelFactory
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@@ -60,7 +59,7 @@
if (query.isBlank()) {
setState { copy(results = emptyList(), currentPage = 1, lastPage = 1, fetchException = false) }
} else {
- fetchJob = viewModelScope.launch(Dispatchers.IO) {
+ fetchJob = viewModelScope.launch {
val results = try {
api.search(query, 1)
} catch (e: Exception) {
@@ -83,7 +82,7 @@
fun fetchNextPage() = withState { state ->
fetchJob?.cancel()
if (state.currentPage >= state.lastPage) return@withState
- fetchJob = viewModelScope.launch(Dispatchers.IO) {
+ fetchJob = viewModelScope.launch {
val response = try {
Log.d("Gabe", "Fetching page ${state.currentPage + 1}")
api.search(state.query, state.currentPage + 1)
@@ -103,17 +102,18 @@
fun setQuery(query: String) = setState { copy(query = query, currentPage = 1, results = emptyList()) }
- @AssistedInject.Factory
+ @AssistedFactory
interface Factory : AssistedViewModelFactory<LottieFilesSearchViewModel, LottieFilesSearchState> {
override fun create(initialState: LottieFilesSearchState): LottieFilesSearchViewModel
}
- companion object : DaggerMvRxViewModelFactory<LottieFilesSearchViewModel, LottieFilesSearchState>(LottieFilesSearchViewModel::class.java)
+ companion object : MavericksViewModelFactory<LottieFilesSearchViewModel, LottieFilesSearchState> by daggerMavericksViewModelFactory()
}
@Composable
fun LottieFilesSearchPage() {
- val (viewModel, state) = mavericksViewModelAndState<LottieFilesSearchViewModel, LottieFilesSearchState>()
+ val viewModel: LottieFilesSearchViewModel = mavericksViewModel()
+ val state = viewModel.collectState()
val navController = findNavController()
LottieFilesSearchPage(
state,
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt
index 85083db..a8c81f4 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt
@@ -1,50 +1,20 @@
package com.airbnb.lottie.sample.compose.player
import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.*
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.preferredSize
-import androidx.compose.foundation.layout.preferredWidth
+import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
-import androidx.compose.material.TopAppBar
+import androidx.compose.material.*
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Close
-import androidx.compose.material.icons.filled.Pause
-import androidx.compose.material.icons.filled.PlayArrow
-import androidx.compose.material.icons.filled.RemoveRedEye
-import androidx.compose.material.icons.filled.Repeat
-import androidx.compose.material.icons.filled.Warning
-import androidx.compose.material.rememberScaffoldState
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Providers
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.onCommit
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.material.icons.filled.*
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -58,31 +28,23 @@
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import com.airbnb.lottie.LottieComposition
-import com.airbnb.lottie.compose.LottieAnimation
-import com.airbnb.lottie.compose.LottieAnimationSpec
-import com.airbnb.lottie.compose.LottieAnimationState
-import com.airbnb.lottie.compose.LottieCompositionResult
-import com.airbnb.lottie.compose.rememberLottieAnimationState
-import com.airbnb.lottie.compose.rememberLottieComposition
-import com.airbnb.lottie.sample.compose.AmbientBackPressedDispatcher
+import com.airbnb.lottie.compose.*
import com.airbnb.lottie.sample.compose.BuildConfig
import com.airbnb.lottie.sample.compose.R
import com.airbnb.lottie.sample.compose.composables.DebouncedCircularProgressIndicator
-import com.airbnb.lottie.sample.compose.composables.SeekBar
import com.airbnb.lottie.sample.compose.ui.Teal
-import com.airbnb.lottie.sample.compose.utils.drawTopBorder
+import com.airbnb.lottie.sample.compose.utils.drawBottomBorder
import com.airbnb.lottie.sample.compose.utils.maybeBackground
import com.airbnb.lottie.sample.compose.utils.maybeDrawBorder
import kotlin.math.ceil
import kotlin.math.roundToInt
-@OptIn(ExperimentalAnimationApi::class)
@Composable
fun PlayerPage(
spec: LottieAnimationSpec,
animationBackgroundColor: Color? = null,
) {
- val backPressedDispatcher = AmbientBackPressedDispatcher.current
+ val backPressedDispatcher = LocalOnBackPressedDispatcherOwner.current.onBackPressedDispatcher
val compositionResult = rememberLottieComposition(spec)
val animationState = rememberLottieAnimationState(autoPlay = true, repeatCount = Integer.MAX_VALUE)
val scaffoldState = rememberScaffoldState()
@@ -180,24 +142,22 @@
)
}
}
- if (speedToolbar.value && !focusMode) {
+ ExpandVisibility(speedToolbar.value && !focusMode) {
SpeedToolbar(
speed = animationState.speed,
onSpeedChanged = { animationState.speed = it }
)
}
- if (backgroundColorToolbar.value && !focusMode) {
+ ExpandVisibility(!focusMode && backgroundColorToolbar.value) {
BackgroundColorToolbar(
animationBackgroundColor = animationBackgroundColor,
onColorChanged = { backgroundColor = it }
)
}
- AnimatedVisibility(
- visible = !focusMode,
- enter = expandVertically(),
- exit = shrinkVertically()
- ) {
+ ExpandVisibility(!focusMode) {
PlayerControlsRow(animationState, compositionResult())
+ }
+ ExpandVisibility(!focusMode) {
Toolbar(
border = borderToolbar,
speed = speedToolbar,
@@ -215,6 +175,17 @@
}
@Composable
+private fun ColumnScope.ExpandVisibility(visible: Boolean, content: @Composable () -> Unit) {
+ AnimatedVisibility(
+ visible = visible,
+ enter = expandVertically(),
+ exit = shrinkVertically()
+ ) {
+ content()
+ }
+}
+
+@Composable
private fun PlayerControlsRow(
animationState: LottieAnimationState,
composition: LottieComposition?,
@@ -231,8 +202,6 @@
) {
Row(
verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .drawTopBorder()
) {
Box(
contentAlignment = Alignment.Center
@@ -254,11 +223,10 @@
.padding(top = 48.dp, bottom = 8.dp)
)
}
- SeekBar(
- progress = animationState.progress,
- onProgressChanged = {
- animationState.progress = it
- },
+ Slider(
+ value = animationState.progress,
+ onValueChange = { animationState.progress = it },
+
modifier = Modifier.weight(1f)
)
IconButton(onClick = {
@@ -291,7 +259,7 @@
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
- .drawTopBorder()
+ .drawBottomBorder()
.padding(vertical = 12.dp, horizontal = 16.dp)
.fillMaxWidth()
) {
@@ -330,7 +298,7 @@
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
- .drawTopBorder()
+ .drawBottomBorder()
.padding(vertical = 12.dp, horizontal = 16.dp)
.fillMaxWidth()
) {
@@ -377,7 +345,12 @@
outlineMasksAndMattes: MutableState<Boolean>,
applyOpacityToLayers: MutableState<Boolean>,
) {
- Row(Modifier.horizontalScroll(rememberScrollState())) {
+ Row(
+ modifier = Modifier
+ .horizontalScroll(rememberScrollState())
+ .padding(horizontal = 8.dp)
+ .padding(bottom = 8.dp)
+ ) {
ToolbarChip(
iconRes = R.drawable.ic_masks_and_mattes,
label = stringResource(R.string.toolbar_item_masks),
@@ -440,7 +413,7 @@
textAlign = TextAlign.Left,
modifier = Modifier
.fillMaxWidth()
- .run { if (i != 0) drawTopBorder() else this }
+ .run { if (i != 0) drawBottomBorder() else this }
.padding(vertical = 12.dp, horizontal = 16.dp)
)
}
@@ -459,9 +432,5 @@
@Preview(name = "Player")
@Composable
fun PlayerPagePreview() {
- Providers(
- AmbientBackPressedDispatcher provides OnBackPressedDispatcher()
- ) {
- PlayerPage(LottieAnimationSpec.Url("https://lottiefiles.com/download/public/32922"))
- }
+ PlayerPage(LottieAnimationSpec.Url("https://lottiefiles.com/download/public/32922"))
}
\ No newline at end of file
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/ToolbarChip.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/ToolbarChip.kt
index 8a7fda9..69904b8 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/ToolbarChip.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/ToolbarChip.kt
@@ -13,8 +13,8 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -46,7 +46,7 @@
) {
if (iconRes != 0) {
Icon(
- vectorResource(iconRes),
+ painterResource(iconRes),
tint = if (isActivated) Color.White else unActivatedColor,
modifier = Modifier
.preferredSize(12.dp),
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/preview/PreviewPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/preview/PreviewPage.kt
index 95047f9..3db713b 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/preview/PreviewPage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/preview/PreviewPage.kt
@@ -4,40 +4,26 @@
import androidx.annotation.StringRes
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.preferredHeight
+import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Divider
-import androidx.compose.material.Icon
-import androidx.compose.material.OutlinedTextField
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
-import androidx.compose.material.TextButton
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.material.*
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.AmbientContext
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
+import androidx.navigation.compose.navigate
import com.airbnb.lottie.sample.compose.R
import com.airbnb.lottie.sample.compose.Route
import com.airbnb.lottie.sample.compose.composables.Marquee
import com.airbnb.lottie.sample.compose.ui.LottieTheme
import com.airbnb.lottie.sample.compose.utils.findNavController
-import androidx.navigation.compose.navigate
@Composable
fun PreviewPage() {
@@ -92,7 +78,7 @@
.preferredHeight(48.dp)
) {
Icon(
- vectorResource(iconRes),
+ painterResource(iconRes),
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(16.dp),
@@ -112,7 +98,7 @@
@Composable
fun AssetsDialog(isShowing: Boolean, onDismiss: () -> Unit, onAssetSelected: (assetName: String) -> Unit) {
if (!isShowing) return
- val context = AmbientContext.current
+ val context = LocalContext.current
val assets = context.assets.list("")
?.asSequence()
?.filter { it.endsWith(".json") || it.endsWith(".zip") }
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcasePage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcasePage.kt
index 11caae5..e00de2d 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcasePage.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcasePage.kt
@@ -16,15 +16,17 @@
import com.airbnb.lottie.sample.compose.composables.Loader
import com.airbnb.lottie.sample.compose.composables.Marquee
import com.airbnb.lottie.sample.compose.ui.LottieTheme
+import com.airbnb.lottie.sample.compose.utils.collectState
import com.airbnb.lottie.sample.compose.utils.findNavController
-import com.airbnb.lottie.sample.compose.utils.mavericksViewModelAndState
+import com.airbnb.lottie.sample.compose.utils.mavericksViewModel
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Uninitialized
@Composable
fun ShowcasePage() {
- val (_, showcaseState) = mavericksViewModelAndState<ShowcaseViewModel, ShowcaseState>()
- val featuredAnimations = showcaseState.animations
+ val viewModel: ShowcaseViewModel = mavericksViewModel()
+ val state = viewModel.collectState()
+ val featuredAnimations = state.animations
val navController = findNavController()
Box(
modifier = Modifier.fillMaxSize()
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcaseViewModel.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcaseViewModel.kt
index aea98d0..d92c7c2 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcaseViewModel.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/showcase/ShowcaseViewModel.kt
@@ -3,19 +3,19 @@
import com.airbnb.lottie.sample.compose.api.AnimationsResponseV2
import com.airbnb.lottie.sample.compose.api.LottieFilesApi
import com.airbnb.lottie.sample.compose.dagger.AssistedViewModelFactory
-import com.airbnb.lottie.sample.compose.dagger.DaggerMvRxViewModelFactory
+import com.airbnb.lottie.sample.compose.dagger.daggerMavericksViewModelFactory
import com.airbnb.mvrx.*
-import com.squareup.inject.assisted.Assisted
-import com.squareup.inject.assisted.AssistedInject
-import kotlinx.coroutines.Dispatchers
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
data class ShowcaseState(
val animations: Async<AnimationsResponseV2> = Uninitialized
) : MavericksState
class ShowcaseViewModel @AssistedInject constructor(
- @Assisted initialState: ShowcaseState,
- private var api: LottieFilesApi
+ @Assisted initialState: ShowcaseState,
+ private var api: LottieFilesApi
) : MavericksViewModel<ShowcaseState>(initialState) {
init {
@@ -25,15 +25,13 @@
private fun fetchFeatured() {
suspend {
api.getFeatured()
- }.execute(Dispatchers.IO) {
- copy(animations = it)
- }
+ }.execute { copy(animations = it) }
}
- @AssistedInject.Factory
+ @AssistedFactory
interface Factory : AssistedViewModelFactory<ShowcaseViewModel, ShowcaseState> {
override fun create(initialState: ShowcaseState): ShowcaseViewModel
}
- companion object : DaggerMvRxViewModelFactory<ShowcaseViewModel, ShowcaseState>(ShowcaseViewModel::class.java)
+ companion object : MavericksViewModelFactory<ShowcaseViewModel, ShowcaseState> by daggerMavericksViewModelFactory()
}
\ No newline at end of file
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/ComposeExtensions.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/ComposeExtensions.kt
index 05caca8..09e827b 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/ComposeExtensions.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/ComposeExtensions.kt
@@ -23,6 +23,10 @@
drawRect(color, Offset.Zero, size = Size(size.width, 1f))
})
+fun Modifier.drawBottomBorder(color: Color = Color.DarkGray) = this.then(drawBehind {
+ drawRect(color, Offset(0f, size.height - 1f), size = Size(size.width, 1f))
+})
+
fun Modifier.maybeDrawBorder(draw: Boolean, color: Color = Color.Black, width: Dp = 1.dp): Modifier {
return if (draw) {
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/MavericksExtensions.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/MavericksExtensions.kt
index d758483..7571440 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/MavericksExtensions.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/MavericksExtensions.kt
@@ -1,31 +1,53 @@
package com.airbnb.lottie.sample.compose.utils
-import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.ui.platform.AmbientContext
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import com.airbnb.mvrx.ActivityViewModelContext
-import com.airbnb.mvrx.Mavericks
-import com.airbnb.mvrx.MavericksState
-import com.airbnb.mvrx.MavericksViewModel
-import com.airbnb.mvrx.MavericksViewModelProvider
-import com.airbnb.mvrx.withState
+import androidx.navigation.NavBackStackEntry
+import com.airbnb.mvrx.*
@Composable
-inline fun <reified VM : MavericksViewModel<S>, reified S : MavericksState> mavericksViewModelAndState(): Pair<VM, S> {
- val viewModelClass = VM::class
- val activity = AmbientContext.current as? FragmentActivity ?: error("Composable is not hosted in a FragmentActivity")
- val keyFactory = { viewModelClass.java.name }
- @SuppressLint("RestrictedApi")
- val viewModel = MavericksViewModelProvider.get(
- viewModelClass = viewModelClass.java,
- stateClass = S::class.java,
- viewModelContext = ActivityViewModelContext(activity, activity.intent.extras?.get(Mavericks.KEY_ARG)),
- key = keyFactory()
- )
- val state by viewModel.stateFlow.collectAsState(initial = withState(viewModel) { it })
- return viewModel to state
+fun <VM : MavericksViewModel<S>, S : MavericksState> VM.collectState(): S {
+ val state by stateFlow.collectAsState(initial = withState(this) { it })
+ return state
}
+
+@Composable
+inline fun <reified VM : MavericksViewModel<S>, reified S : MavericksState> mavericksViewModel(): VM {
+ val viewModelClass = VM::class
+ val context = LocalContext.current
+ val viewModelContext = when (val lifecycleOwner = LocalLifecycleOwner.current) {
+ is Fragment -> {
+ val activity = lifecycleOwner.requireActivity()
+ val args = lifecycleOwner.arguments?.get(Mavericks.KEY_ARG)
+ FragmentViewModelContext(activity, args, lifecycleOwner)
+ }
+ is FragmentActivity -> {
+ val args = lifecycleOwner.intent.extras?.get(Mavericks.KEY_ARG)
+ ActivityViewModelContext(lifecycleOwner, args)
+ }
+ is NavBackStackEntry -> {
+ val args = lifecycleOwner.arguments?.get(Mavericks.KEY_ARG)
+ val activity = context as? FragmentActivity ?: error("Local context should be a FragmentActivity but it is a ${context::class.simpleName}!")
+ ActivityViewModelContext(activity, args)
+ }
+ else -> error("Unknown LifecycleOwner ${lifecycleOwner::class.simpleName}. Must be Fragment or Activity for now.")
+ }
+ val activity = context as? FragmentActivity ?: error("Composable is not hosted in a FragmentActivity")
+ return remember(viewModelClass, activity) {
+ val keyFactory = { viewModelClass.java.name }
+ @Suppress("RestrictedApi")
+ MavericksViewModelProvider.get(
+ viewModelClass = viewModelClass.java,
+ stateClass = S::class.java,
+ viewModelContext = viewModelContext,
+ key = keyFactory()
+ )
+ }
+}
\ No newline at end of file
diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/NavigationExtensions.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/NavigationExtensions.kt
index 68d1819..976ae33 100644
--- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/NavigationExtensions.kt
+++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/utils/NavigationExtensions.kt
@@ -3,13 +3,13 @@
import android.os.Bundle
import android.util.Base64
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.staticAmbientOf
+import androidx.compose.runtime.staticCompositionLocalOf
import androidx.navigation.NavController
import java.nio.charset.StandardCharsets
-val AmbientNavController = staticAmbientOf<NavController> { error("You must specify a NavController.") }
+val LocalNavController = staticCompositionLocalOf<NavController> { error("You must specify a NavController.") }
@Composable
-fun findNavController() = AmbientNavController.current
+fun findNavController() = LocalNavController.current
fun Bundle.getBase64String(key: String) = String(Base64.decode(getString(key), Base64.DEFAULT), StandardCharsets.UTF_8)
diff --git a/sample/src/main/kotlin/com/airbnb/lottie/samples/PreviewFragment.kt b/sample/src/main/kotlin/com/airbnb/lottie/samples/PreviewFragment.kt
index cdb3d1b..d6ad662 100644
--- a/sample/src/main/kotlin/com/airbnb/lottie/samples/PreviewFragment.kt
+++ b/sample/src/main/kotlin/com/airbnb/lottie/samples/PreviewFragment.kt
@@ -34,6 +34,7 @@
if (requireContext().hasPermission(Manifest.permission.CAMERA)) {
startActivity(QRScanActivity.intent(requireContext()))
} else {
+ @Suppress("DEPRECATION")
requestPermissions(arrayOf(Manifest.permission.CAMERA), RC_CAMERA_PERMISSION)
}
}
@@ -49,6 +50,7 @@
type = "*/*"
addCategory(Intent.CATEGORY_OPENABLE)
}
+ @Suppress("DEPRECATION")
startActivityForResult(Intent.createChooser(intent, "Select a JSON file"), RC_FILE)
} catch (ex: ActivityNotFoundException) {
// Potentially direct the user to the Market with a Dialog
diff --git a/sample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt b/sample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
index f5e879a..339a3ee 100644
--- a/sample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
+++ b/sample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
@@ -13,7 +13,6 @@
import com.airbnb.lottie.samples.views.marquee
import com.airbnb.lottie.samples.views.showcaseCarousel
import com.airbnb.mvrx.*
-import kotlinx.coroutines.Dispatchers
data class ShowcaseState(val response: Async<AnimationResponseV2> = Uninitialized) : MvRxState
@@ -21,11 +20,11 @@
init {
suspend {
api.getCollection()
- }.execute(Dispatchers.IO) { copy(response = it) }
+ }.execute { copy(response = it) }
}
companion object : MvRxViewModelFactory<ShowcaseViewModel, ShowcaseState> {
- override fun create(viewModelContext: ViewModelContext, state: ShowcaseState): ShowcaseViewModel? {
+ override fun create(viewModelContext: ViewModelContext, state: ShowcaseState): ShowcaseViewModel {
val service = viewModelContext.app<LottieApplication>().lottiefilesService
return ShowcaseViewModel(state, service)
}
diff --git a/sample/src/main/kotlin/com/airbnb/lottie/samples/testing/FilmStripSnapshotActivity.kt b/sample/src/main/kotlin/com/airbnb/lottie/samples/testing/FilmStripSnapshotActivity.kt
index aab597f..bcc9147 100644
--- a/sample/src/main/kotlin/com/airbnb/lottie/samples/testing/FilmStripSnapshotActivity.kt
+++ b/sample/src/main/kotlin/com/airbnb/lottie/samples/testing/FilmStripSnapshotActivity.kt
@@ -89,6 +89,7 @@
binding.filmStripView.draw(canvas)
val outputFileName = file.name.replace(".json", ".png")
+ @Suppress("DEPRECATION")
val outputFilePath = "${Environment.getExternalStorageDirectory()}/lottie/snapshots/$outputFileName"
FileOutputStream(outputFilePath).use {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)