diff --git a/data/src/main/kotlin/com/theapache64/stackzy/data/remote/ApiInterface.kt b/data/src/main/kotlin/com/theapache64/stackzy/data/remote/ApiInterface.kt index 8822343..123a0f4 100644 --- a/data/src/main/kotlin/com/theapache64/stackzy/data/remote/ApiInterface.kt +++ b/data/src/main/kotlin/com/theapache64/stackzy/data/remote/ApiInterface.kt @@ -60,4 +60,8 @@ interface ApiInterface { @Query("except_v_code") exceptVersionCode : Int ): Flow> + @Read("SELECT *") + @GET(NetworkModule.TABLE_FUN_FACTS) + fun getFunFacts() : Flow>> + } \ No newline at end of file diff --git a/data/src/main/kotlin/com/theapache64/stackzy/data/remote/FunFact.kt b/data/src/main/kotlin/com/theapache64/stackzy/data/remote/FunFact.kt new file mode 100644 index 0000000..ee17d95 --- /dev/null +++ b/data/src/main/kotlin/com/theapache64/stackzy/data/remote/FunFact.kt @@ -0,0 +1,12 @@ +package com.theapache64.stackzy.data.remote +import com.squareup.moshi.JsonClass + +import com.squareup.moshi.Json + +@JsonClass(generateAdapter = true) +data class FunFact( + @Json(name = "id") + val id: Int, // 1 + @Json(name = "fun_fact") + val funFact: String // lorem ipsum +) \ No newline at end of file diff --git a/data/src/main/kotlin/com/theapache64/stackzy/data/repo/FunFactsRepo.kt b/data/src/main/kotlin/com/theapache64/stackzy/data/repo/FunFactsRepo.kt new file mode 100644 index 0000000..539a9d5 --- /dev/null +++ b/data/src/main/kotlin/com/theapache64/stackzy/data/repo/FunFactsRepo.kt @@ -0,0 +1,38 @@ +package com.theapache64.stackzy.data.repo + +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import com.theapache64.stackzy.data.remote.ApiInterface +import com.theapache64.stackzy.data.remote.FunFact +import java.util.prefs.Preferences +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +open class FunFactsRepo @Inject constructor( + private val apiInterface: ApiInterface, + private val moshi: Moshi, + private val pref: Preferences +) { + companion object { + private const val KEY_FUN_FACTS = "FunFacts" + } + + private val funFactsJsonAdapter by lazy { + val listMyData = Types.newParameterizedType(List::class.java, FunFact::class.java) + moshi.adapter>(listMyData) + } + + fun getRemoteFunFacts() = + apiInterface.getFunFacts() + + fun getLocalFunFacts(): Set? { + val funFactsJson = pref.get(KEY_FUN_FACTS, null) + return funFactsJsonAdapter.fromJson(funFactsJson)?.toSet() + } + + fun saveFunFactsToLocal(data: List) { + pref.put(KEY_FUN_FACTS, funFactsJsonAdapter.toJson(data)) + } + +} diff --git a/data/src/main/kotlin/com/theapache64/stackzy/di/module/NetworkModule.kt b/data/src/main/kotlin/com/theapache64/stackzy/di/module/NetworkModule.kt index 1e03144..e3dd0dd 100644 --- a/data/src/main/kotlin/com/theapache64/stackzy/di/module/NetworkModule.kt +++ b/data/src/main/kotlin/com/theapache64/stackzy/di/module/NetworkModule.kt @@ -23,6 +23,7 @@ class NetworkModule { const val TABLE_UNTRACKED_LIBS = "untracked_libs" const val TABLE_RESULTS = "results" const val TABLE_CONFIG = "config" + const val TABLE_FUN_FACTS = "fun_facts" } @Singleton @@ -34,6 +35,10 @@ class NetworkModule { sheetName = TABLE_CATEGORIES, "id", "name" ) + .addSheet( + sheetName = TABLE_FUN_FACTS, + "id", "fun_fact" + ) .addSheet( sheetName = TABLE_LIBRARIES, "id", "name", "package_name", "category", "website" diff --git a/src/main/kotlin/com/theapache64/stackzy/ui/common/CenterBox.kt b/src/main/kotlin/com/theapache64/stackzy/ui/common/CenterBox.kt new file mode 100644 index 0000000..5a2f35d --- /dev/null +++ b/src/main/kotlin/com/theapache64/stackzy/ui/common/CenterBox.kt @@ -0,0 +1,23 @@ +package com.theapache64.stackzy.ui.common + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +/** + * Only used for debugging/preview purpose + */ +@Composable +fun CenterBox( + content: @Composable BoxScope.() -> Unit +) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + content() + } +} diff --git a/src/main/kotlin/com/theapache64/stackzy/ui/common/LoadingAnimation.kt b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/LoadingAnimation.kt similarity index 71% rename from src/main/kotlin/com/theapache64/stackzy/ui/common/LoadingAnimation.kt rename to src/main/kotlin/com/theapache64/stackzy/ui/common/loading/LoadingAnimation.kt index 4ba6a4a..6f926a6 100644 --- a/src/main/kotlin/com/theapache64/stackzy/ui/common/LoadingAnimation.kt +++ b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/LoadingAnimation.kt @@ -4,9 +4,11 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -14,6 +16,7 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import com.theapache64.stackzy.data.repo.ConfigRepo /** * To show a rotating icon at the center and blinking text at the bottom of the screen @@ -41,15 +44,20 @@ fun LoadingAnimation(message: String) { Box( modifier = Modifier.fillMaxSize() ) { - Image( - modifier = Modifier - .rotate(animatedRotation) - .align(Alignment.Center) - .size(50.dp), - colorFilter = ColorFilter.tint(MaterialTheme.colors.primary), - painter = painterResource("drawables/loading.png"), - contentDescription = "" - ) + Column( + modifier = Modifier.align(Alignment.Center) + ) { + Image( + modifier = Modifier + .rotate(animatedRotation) + .size(50.dp), + colorFilter = ColorFilter.tint(MaterialTheme.colors.primary), + painter = painterResource("drawables/loading.png"), + contentDescription = "" + ) + + + } LoadingText( modifier = Modifier.align(Alignment.BottomCenter), diff --git a/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFact.kt b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFact.kt new file mode 100644 index 0000000..25e2553 --- /dev/null +++ b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFact.kt @@ -0,0 +1,39 @@ +package com.theapache64.stackzy.ui.common.loading.funfact + +import androidx.compose.foundation.clickable +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.window.singleWindowApplication +import com.theapache64.stackzy.data.remote.FunFact +import com.theapache64.stackzy.ui.common.CenterBox +import com.theapache64.stackzy.util.PureRandom + + +@Composable +fun FunFact(funFacts: Set) { + val pureRandom = remember { PureRandom(funFacts) } + var currentFunFact by remember { mutableStateOf(pureRandom.get()) } + + Text( + text = currentFunFact.funFact, + modifier = Modifier.clickable { + currentFunFact = pureRandom.get() + } + ) +} + + +fun main(args: Array) = singleWindowApplication { + CenterBox { + FunFact( + setOf( + FunFact(id = 1, "A"), + FunFact(id = 2, "B"), + FunFact(id = 3, "C"), + FunFact(id = 4, "D"), + FunFact(id = 5, "E"), + ) + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFactViewModel.kt b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFactViewModel.kt new file mode 100644 index 0000000..73f998a --- /dev/null +++ b/src/main/kotlin/com/theapache64/stackzy/ui/common/loading/funfact/FunFactViewModel.kt @@ -0,0 +1,4 @@ +package com.theapache64.stackzy.ui.common.loading.funfact + +class FunFactViewModel { +} \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/stackzy/ui/feature/splash/SplashViewModel.kt b/src/main/kotlin/com/theapache64/stackzy/ui/feature/splash/SplashViewModel.kt index 56b07cf..4b34e43 100644 --- a/src/main/kotlin/com/theapache64/stackzy/ui/feature/splash/SplashViewModel.kt +++ b/src/main/kotlin/com/theapache64/stackzy/ui/feature/splash/SplashViewModel.kt @@ -4,6 +4,7 @@ import com.theapache64.stackzy.App import com.theapache64.stackzy.data.remote.Config import com.theapache64.stackzy.data.repo.AdbRepo import com.theapache64.stackzy.data.repo.ConfigRepo +import com.theapache64.stackzy.data.repo.FunFactsRepo import com.theapache64.stackzy.data.repo.LibrariesRepo import com.theapache64.stackzy.data.util.calladapter.flow.Resource import com.toxicbakery.logging.Arbor @@ -21,7 +22,8 @@ import javax.inject.Inject class SplashViewModel @Inject constructor( private val librariesRepo: LibrariesRepo, private val adbRepo: AdbRepo, - private val configRepo: ConfigRepo + private val configRepo: ConfigRepo, + private val funFactsRepo: FunFactsRepo ) { private lateinit var viewModelScope: CoroutineScope @@ -47,9 +49,11 @@ class SplashViewModel @Inject constructor( try { syncAndCacheLibraries { // first cache libs syncAndStoreConfig { // then sync config - checkAndFixAdb { // then check adb - checkJdk { - _isSyncFinished.value = true // all done + syncAndStoreFunFacts { + checkAndFixAdb { // then check adb + checkJdk { + _isSyncFinished.value = true // all done + } } } } @@ -70,6 +74,25 @@ class SplashViewModel @Inject constructor( } } + private suspend fun syncAndStoreFunFacts( + onSynced: suspend () -> Unit + ) { + funFactsRepo.getRemoteFunFacts().collect { resource -> + when (resource) { + is Resource.Loading -> { + _syncMsg.value = "Getting some fun facts for you..." + } + is Resource.Success -> { + val funFacts = resource.data + funFactsRepo.saveFunFactsToLocal(funFacts) + onSynced() + } + is Resource.Error -> { + _syncFailedMsg.value = resource.errorData + } + } + } + } private suspend fun syncAndCacheLibraries( onSuccess: suspend () -> Unit diff --git a/src/main/kotlin/com/theapache64/stackzy/util/ColorUtil.kt b/src/main/kotlin/com/theapache64/stackzy/util/ColorUtil.kt index 6ae783c..c948642 100644 --- a/src/main/kotlin/com/theapache64/stackzy/util/ColorUtil.kt +++ b/src/main/kotlin/com/theapache64/stackzy/util/ColorUtil.kt @@ -115,7 +115,7 @@ object ColorUtil { private val pureRandom = PureRandom(colorSet) fun getRandomColor(): Color { - return pureRandom.take() + return pureRandom.get() } } \ No newline at end of file diff --git a/src/main/kotlin/com/theapache64/stackzy/util/PureRandom.kt b/src/main/kotlin/com/theapache64/stackzy/util/PureRandom.kt index 8819ed8..a197342 100644 --- a/src/main/kotlin/com/theapache64/stackzy/util/PureRandom.kt +++ b/src/main/kotlin/com/theapache64/stackzy/util/PureRandom.kt @@ -8,7 +8,7 @@ class PureRandom( ) { private val takenItems = mutableSetOf() - fun take(): T { + fun get(): T { if (takenItems.size >= items.size) { // all items taken so clear the list @@ -18,7 +18,7 @@ class PureRandom( val takenItem = items.random() if (takenItems.contains(takenItem)) { // already taken - return take() + return get() } takenItems.add(takenItem) return takenItem