Add installation id for feature flags (#3052)
# Conflicts: # app/build.gradle.kts # app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt # app/src/main/java/mihon/core/migration/migrations/Migrations.kt
This commit is contained in:
@@ -31,7 +31,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "eu.kanade.tachiyomi.sy"
|
applicationId = "eu.kanade.tachiyomi.sy"
|
||||||
|
|
||||||
versionCode = 76
|
versionCode = 77
|
||||||
versionName = "1.12.0"
|
versionName = "1.12.0"
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
|
|||||||
@@ -35,4 +35,6 @@ class BasePreferences(
|
|||||||
fun hardwareBitmapThreshold() = preferenceStore.getInt("pref_hardware_bitmap_threshold", GLUtil.SAFE_TEXTURE_LIMIT)
|
fun hardwareBitmapThreshold() = preferenceStore.getInt("pref_hardware_bitmap_threshold", GLUtil.SAFE_TEXTURE_LIMIT)
|
||||||
|
|
||||||
fun alwaysDecodeLongStripWithSSIV() = preferenceStore.getBoolean("pref_always_decode_long_strip_with_ssiv", false)
|
fun alwaysDecodeLongStripWithSSIV() = preferenceStore.getBoolean("pref_always_decode_long_strip_with_ssiv", false)
|
||||||
|
|
||||||
|
fun installationId() = preferenceStore.getString(Preference.appStateKey("installation_id"), "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ sealed class Preference {
|
|||||||
override val title: String,
|
override val title: String,
|
||||||
override val subtitle: CharSequence? = null,
|
override val subtitle: CharSequence? = null,
|
||||||
override val enabled: Boolean = true,
|
override val enabled: Boolean = true,
|
||||||
|
val widget: @Composable (() -> Unit)? = null,
|
||||||
val onClick: (() -> Unit)? = null,
|
val onClick: (() -> Unit)? = null,
|
||||||
) : PreferenceItem<String, Unit>() {
|
) : PreferenceItem<String, Unit>() {
|
||||||
override val icon: ImageVector? = null
|
override val icon: ImageVector? = null
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ internal fun PreferenceItem(
|
|||||||
title = item.title,
|
title = item.title,
|
||||||
subtitle = item.subtitle,
|
subtitle = item.subtitle,
|
||||||
icon = item.icon,
|
icon = item.icon,
|
||||||
|
widget = item.widget,
|
||||||
onPreferenceClick = item.onClick,
|
onPreferenceClick = item.onClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+42
@@ -1,24 +1,38 @@
|
|||||||
package eu.kanade.presentation.more.settings.screen.debug
|
package eu.kanade.presentation.more.settings.screen.debug
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Autorenew
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.profileinstaller.ProfileVerifier
|
import androidx.profileinstaller.ProfileVerifier
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.presentation.more.settings.Preference
|
import eu.kanade.presentation.more.settings.Preference
|
||||||
import eu.kanade.presentation.more.settings.PreferenceScaffold
|
import eu.kanade.presentation.more.settings.PreferenceScaffold
|
||||||
import eu.kanade.presentation.more.settings.screen.about.AboutScreen
|
import eu.kanade.presentation.more.settings.screen.about.AboutScreen
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import kotlinx.collections.immutable.mutate
|
import kotlinx.collections.immutable.mutate
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.guava.await
|
import kotlinx.coroutines.guava.await
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import mihon.core.common.FeatureFlags
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
|
import tachiyomi.presentation.core.util.collectAsState
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class DebugInfoScreen : Screen() {
|
class DebugInfoScreen : Screen() {
|
||||||
|
|
||||||
@@ -47,6 +61,12 @@ class DebugInfoScreen : Screen() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getAppInfoGroup(): Preference.PreferenceGroup {
|
private fun getAppInfoGroup(): Preference.PreferenceGroup {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val installationIdPref = remember { Injekt.get<BasePreferences>().installationId() }
|
||||||
|
val installationId by installationIdPref.collectAsState()
|
||||||
|
|
||||||
return Preference.PreferenceGroup(
|
return Preference.PreferenceGroup(
|
||||||
title = "App info",
|
title = "App info",
|
||||||
preferenceItems = persistentListOf(
|
preferenceItems = persistentListOf(
|
||||||
@@ -58,6 +78,28 @@ class DebugInfoScreen : Screen() {
|
|||||||
title = "Build time",
|
title = "Build time",
|
||||||
subtitle = AboutScreen.getFormattedBuildTime(),
|
subtitle = AboutScreen.getFormattedBuildTime(),
|
||||||
),
|
),
|
||||||
|
Preference.PreferenceItem.TextPreference(
|
||||||
|
title = "Installation ID",
|
||||||
|
subtitle = installationId,
|
||||||
|
widget = {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
installationIdPref.set(FeatureFlags.newInstallationId())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Autorenew,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
context.copyToClipboard(installationId, installationId)
|
||||||
|
},
|
||||||
|
),
|
||||||
getProfileVerifierPreference(),
|
getProfileVerifierPreference(),
|
||||||
Preference.PreferenceItem.TextPreference(
|
Preference.PreferenceItem.TextPreference(
|
||||||
title = "WebView version",
|
title = "WebView version",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.util
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
@@ -20,6 +21,7 @@ import java.time.ZoneId
|
|||||||
class CrashLogUtil(
|
class CrashLogUtil(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||||
|
private val preferences: BasePreferences = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun dumpLogs(exception: Throwable? = null) = withNonCancellableContext {
|
suspend fun dumpLogs(exception: Throwable? = null) = withNonCancellableContext {
|
||||||
@@ -44,6 +46,7 @@ class CrashLogUtil(
|
|||||||
App ID: ${BuildConfig.APPLICATION_ID}
|
App ID: ${BuildConfig.APPLICATION_ID}
|
||||||
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME})
|
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME})
|
||||||
Preview build: $syDebugVersion
|
Preview build: $syDebugVersion
|
||||||
|
Installation ID: ${preferences.installationId().get()}
|
||||||
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}; build ${Build.DISPLAY})
|
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}; build ${Build.DISPLAY})
|
||||||
Device brand: ${Build.BRAND}
|
Device brand: ${Build.BRAND}
|
||||||
Device manufacturer: ${Build.MANUFACTURER}
|
Device manufacturer: ${Build.MANUFACTURER}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package mihon.core.migration.migrations
|
||||||
|
|
||||||
|
import eu.kanade.domain.base.BasePreferences
|
||||||
|
import mihon.core.common.FeatureFlags
|
||||||
|
import mihon.core.migration.Migration
|
||||||
|
import mihon.core.migration.MigrationContext
|
||||||
|
import kotlin.uuid.ExperimentalUuidApi
|
||||||
|
|
||||||
|
class InstallationIdMigration : Migration {
|
||||||
|
override val version: Float = Migration.ALWAYS
|
||||||
|
|
||||||
|
@OptIn(ExperimentalUuidApi::class)
|
||||||
|
override suspend fun invoke(migrationContext: MigrationContext): Boolean {
|
||||||
|
val installationId = migrationContext.get<BasePreferences>()?.installationId() ?: return false
|
||||||
|
if (!installationId.isSet()) installationId.set(FeatureFlags.newInstallationId())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,4 +47,5 @@ val migrations: List<Migration>
|
|||||||
TrustExtensionRepositoryMigration(),
|
TrustExtensionRepositoryMigration(),
|
||||||
CategoryPreferencesCleanupMigration(),
|
CategoryPreferencesCleanupMigration(),
|
||||||
RemoveDuplicateReaderPreferenceMigration(),
|
RemoveDuplicateReaderPreferenceMigration(),
|
||||||
|
InstallationIdMigration(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package mihon.core.common
|
||||||
|
|
||||||
|
import kotlin.uuid.ExperimentalUuidApi
|
||||||
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
object FeatureFlags {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalUuidApi::class)
|
||||||
|
fun newInstallationId(): String {
|
||||||
|
return Uuid.random().toHexDashString()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user