Skip to content

Commit

Permalink
ui: DELETED shared elements transitions
Browse files Browse the repository at this point in the history
perf: Improved tracks loading
refactor: Deleted unnecessary utilities

Signed-off-by: Gabriel Fontán <[email protected]>
  • Loading branch information
BobbyESP committed May 14, 2024
1 parent a9dafa6 commit f2d02c9
Show file tree
Hide file tree
Showing 26 changed files with 120 additions and 525 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ fun HomePage(

var desiredLayout by remember {
mutableStateOf(
Preferences.EnumPrefs.getValue(
Preferences.Enumerations.getValue(
DESIRED_OVERLAY, LayoutType.Grid
)
)
Expand Down Expand Up @@ -256,7 +256,7 @@ private fun DropdownMenuContent(

var desiredOverlay by remember {
mutableIntStateOf(
Preferences.EnumPrefs.getValue(
Preferences.Enumerations.getValue(
DESIRED_OVERLAY, LayoutType.Grid
).ordinal
)
Expand All @@ -279,7 +279,7 @@ private fun DropdownMenuContent(
selected = desiredOverlay == listType.ordinal,
onClick = {
desiredOverlay = listType.ordinal
Preferences.EnumPrefs.encodeValue(
Preferences.Enumerations.encodeValue(
DESIRED_OVERLAY, listType
)
onLayoutChanged(listType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.bobbyesp.metadator.presentation.pages.utilities.tageditor

import android.app.Activity
import android.net.Uri
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.PickVisualMediaRequest
Expand Down Expand Up @@ -145,6 +146,17 @@ fun ID3MetadataEditorPage(
})


BackHandler {
if (scaffoldState.bottomSheetState.isVisible) {
scope.launch {
scaffoldState.bottomSheetState.hide()
}
} else {
navController.popBackStack()
}
}


BottomSheetScaffold(topBar = {
TopAppBar(title = {
Column(modifier = Modifier.fillMaxWidth()) {
Expand Down Expand Up @@ -182,7 +194,7 @@ fun ID3MetadataEditorPage(
},
modifier = Modifier.fillMaxSize(),
scaffoldState = scaffoldState,
sheetPeekHeight = 128.dp,
sheetPeekHeight = 148.dp,
sheetShadowElevation = 8.dp,
sheetContent = {
SpMetadataBottomSheetContent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.bobbyesp.metadator.presentation.pages.utilities.tageditor.spotify

import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
Expand All @@ -12,6 +10,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
Expand All @@ -22,14 +21,15 @@ import com.bobbyesp.ui.motion.MotionConstants.DURATION_EXIT_SHORT
import com.bobbyesp.ui.motion.tweenEnter
import com.bobbyesp.ui.motion.tweenExit

@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SpMetadataBottomSheetContent(
name: String,
artist: String,
state: SheetState,
viewModel: SpMetadataBottomSheetContentViewModel = hiltViewModel()
) {
val scope = rememberCoroutineScope()
val viewState = viewModel.viewStateFlow.collectAsStateWithLifecycle().value

val bottomSheetState = viewState.stage
Expand All @@ -39,40 +39,34 @@ fun SpMetadataBottomSheetContent(
if (name.isEmpty() && artist.isEmpty()) return

LaunchedEffect(state.isVisible, name, artist) {
if (state.isVisible) {
val query = "$name $artist"
if (state.isVisible && viewState.lastQuery != query) {
viewModel.updateStage(BottomSheetStage.SEARCH)
viewModel.searchTracks("$name $artist")
viewModel.searchTracks(query)
}
}

SharedTransitionLayout {
AnimatedContent(
targetState = bottomSheetState,
label = "Transition between bs states",
transitionSpec = {
fadeIn(
tweenEnter(delayMillis = DURATION_EXIT_SHORT)
) togetherWith fadeOut(
tweenExit(durationMillis = DURATION_EXIT_SHORT)
AnimatedContent(targetState = bottomSheetState,
label = "Transition between bs states",
transitionSpec = {
fadeIn(
tweenEnter(delayMillis = DURATION_EXIT_SHORT)
) togetherWith fadeOut(
tweenExit(durationMillis = DURATION_EXIT_SHORT)
)
}) { actualStage ->
when (actualStage) {
BottomSheetStage.SEARCH -> {
SpMetadataBsSearch(
name = name, artist = artist, listState = lazyListState, viewModel = viewModel
)
}) { actualStage ->
when (actualStage) {
BottomSheetStage.SEARCH -> {
SpMetadataBsSearch(
name = name,
artist = artist,
listState = lazyListState,
viewModel = viewModel
)
}
}

BottomSheetStage.TRACK_DETAILS -> {
SpMetadataBsDetails(
modifier = Modifier.fillMaxSize(),
viewModel = viewModel
)
}
BottomSheetStage.TRACK_DETAILS -> {
SpMetadataBsDetails(
modifier = Modifier.fillMaxSize(), viewModel = viewModel
)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import com.bobbyesp.metadator.features.spotify.domain.pagination.TracksPagingSou
import com.bobbyesp.metadator.features.spotify.domain.services.SpotifyService
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -33,25 +32,21 @@ class SpMetadataBottomSheetContentViewModel @Inject constructor(
}
}

private var searchJob: Job? = null

private val mutableViewStateFlow = MutableStateFlow(ViewState())
val viewStateFlow = mutableViewStateFlow.asStateFlow()

data class ViewState(
val stage: BottomSheetStage = BottomSheetStage.SEARCH,
val viewState: SearchStageViewState = SearchStageViewState.Idle,
val searchedTracks: Flow<PagingData<Track>> = emptyFlow(),
val selectedTrack: Track? = null
val selectedTrack: Track? = null,
val lastQuery: String = "",
)

fun searchTracks(query: String) {
searchJob?.cancel()
updateViewState(SearchStageViewState.Loading)
searchJob = viewModelScope.launch(Dispatchers.IO) {
updateQuery(query)
viewModelScope.launch(Dispatchers.IO) {
getTracksPaginatedData(query)
}
updateViewState(SearchStageViewState.Success)
}

private fun getTracksPaginatedData(query: String) {
Expand Down Expand Up @@ -86,12 +81,12 @@ class SpMetadataBottomSheetContentViewModel @Inject constructor(
}

fun clearTrack() {
updateStage(BottomSheetStage.SEARCH)
mutableViewStateFlow.update {
it.copy(
selectedTrack = null
)
}
updateStage(BottomSheetStage.SEARCH)
}

fun updateStage(stage: BottomSheetStage) {
Expand All @@ -102,23 +97,15 @@ class SpMetadataBottomSheetContentViewModel @Inject constructor(
}
}

private fun updateViewState(viewState: SearchStageViewState) {
fun updateQuery(query: String) {
mutableViewStateFlow.update {
it.copy(
viewState = viewState
lastQuery = query
)
}
}

companion object {
sealed class SearchStageViewState {
data object Idle : SearchStageViewState() // Initial state - May be deleted
data object Loading : SearchStageViewState()
data object Success : SearchStageViewState()
data class Error(val error: String) : SearchStageViewState()
}


enum class BottomSheetStage {
SEARCH,
TRACK_DETAILS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package com.bobbyesp.metadator.presentation.pages.utilities.tageditor.spotify.stages

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -23,15 +19,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.adamratzman.spotify.models.Track
import com.bobbyesp.metadator.presentation.components.cards.songs.spotify.SpotifyHorizontalSongCard
import com.bobbyesp.metadator.presentation.pages.utilities.tageditor.spotify.SpMetadataBottomSheetContentViewModel
import com.bobbyesp.metadator.presentation.utils.SongCardBoundsTransformation
import com.bobbyesp.ui.motion.MotionConstants.DURATION_EXIT_SHORT
import com.bobbyesp.ui.motion.tweenEnter
import com.bobbyesp.ui.motion.tweenExit

context(SharedTransitionScope)
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun AnimatedVisibilityScope.SpMetadataBsDetails(
fun SpMetadataBsDetails(
modifier: Modifier = Modifier,
viewModel: SpMetadataBottomSheetContentViewModel
) {
Expand All @@ -50,34 +41,11 @@ fun AnimatedVisibilityScope.SpMetadataBsDetails(
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
LaunchedEffect(true) {
LaunchedEffect(viewState.selectedTrack) {
selectedTrack = viewState.selectedTrack
}
selectedTrack?.let {
SpotifyHorizontalSongCard(
modifier = Modifier
.sharedBounds(
sharedContentState = rememberSharedContentState(
key = "container_${it.id}"
),
animatedVisibilityScope = this@SpMetadataBsDetails,
placeHolderSize = SharedTransitionScope.PlaceHolderSize.animatedSize,
boundsTransform = SongCardBoundsTransformation,
enter = fadeIn(
tweenEnter(delayMillis = DURATION_EXIT_SHORT)
),
exit = fadeOut(
tweenExit(durationMillis = DURATION_EXIT_SHORT)
)
),
imageModifier = Modifier.sharedElement(
state = rememberSharedContentState(
key = it.id
),
animatedVisibilityScope = this@SpMetadataBsDetails,
placeHolderSize = SharedTransitionScope.PlaceHolderSize.animatedSize,
boundsTransform = SongCardBoundsTransformation,
),
innerModifier = Modifier.padding(8.dp),
surfaceColor = Color.Transparent,
track = it,
Expand Down
Loading

0 comments on commit f2d02c9

Please sign in to comment.