Skip to content

Commit

Permalink
change character state machine to repository
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed May 3, 2024
1 parent 6c56fdc commit d841a64
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 136 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dev.datlag.aniflow.anilist

import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.Optional
import dev.datlag.aniflow.anilist.model.Character
import kotlinx.coroutines.flow.*

class CharacterRepository(
private val client: ApolloClient,
private val fallbackClient: ApolloClient
) {

private val id = MutableStateFlow<Int?>(null)
private val query = id.filterNotNull().map {
Query(it)
}
private val fallbackQuery = query.transform {
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
State.fromGraphQL(data)
} else {
null
}
} else {
State.fromGraphQL(data)
}
}

val character = query.transform {
return@transform emitAll(client.query(it.toGraphQL()).toFlow())
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
State.fromGraphQL(data)
} else {
null
}
} else {
State.fromGraphQL(data)
}
}.transform {
return@transform if (it is Error) {
emitAll(fallbackQuery)
} else {
emit(it)
}
}

fun clear() = id.update { null }

fun load(id: Int) = this.id.update { id }

private data class Query(
val id: Int
) {
fun toGraphQL() = CharacterQuery(
id = Optional.present(id),
html = Optional.present(true)
)
}

sealed interface State {
data class Success(val character: Character) : State
data object Error : State

companion object {
fun fromGraphQL(query: CharacterQuery.Data?): State {
val char = query?.Character?.let { Character(it) }

if (char == null) {
return Error
}

return Success(char)
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,11 @@ data object NetworkModule {
nsfw = appSettings.adultContent
)
}
bindSingleton<CharacterRepository> {
CharacterRepository(
client = instance(Constants.AniList.APOLLO_CLIENT),
fallbackClient = instance(Constants.AniList.FALLBACK_APOLLO_CLIENT),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.datlag.aniflow.ui.navigation.screen.medium.dialog.character

import dev.datlag.aniflow.anilist.CharacterStateMachine
import dev.datlag.aniflow.anilist.CharacterRepository
import dev.datlag.aniflow.anilist.model.Character
import dev.datlag.aniflow.settings.model.CharLanguage
import dev.datlag.aniflow.ui.navigation.DialogComponent
Expand All @@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.StateFlow
interface CharacterComponent : DialogComponent {
val initialChar: Character

val state: StateFlow<CharacterStateMachine.State>
val state: Flow<CharacterRepository.State>
val charLanguage: Flow<CharLanguage?>

val image: Flow<Character.Image>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import coil3.compose.AsyncImage
import coil3.compose.rememberAsyncImagePainter
import dev.datlag.aniflow.LocalEdgeToEdge
import dev.datlag.aniflow.SharedRes
import dev.datlag.aniflow.anilist.CharacterStateMachine
import dev.datlag.aniflow.anilist.CharacterRepository
import dev.datlag.aniflow.common.*
import dev.datlag.aniflow.ui.navigation.screen.medium.component.TranslateButton
import dev.datlag.tooling.compose.ifFalse
Expand Down Expand Up @@ -60,7 +60,7 @@ fun CharacterDialog(component: CharacterComponent) {
contentAlignment = Alignment.Center
) {
val image by component.image.collectAsStateWithLifecycle(component.initialChar.image)
val state by component.state.collectAsStateWithLifecycle()
val state by component.state.collectAsStateWithLifecycle(null)

this@ModalBottomSheet.AnimatedVisibility(
modifier = Modifier.align(Alignment.CenterStart),
Expand Down Expand Up @@ -94,7 +94,7 @@ fun CharacterDialog(component: CharacterComponent) {
)

this@ModalBottomSheet.AnimatedVisibility(
visible = state.isLoading,
visible = state == null,
enter = fadeIn(),
exit = fadeOut()
) {
Expand All @@ -105,7 +105,7 @@ fun CharacterDialog(component: CharacterComponent) {

this@ModalBottomSheet.AnimatedVisibility(
modifier = Modifier.align(Alignment.CenterEnd),
visible = state.isSuccess,
visible = state is CharacterRepository.State.Success,
enter = fadeIn(),
exit = fadeOut()
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.Optional
import com.arkivanov.decompose.ComponentContext
import dev.datlag.aniflow.anilist.CharacterStateMachine
import dev.datlag.aniflow.anilist.CharacterRepository
import dev.datlag.aniflow.anilist.FavoriteToggleMutation
import dev.datlag.aniflow.anilist.model.Character
import dev.datlag.aniflow.common.nullableFirebaseInstance
Expand All @@ -29,26 +29,14 @@ class CharacterDialogComponent(
) : CharacterComponent, ComponentContext by componentContext {

private val aniListClient by di.instance<ApolloClient>(Constants.AniList.APOLLO_CLIENT)
private val aniListFallbackClient by di.instance<ApolloClient>(Constants.AniList.FALLBACK_APOLLO_CLIENT)
private val characterStateMachine = CharacterStateMachine(
client = aniListClient,
fallbackClient = aniListFallbackClient,
crashlytics = di.nullableFirebaseInstance()?.crashlytics,
id = initialChar.id
)
private val characterRepository by di.instance<CharacterRepository>()

private val appSettings by di.instance<Settings.PlatformAppSettings>()
override val charLanguage: Flow<CharLanguage?> = appSettings.charLanguage.flowOn(ioDispatcher())

override val state = characterStateMachine.state.flowOn(
context = ioDispatcher()
).stateIn(
scope = ioScope(),
started = SharingStarted.WhileSubscribed(),
initialValue = characterStateMachine.currentState
)
override val state = characterRepository.character
private val characterSuccessState = state.mapNotNull {
it.safeCast<CharacterStateMachine.State.Success>()
it.safeCast<CharacterRepository.State.Success>()
}

override val image: Flow<Character.Image> = characterSuccessState.map {
Expand Down Expand Up @@ -85,6 +73,10 @@ class CharacterDialogComponent(
it.character.isFavoriteBlocked
}

init {
characterRepository.load(initialChar.id)
}

@Composable
override fun render() {
onRender {
Expand All @@ -101,9 +93,7 @@ class CharacterDialogComponent(
}

override fun retry() {
launchIO {
characterStateMachine.dispatch(CharacterStateMachine.Action.Retry)
}

}

override fun toggleFavorite() {
Expand Down

0 comments on commit d841a64

Please sign in to comment.