Fix some animation issue
This commit is contained in:
		
							parent
							
								
									90d6c4bd65
								
							
						
					
					
						commit
						befb235b8b
					
				
					 7 changed files with 61 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable.pages
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.background
 | 
			
		||||
import androidx.compose.foundation.layout.*
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.shape.RoundedCornerShape
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,7 @@ import androidx.compose.runtime.livedata.observeAsState
 | 
			
		|||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.draw.clip
 | 
			
		||||
import androidx.compose.ui.focus.focusModifier
 | 
			
		||||
import androidx.compose.ui.graphics.ColorFilter
 | 
			
		||||
import androidx.compose.ui.layout.ContentScale
 | 
			
		||||
import androidx.compose.ui.platform.LocalContext
 | 
			
		||||
| 
						 | 
				
			
			@ -43,9 +45,13 @@ fun DetailPageComposable(
 | 
			
		|||
    booksViewModel: IBooksViewModel = viewModel<BooksViewModel>(),
 | 
			
		||||
    bookId: Int
 | 
			
		||||
) {
 | 
			
		||||
    val book by booksViewModel.getBookDetail(bookId).observeAsState()
 | 
			
		||||
    book?.let {
 | 
			
		||||
        DetailPageComposable(book = it)
 | 
			
		||||
    Box(
 | 
			
		||||
        Modifier.fillMaxWidth().fillMaxHeight()
 | 
			
		||||
    ) {
 | 
			
		||||
        val book by booksViewModel.getBookDetail(bookId).observeAsState()
 | 
			
		||||
        book?.let {
 | 
			
		||||
            DetailPageComposable(book = it)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +63,7 @@ fun DetailPageComposable(book: BookUio) {
 | 
			
		|||
        modifier = Modifier
 | 
			
		||||
            .fillMaxHeight()
 | 
			
		||||
            .verticalScroll(rememberScrollState())
 | 
			
		||||
            .background(MaterialTheme.colors.background)
 | 
			
		||||
            .padding(horizontal = 16.dp)
 | 
			
		||||
    ) {
 | 
			
		||||
        Image(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@ package com.pixelized.biblib.ui.composable.screen
 | 
			
		|||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.util.Log
 | 
			
		||||
import androidx.compose.animation.AnimatedVisibility
 | 
			
		||||
import androidx.compose.animation.ExperimentalAnimationApi
 | 
			
		||||
import androidx.compose.animation.expandVertically
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +227,7 @@ private fun ColumnScope.Title() {
 | 
			
		|||
            .padding(vertical = 16.dp)
 | 
			
		||||
            .align(alignment = Alignment.CenterHorizontally),
 | 
			
		||||
        style = typography.h4,
 | 
			
		||||
        text = stringResource(id = R.string.welcome_sign_in)
 | 
			
		||||
        text = stringResource(id = R.string.authentication_title)
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable.screen
 | 
			
		||||
 | 
			
		||||
import androidx.compose.animation.*
 | 
			
		||||
import androidx.compose.animation.core.tween
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.material.*
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.sharp.ArrowBack
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +15,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
 | 
			
		|||
import com.pixelized.biblib.R
 | 
			
		||||
import com.pixelized.biblib.ui.composable.pages.DetailPageComposable
 | 
			
		||||
import com.pixelized.biblib.ui.composable.pages.HomePageComposable
 | 
			
		||||
import com.pixelized.biblib.ui.theme.Animation
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.book.BooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
 | 
			
		||||
| 
						 | 
				
			
			@ -65,16 +68,28 @@ fun MainScreenComposable(
 | 
			
		|||
        AnimatedVisibility(
 | 
			
		||||
            visible = page is Page.HomePage,
 | 
			
		||||
            initiallyVisible = true,
 | 
			
		||||
            enter = slideInHorizontally(initialOffsetX = { width -> -width }),
 | 
			
		||||
            exit = slideOutHorizontally(targetOffsetX = { width -> -width }),
 | 
			
		||||
            enter = slideInHorizontally(
 | 
			
		||||
                animationSpec = tween(Animation.MEDIUM_DURATION),
 | 
			
		||||
                initialOffsetX = { width -> -width }
 | 
			
		||||
            ),
 | 
			
		||||
            exit = slideOutHorizontally(
 | 
			
		||||
                animationSpec = tween(Animation.MEDIUM_DURATION),
 | 
			
		||||
                targetOffsetX = { width -> -width }
 | 
			
		||||
            ),
 | 
			
		||||
        ) {
 | 
			
		||||
            HomePageComposable(navigationViewModel, booksViewModel)
 | 
			
		||||
        }
 | 
			
		||||
        AnimatedVisibility(
 | 
			
		||||
            visible = page is Page.Detail,
 | 
			
		||||
            initiallyVisible = false,
 | 
			
		||||
            enter = slideInHorizontally(initialOffsetX = { width -> width }),
 | 
			
		||||
            exit = slideOutHorizontally(targetOffsetX = { width -> width }),
 | 
			
		||||
            enter = slideInHorizontally(
 | 
			
		||||
                animationSpec = tween(Animation.MEDIUM_DURATION),
 | 
			
		||||
                initialOffsetX = { width -> width },
 | 
			
		||||
            ),
 | 
			
		||||
            exit = slideOutHorizontally(
 | 
			
		||||
                animationSpec = tween(Animation.MEDIUM_DURATION),
 | 
			
		||||
                targetOffsetX = { width -> width },
 | 
			
		||||
            ),
 | 
			
		||||
        ) {
 | 
			
		||||
            // Small trick to display the detail page during animation exit.
 | 
			
		||||
            var currentPage by remember { mutableStateOf<Page.Detail?>(null) }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ import com.pixelized.biblib.BuildConfig
 | 
			
		|||
import com.pixelized.biblib.R
 | 
			
		||||
import com.pixelized.biblib.ui.composable.items.dialog.CrossFadeOverlay
 | 
			
		||||
import com.pixelized.biblib.ui.composable.items.dialog.ErrorCard
 | 
			
		||||
import com.pixelized.biblib.ui.theme.Animation
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.authentication.AuthenticationViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.authentication.IAuthenticationViewModel
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +30,6 @@ import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
 | 
			
		|||
import kotlinx.coroutines.delay
 | 
			
		||||
import java.util.*
 | 
			
		||||
 | 
			
		||||
private const val ANIMATION_DURATION = 1000
 | 
			
		||||
private const val LAUNCH_EFFECT_AUTHENTICATION = "LAUNCH_EFFECT_AUTHENTICATION"
 | 
			
		||||
private const val LAUNCH_EFFECT_BOOK = "LAUNCH_EFFECT_BOOK"
 | 
			
		||||
private const val LAUNCH_EFFECT_NAVIGATION = "LAUNCH_EFFECT_NAVIGATION"
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ fun SplashScreenComposable(
 | 
			
		|||
) {
 | 
			
		||||
    val authenticationState: IAuthenticationViewModel.State? by authenticationViewModel.state.observeAsState()
 | 
			
		||||
    val bookState by bookViewModel.state.observeAsState()
 | 
			
		||||
    val contentVisible = remember { mutableStateOf(true) }
 | 
			
		||||
    val contentVisible = remember { mutableStateOf(false) }
 | 
			
		||||
 | 
			
		||||
    // Content
 | 
			
		||||
    ContentComposable(
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,10 @@ fun SplashScreenComposable(
 | 
			
		|||
    BookError(state = bookState as? IBooksViewModel.State.Error)
 | 
			
		||||
 | 
			
		||||
    LaunchedEffect(LAUNCH_EFFECT_AUTHENTICATION) {
 | 
			
		||||
        delay(1500)
 | 
			
		||||
        delay(Animation.SHORT_DURATION.toLong())
 | 
			
		||||
        contentVisible.value = true
 | 
			
		||||
        delay(Animation.LONG_DURATION.toLong())
 | 
			
		||||
        delay(Animation.SHORT_DURATION.toLong())
 | 
			
		||||
        authenticationViewModel.autoLogin()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,14 +88,14 @@ fun SplashScreenComposable(
 | 
			
		|||
            (bookState as? IBooksViewModel.State.Finished)?.let {
 | 
			
		||||
                LaunchedEffect(LAUNCH_EFFECT_NAVIGATION) {
 | 
			
		||||
                    contentVisible.value = false
 | 
			
		||||
                    delay(1000)
 | 
			
		||||
                    delay(Animation.LONG_DURATION.toLong())
 | 
			
		||||
                    navigationViewModel.navigateTo(Screen.MainScreen)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            LaunchedEffect(LAUNCH_EFFECT_NAVIGATION) {
 | 
			
		||||
                contentVisible.value = false
 | 
			
		||||
                delay(1000)
 | 
			
		||||
                delay(Animation.LONG_DURATION.toLong())
 | 
			
		||||
                navigationViewModel.navigateTo(Screen.LoginScreen)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +105,7 @@ fun SplashScreenComposable(
 | 
			
		|||
@OptIn(ExperimentalAnimationApi::class)
 | 
			
		||||
@Composable
 | 
			
		||||
private fun ContentComposable(
 | 
			
		||||
    duration: Int = ANIMATION_DURATION,
 | 
			
		||||
    duration: Int = Animation.LONG_DURATION,
 | 
			
		||||
    visible: Boolean = false,
 | 
			
		||||
    initiallyVisible: Boolean = false,
 | 
			
		||||
) {
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +138,7 @@ private fun ContentComposable(
 | 
			
		|||
            ) {
 | 
			
		||||
                Text(
 | 
			
		||||
                    style = typography.h4,
 | 
			
		||||
                    text = "Welcome to"
 | 
			
		||||
                    text = stringResource(id = R.string.splash_welcome)
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
            AnimatedVisibility(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
package com.pixelized.biblib.ui.theme
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
object Animation {
 | 
			
		||||
    const val SHORT_DURATION = 300
 | 
			
		||||
    const val MEDIUM_DURATION = 500
 | 
			
		||||
    const val LONG_DURATION = 1000
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
 | 
			
		|||
            .asPagingSourceFactory(Dispatchers.Default)
 | 
			
		||||
 | 
			
		||||
    override val books: Flow<PagingData<BookThumbnailUio>> = Pager(
 | 
			
		||||
        config = PagingConfig(pageSize = 20),
 | 
			
		||||
        config = PagingConfig(pageSize = PAGING_SIZE),
 | 
			
		||||
        pagingSourceFactory = source
 | 
			
		||||
    ).flow
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,4 +104,8 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
 | 
			
		|||
        series = series?.name,
 | 
			
		||||
        description = synopsis ?: "",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val PAGING_SIZE = 30
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
    <string name="app_name">BibLib</string>
 | 
			
		||||
    <string name="app_version">%1$s: %2$s - %3$d</string>
 | 
			
		||||
 | 
			
		||||
    <!--  Actions -->
 | 
			
		||||
 | 
			
		||||
    <string name="action_register">Register</string>
 | 
			
		||||
    <string name="action_login">Login</string>
 | 
			
		||||
    <string name="action_epub">EPUB</string>
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +11,8 @@
 | 
			
		|||
    <string name="action_send">SEND</string>
 | 
			
		||||
    <string name="action_google_sign_in">Sign in with Google</string>
 | 
			
		||||
 | 
			
		||||
    <!--  Dialogs -->
 | 
			
		||||
 | 
			
		||||
    <string name="error_generic">Oops!</string>
 | 
			
		||||
    <string name="error_authentication">Oops, connection failed!</string>
 | 
			
		||||
    <string name="error_book">Oops! library download failed!</string>
 | 
			
		||||
| 
						 | 
				
			
			@ -19,8 +23,11 @@
 | 
			
		|||
    <string name="success_authentication">Authentication successful</string>
 | 
			
		||||
    <string name="success_book">Library successfully loaded</string>
 | 
			
		||||
 | 
			
		||||
    <string name="welcome_sign_in">Sign in to BibLib</string>
 | 
			
		||||
    <!--  Screens & pages -->
 | 
			
		||||
 | 
			
		||||
    <string name="splash_welcome">Welcome to</string>
 | 
			
		||||
 | 
			
		||||
    <string name="authentication_title">Sign in to BibLib</string>
 | 
			
		||||
    <string name="authentication_login">Login</string>
 | 
			
		||||
    <string name="authentication_password">Password</string>
 | 
			
		||||
    <string name="authentication_credential_remember">Remember my credential</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue