From b151a801a8394765eea6a3da4b04b5267023a7f9 Mon Sep 17 00:00:00 2001 From: jacobrein Date: Mon, 9 Dec 2024 07:43:43 -0700 Subject: [PATCH] - Refactor: Update AppUpdate and Dependencies This commit refactors the `AppUpdate` object to use Ktor for network requests and Kotlin Serialization for JSON parsing. - Updates dependencies to the latest versions. - Replaces `getJsonApi` with a Ktor-based implementation in `AppUpdate`. - Renames data class properties in `AppUpdates` to follow Kotlin coding conventions (e.g., `update_real_version` to `updateRealVersion`). - Updates usages of `AppUpdates` properties throughout the project to reflect the new naming. - Updates build files to include Ktor and Kotlin Serialization dependencies. - Updates `apkString` to use the new property names. - Refactors update checks to use the new `AppUpdates` properties. - Updates `SettingsActivity` to use the new `AppUpdates` properties. - Refactors `GenericAnime`, `GenericManga`, and `GenericNovel` to use the new `AppUpdates` properties. - Updates `BaseMainActivity` to use the new `AppUpdates` properties. - Refactors `UpdateChecker` to use the new `AppUpdates` properties. - Refactors `NavGraph` to improve navigation transitions (TODO). - Refactors `MainFragment` to use the new `AppUpdates` properties and uses a different random source. - Refactors `InfoSettings` to use the new `AppUpdates` properties. --- .../uiviews/BaseMainActivity.kt | 2 +- .../com/programmersbox/uiviews/NavGraph.kt | 2 + .../uiviews/checkers/UpdateChecker.kt | 2 +- .../uiviews/settings/InfoSettings.kt | 6 +- .../programmersbox/animeworld/GenericAnime.kt | 2 +- .../animeworldtv/MainActivity.kt | 2 +- .../animeworldtv/MainFragment.kt | 2 +- .../animeworldtv/SettingsActivity.kt | 8 +-- gradle/libs.versions.toml | 8 +-- .../programmersbox/mangaworld/GenericManga.kt | 2 +- .../programmersbox/novelworld/GenericNovel.kt | 2 +- sharedutils/build.gradle.kts | 3 + .../programmersbox/sharedutils/AppUpdate.kt | 66 ++++++++++++++----- 13 files changed, 74 insertions(+), 33 deletions(-) diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/BaseMainActivity.kt b/UIViews/src/main/java/com/programmersbox/uiviews/BaseMainActivity.kt index ccc9bb005..3122904c4 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/BaseMainActivity.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/BaseMainActivity.kt @@ -727,7 +727,7 @@ abstract class BaseMainActivity : AppCompatActivity() { val appUpdate by updateAppCheck.collectAsState(null) return AppUpdate.checkForUpdate( appVersion(), - appUpdate?.update_real_version.orEmpty() + appUpdate?.updateRealVersion.orEmpty() ) } diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/NavGraph.kt b/UIViews/src/main/java/com/programmersbox/uiviews/NavGraph.kt index ec077590a..6bd850cc8 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/NavGraph.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/NavGraph.kt @@ -47,6 +47,8 @@ import com.programmersbox.uiviews.utils.Screen import com.programmersbox.uiviews.utils.chromeCustomTabs import com.programmersbox.uiviews.utils.sharedelements.animatedScopeComposable +//TODO: MAYBE give each screen an enum of where they are and the transitions are based off of that? + @OptIn( ExperimentalAnimationApi::class, ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class ) diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/checkers/UpdateChecker.kt b/UIViews/src/main/java/com/programmersbox/uiviews/checkers/UpdateChecker.kt index 9fd20a625..6ec1019b8 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/checkers/UpdateChecker.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/checkers/UpdateChecker.kt @@ -73,7 +73,7 @@ class AppCheckWorker( override suspend fun doWork(): Result { return try { - val f = withTimeoutOrNull(60000) { AppUpdate.getUpdate()?.update_real_version.orEmpty() } + val f = withTimeoutOrNull(60000) { AppUpdate.getUpdate()?.updateRealVersion.orEmpty() } logFirebaseMessage("Current Version: $f") val appVersion = applicationContext.appVersion if (f != null && AppUpdate.checkForUpdate(appVersion, f)) { diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/settings/InfoSettings.kt b/UIViews/src/main/java/com/programmersbox/uiviews/settings/InfoSettings.kt index 59e90fb82..3663cd486 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/settings/InfoSettings.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/settings/InfoSettings.kt @@ -121,14 +121,14 @@ fun InfoSettings( val downloadInstaller = remember { DownloadAndInstaller(context) } ShowWhen( - visibility = AppUpdate.checkForUpdate(appVersion(), appUpdate?.update_real_version.orEmpty()) + visibility = AppUpdate.checkForUpdate(appVersion(), appUpdate?.updateRealVersion.orEmpty()) ) { var showDialog by remember { mutableStateOf(false) } if (showDialog) { AlertDialog( onDismissRequest = { showDialog = false }, - title = { Text(stringResource(R.string.updateTo, appUpdate?.update_real_version.orEmpty())) }, + title = { Text(stringResource(R.string.updateTo, appUpdate?.updateRealVersion.orEmpty())) }, text = { Text(stringResource(R.string.please_update_for_latest_features)) }, confirmButton = { TextButton( @@ -171,7 +171,7 @@ fun InfoSettings( PreferenceSetting( settingTitle = { Text(stringResource(R.string.update_available)) }, - summaryValue = { Text(stringResource(R.string.updateTo, appUpdate?.update_real_version.orEmpty())) }, + summaryValue = { Text(stringResource(R.string.updateTo, appUpdate?.updateRealVersion.orEmpty())) }, modifier = Modifier.clickable( indication = ripple(), interactionSource = null diff --git a/animeworld/src/main/java/com/programmersbox/animeworld/GenericAnime.kt b/animeworld/src/main/java/com/programmersbox/animeworld/GenericAnime.kt index cbef9a141..b3026da19 100644 --- a/animeworld/src/main/java/com/programmersbox/animeworld/GenericAnime.kt +++ b/animeworld/src/main/java/com/programmersbox/animeworld/GenericAnime.kt @@ -129,7 +129,7 @@ class GenericAnime( val storageHolder: StorageHolder, ) : GenericInfo { - override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") anime_no_firebase_file else anime_file } + override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") animeNoFirebaseFile else animeFile } override val deepLinkUri: String get() = "animeworld://" override val sourceType: String get() = "anime" diff --git a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainActivity.kt b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainActivity.kt index 13669d05c..e4b804cfb 100644 --- a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainActivity.kt +++ b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainActivity.kt @@ -26,7 +26,7 @@ class MainActivity : FragmentActivity() { lifecycleScope.launch { if (currentService == null) { - val s = Sources.values().filterNot(Sources::notWorking).random() + val s = Sources.entries.filterNot(Sources::notWorking).random() //sourceFlow.emit(s) currentService = s.serviceName } else if (currentService != null) { diff --git a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainFragment.kt b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainFragment.kt index e5b018b32..671cde791 100644 --- a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainFragment.kt +++ b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/MainFragment.kt @@ -196,7 +196,7 @@ class MainFragment : BrowseSupportFragment() { .filterNotNull() .map { val appVersion = context?.packageManager?.getPackageInfo(requireContext().packageName, 0)?.versionName.orEmpty() - AppUpdate.checkForUpdate(appVersion, it.update_real_version.orEmpty()) + AppUpdate.checkForUpdate(appVersion, it.updateRealVersion.orEmpty()) } .onEach { if (it) gridRowAdapter.add(resources.getString(R.string.update_available)) diff --git a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/SettingsActivity.kt b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/SettingsActivity.kt index f0c04a385..f58467309 100644 --- a/animeworldtv/src/main/java/com/programmersbox/animeworldtv/SettingsActivity.kt +++ b/animeworldtv/src/main/java/com/programmersbox/animeworldtv/SettingsActivity.kt @@ -108,8 +108,8 @@ class SettingsFragment : LeanbackSettingsFragmentCompat(), DialogPreference.Targ .flowOn(Dispatchers.Main) .onEach { val appVersion = context?.packageManager?.getPackageInfo(requireContext().packageName, 0)?.versionName.orEmpty() - p.summary = if (AppUpdate.checkForUpdate(appVersion, it.update_real_version.orEmpty())) - getString(R.string.updateVersionAvailable, it.update_real_version.orEmpty()) + p.summary = if (AppUpdate.checkForUpdate(appVersion, it.updateRealVersion.orEmpty())) + getString(R.string.updateVersionAvailable, it.updateRealVersion.orEmpty()) else "" } .collect() @@ -136,9 +136,9 @@ class SettingsFragment : LeanbackSettingsFragmentCompat(), DialogPreference.Targ .filterNotNull() .flowOn(Dispatchers.Main) .onEach { - p.summary = getString(R.string.currentVersion, it.update_real_version.orEmpty()) + p.summary = getString(R.string.currentVersion, it.updateRealVersion.orEmpty()) val appVersion = context?.packageManager?.getPackageInfo(requireContext().packageName, 0)?.versionName.orEmpty() - p.isVisible = AppUpdate.checkForUpdate(appVersion, it.update_real_version.orEmpty()) + p.isVisible = AppUpdate.checkForUpdate(appVersion, it.updateRealVersion.orEmpty()) } .collect() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f6c4c3ddc..1b3644d42 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ biometricVersion = "1.4.0-alpha02" blurhash = "0.4.0-SNAPSHOT" generativeai = "0.9.0" -gradle = "8.7.2" +gradle = "8.7.3" kotlin = "2.1.0" kspVersion = "2.1.0-1.0.29" @@ -13,7 +13,7 @@ dragselect = "2.4.1" easylauncher = "6.4.0" firebaseCrashlyticsGradle = "3.0.2" googleServices = "4.4.2" -haze = "1.1.0" +haze = "1.1.1" kamelImage = "1.0.2" latestAboutLibsRelease = "11.2.3" coroutinesVersion = "1.9.0" @@ -32,7 +32,7 @@ jetpackCompiler = "1.5.11" jetbrainsCompiler = "1.5.1" accompanist = "0.36.0" okhttpVersion = "4.12.0" -ktorVersion = "3.0.1" +ktorVersion = "3.0.2" workVersion = "2.10.0" ziplineVersion = "1.1.0" landscapist = "2.4.4" @@ -306,7 +306,7 @@ androidxWebkit = "androidx.webkit:webkit:1.12.1" mlkitTranslate = "com.google.mlkit:translate:17.0.3" mlkitLanguage = "com.google.mlkit:language-id:17.0.6" -firebasePlatform = "com.google.firebase:firebase-bom:33.6.0" +firebasePlatform = "com.google.firebase:firebase-bom:33.7.0" firebaseDatabase = { group = "com.google.firebase", name = "firebase-database" } firebaseFirestore = { group = "com.google.firebase", name = "firebase-firestore" } firebaseAuth = { group = "com.google.firebase", name = "firebase-auth" } diff --git a/mangaworld/src/main/java/com/programmersbox/mangaworld/GenericManga.kt b/mangaworld/src/main/java/com/programmersbox/mangaworld/GenericManga.kt index 769104d82..e755374f6 100644 --- a/mangaworld/src/main/java/com/programmersbox/mangaworld/GenericManga.kt +++ b/mangaworld/src/main/java/com/programmersbox/mangaworld/GenericManga.kt @@ -110,7 +110,7 @@ class GenericManga( override val deepLinkUri: String get() = "mangaworld://" - override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") manga_no_firebase_file else manga_file } + override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") mangaNoFirebaseFile else mangaFile } override val scrollBuffer: Int = 4 override fun chapterOnClick( diff --git a/novelworld/src/main/java/com/programmersbox/novelworld/GenericNovel.kt b/novelworld/src/main/java/com/programmersbox/novelworld/GenericNovel.kt index 60e6961cc..edc194ef8 100644 --- a/novelworld/src/main/java/com/programmersbox/novelworld/GenericNovel.kt +++ b/novelworld/src/main/java/com/programmersbox/novelworld/GenericNovel.kt @@ -110,7 +110,7 @@ class GenericNovel(val context: Context) : GenericInfo { ) { } - override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") novel_no_firebase_file else novel_file } + override val apkString: AppUpdate.AppUpdates.() -> String? get() = { if (BuildConfig.FLAVOR == "noFirebase") novelNoFirebaseFile else novelFile } @Composable override fun ComposeShimmerItem() { diff --git a/sharedutils/build.gradle.kts b/sharedutils/build.gradle.kts index 917a95db6..b9c92d8e3 100644 --- a/sharedutils/build.gradle.kts +++ b/sharedutils/build.gradle.kts @@ -2,6 +2,7 @@ import plugins.ProductFlavorTypes plugins { id("otaku-library") + id("kotlinx-serialization") } android { @@ -47,6 +48,8 @@ dependencies { implementation(libs.coroutinesCore) implementation(libs.coroutinesAndroid) + implementation(libs.bundles.ktorLibs) + implementation(projects.models) implementation(projects.favoritesdatabase) implementation(platform(libs.koin.bom)) diff --git a/sharedutils/src/main/java/com/programmersbox/sharedutils/AppUpdate.kt b/sharedutils/src/main/java/com/programmersbox/sharedutils/AppUpdate.kt index a80c11de3..bc4cc3987 100644 --- a/sharedutils/src/main/java/com/programmersbox/sharedutils/AppUpdate.kt +++ b/sharedutils/src/main/java/com/programmersbox/sharedutils/AppUpdate.kt @@ -1,26 +1,61 @@ package com.programmersbox.sharedutils -import com.programmersbox.gsonutils.getJsonApi +import io.ktor.client.HttpClient +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.get +import io.ktor.client.statement.bodyAsText +import io.ktor.serialization.kotlinx.json.json import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json object AppUpdate { private const val url = "https://raw.githubusercontent.com/jakepurple13/OtakuWorld/master/update.json" - fun getUpdate() = getJsonApi(url) + + private val client = HttpClient { + install(ContentNegotiation) { + json() + } + } + + suspend fun getUpdate() = runCatching { + client.get(url) + .bodyAsText() + .let { Json.decodeFromString(it) } + } + .onSuccess { println(it) } + .onFailure { it.printStackTrace() } + .getOrNull() + + @Serializable data class AppUpdates( - val update_version: Double?, - val update_real_version: String?, - val update_url: String?, - val manga_file: String?, - val anime_file: String?, - val novel_file: String?, - val animetv_file: String?, - val otakumanager_file: String?, - val manga_no_firebase_file: String?, - val anime_no_firebase_file: String?, - val novel_no_firebase_file: String?, - val animetv_no_firebase_file: String?, + @SerialName("update_version") + val updateVersion: Double?, + @SerialName("update_real_version") + val updateRealVersion: String?, + @SerialName("update_url") + val updateUrl: String?, + @SerialName("manga_file") + val mangaFile: String?, + @SerialName("anime_file") + val animeFile: String?, + @SerialName("novel_file") + val novelFile: String?, + @SerialName("animetv_file") + val animetvFile: String?, + @SerialName("otakumanager_file") + val otakumanagerFile: String?, + @SerialName("manga_no_firebase_file") + val mangaNoFirebaseFile: String?, + @SerialName("anime_no_firebase_file") + val animeNoFirebaseFile: String?, + @SerialName("novel_no_firebase_file") + val novelNoFirebaseFile: String?, + @SerialName("animetv_no_firebase_file") + val animetvNoFirebaseFile: String?, ) { - fun downloadUrl(url: AppUpdates.() -> String?) = "$update_url${url()}" + fun downloadUrl(url: AppUpdates.() -> String?) = "$updateUrl${url()}" } private fun String.removeVariantSuffix() = removeSuffix("-noFirebase") @@ -42,6 +77,7 @@ object AppUpdate { major.second.toInt() == major.first.toInt() && minor.second.toInt() == minor.first.toInt() && patch.second.removeVariantSuffix().toInt() > patch.first.removeVariantSuffix().toInt() -> true + else -> false } } catch (e: Exception) {