Skip to content

Commit

Permalink
🎨 added SpotlightRepository to take care of loading and holding spotl…
Browse files Browse the repository at this point in the history
…ight data for the current session
  • Loading branch information
schachi5000 committed Sep 23, 2024
1 parent 918bf55 commit 863492d
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 141 deletions.
2 changes: 2 additions & 0 deletions shared/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import net.schacher.mcc.shared.repositories.AuthRepository
import net.schacher.mcc.shared.repositories.CardRepository
import net.schacher.mcc.shared.repositories.DeckRepository
import net.schacher.mcc.shared.repositories.PackRepository
import net.schacher.mcc.shared.repositories.SpotlightRepository
import net.schacher.mcc.shared.screens.app.AppScreen
import net.schacher.mcc.shared.screens.app.AppViewModel
import net.schacher.mcc.shared.screens.main.MainViewModel
Expand All @@ -38,6 +39,7 @@ val repositories = module {
singleOf(::CardRepository)
singleOf(::DeckRepository)
singleOf(::PackRepository)
singleOf(::SpotlightRepository)
}

val viewModels = module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package net.schacher.mcc.shared.repositories
import co.touchlab.kermit.Logger
import io.ktor.http.Url
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import net.schacher.mcc.shared.datasource.database.SettingsDao
import net.schacher.mcc.shared.time.Time
Expand All @@ -19,7 +18,7 @@ class AuthRepository(private val settingsDao: SettingsDao) {

private val _loginState = MutableStateFlow(this.loggedIn)

val loginState: StateFlow<Boolean> = _loginState.asStateFlow()
val loginState = _loginState.asStateFlow()

init {
this.restoreAccessToken()
Expand Down Expand Up @@ -102,7 +101,6 @@ class AuthRepository(private val settingsDao: SettingsDao) {
this.settingsDao.remove(EXPIRES_AT)
}


private fun storeAccessToken(accessToken: AccessToken) {
this.settingsDao.putString(ACCESS_TOKEN, accessToken.token)
this.settingsDao.putString(EXPIRES_AT, accessToken.expiresAt.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import kotlin.random.Random

class DeckRepository(
private val cardRepository: CardRepository,
private val spotlightRepository: SpotlightRepository,
private val deckDatabaseDao: DeckDatabaseDao,
private val marvelCDbDataSource: MarvelCDbDataSource,
private val authRepository: AuthRepository
Expand All @@ -41,6 +42,9 @@ class DeckRepository(
private val randomDeckNumber: Int
get() = Random.nextInt(Int.MAX_VALUE) * -1

fun getDeckById(deckId: Int): Deck? =
this.decks.value.find { it.id == deckId } ?: this.spotlightRepository.getDeckById(deckId)

suspend fun createDeck(heroCard: Card, label: String? = null, aspect: Aspect? = null) {
if (heroCard.type != HERO) {
throw Exception("Hero card must be of type HERO - $heroCard")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package net.schacher.mcc.shared.repositories

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.datetime.LocalDate
import net.schacher.mcc.shared.datasource.http.MarvelCDbDataSource
import net.schacher.mcc.shared.model.Deck

class SpotlightRepository(
private val cardRepository: CardRepository,
private val marvelCDbDataSource: MarvelCDbDataSource,
) {
private val _state = MutableStateFlow<Map<LocalDate, List<Deck>>>(emptyMap())

val state = _state.asStateFlow()

fun getDeckById(deckId: Int): Deck? =
this.state.value.values.flatten().find { it.id == deckId }

suspend fun getSpotlightDecks(localDate: LocalDate): List<Deck> {
val spotlight = this.marvelCDbDataSource.getSpotlightDecksByDate(localDate) {
this.cardRepository.getCard(it)
}.getOrNull()

if (spotlight != null) {
_state.update {
it.toMutableMap().apply {
put(localDate, spotlight)
}
}
}

return spotlight ?: emptyList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.schacher.mcc.shared.screens

enum class AppScreen(val route: String) {
Login(route = "login"),
Main(route = "main"),
Deck(route = "deck/{deckId}"),
Card(route = "card/{cardCode}"),
AddDeck(route = "add_deck")
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package net.schacher.mcc.shared.screens.app

import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import net.schacher.mcc.shared.design.compose.Animation
import net.schacher.mcc.shared.screens.AppScreen
import net.schacher.mcc.shared.screens.card.CardScreen
import net.schacher.mcc.shared.screens.deck.DeckScreen
import net.schacher.mcc.shared.screens.login.LoginScreen
import net.schacher.mcc.shared.screens.main.MainScreen
import org.koin.compose.koinInject
Expand All @@ -18,37 +27,102 @@ private const val LOG_OUT_MILLIS = 450
@Composable
fun AppScreen(
appViewModel: AppViewModel = koinInject(),
navController: NavHostController = rememberNavController(),
onLogInClicked: () -> Unit
) {
val loggedIn = appViewModel.state.collectAsState()

AnimatedContent(
targetState = loggedIn.value,
transitionSpec = {
if (targetState) {
slideInVertically(
tween(LOG_IN_MILLIS),
initialOffsetY = { fillHeight -> fillHeight }) togetherWith
slideOutVertically(tween(
LOG_IN_MILLIS
), targetOffsetY = { fillHeight -> -fillHeight })
} else {
slideInVertically(
tween(LOG_OUT_MILLIS),
initialOffsetY = { fillHeight -> -fillHeight }) togetherWith
slideOutVertically(
tween(LOG_OUT_MILLIS),
targetOffsetY = { fillHeight -> fillHeight })
// Get current back stack entry
val backStackEntry by navController.currentBackStackEntryAsState()

// Get the name of the current screen
// val currentScreen = AppScreen.valueOf(
// backStackEntry?.destination?.name ?: AppScreen.Login.name
// )

NavHost(
navController = navController,
startDestination = AppScreen.Login.route,
modifier = Modifier.fillMaxSize(),
popExitTransition = { Animation.fullscreenExit },
popEnterTransition = { Animation.fullscreenEnter },
exitTransition = { Animation.fullscreenExit },
enterTransition = { Animation.fullscreenEnter }
) {
composable(AppScreen.Login.route) {
LoginScreen(onLogInClicked = onLogInClicked, onContinueAsGuestClicked = {
navController.navigate(AppScreen.Main.route)
})
}
composable(AppScreen.Main.route) {
MainScreen(navController = navController)
}

composable(
route = AppScreen.Deck.route,
arguments = listOf(navArgument("deckId") {
type = NavType.IntType
})
) {
it.arguments?.getInt("deckId")?.let { deckId ->
DeckScreen(
deckId = deckId,
navController = navController,
onDeleteDeckClick = {})
}
}) {

if (it) {
MainScreen()
} else {
LoginScreen(
onLogInClicked = onLogInClicked,
onContinueAsGuestClicked = { appViewModel.onGuestLoginClicked() }
)
}
composable(
route = AppScreen.Card.route,
arguments = listOf(navArgument("cardCode") {
type = NavType.StringType
})
) {
it.arguments?.getString("cardCode")?.let { cardCode ->
CardScreen(cardCode = cardCode) {
navController.popBackStack()
}
}
}
}

if (loggedIn.value) {
navController.navigate(AppScreen.Main.route)
} else {
navController.popBackStack(AppScreen.Login.route, false)
}

// LoginScreen(
// onLogInClicked = onLogInClicked,
// onContinueAsGuestClicked = { appViewModel.onGuestLoginClicked() }
// )

// AnimatedContent(
// targetState = loggedIn.value,
// transitionSpec = {
// if (targetState) {
// slideInVertically(
// tween(LOG_IN_MILLIS),
// initialOffsetY = { fillHeight -> fillHeight }) togetherWith
// slideOutVertically(tween(
// LOG_IN_MILLIS
// ), targetOffsetY = { fillHeight -> -fillHeight })
// } else {
// slideInVertically(
// tween(LOG_OUT_MILLIS),
// initialOffsetY = { fillHeight -> -fillHeight }) togetherWith
// slideOutVertically(
// tween(LOG_OUT_MILLIS),
// targetOffsetY = { fillHeight -> fillHeight })
// }
// }) {
//
// if (it) {
// MainScreen()
// } else {
// LoginScreen(
// onLogInClicked = onLogInClicked,
// onContinueAsGuestClicked = { appViewModel.onGuestLoginClicked() }
// )
// }
// }
}
Loading

0 comments on commit 863492d

Please sign in to comment.