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:
AntsyLich
2026-03-10 23:53:11 +06:00
committed by Jobobby04
parent 8b1fd30902
commit b7d6cc8dd0
9 changed files with 81 additions and 1 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ android {
defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy"
versionCode = 76
versionCode = 77
versionName = "1.12.0"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
@@ -35,4 +35,6 @@ class BasePreferences(
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 installationId() = preferenceStore.getString(Preference.appStateKey("installation_id"), "")
}
@@ -30,6 +30,7 @@ sealed class Preference {
override val title: String,
override val subtitle: CharSequence? = null,
override val enabled: Boolean = true,
val widget: @Composable (() -> Unit)? = null,
val onClick: (() -> Unit)? = null,
) : PreferenceItem<String, Unit>() {
override val icon: ImageVector? = null
@@ -147,6 +147,7 @@ internal fun PreferenceItem(
title = item.title,
subtitle = item.subtitle,
icon = item.icon,
widget = item.widget,
onPreferenceClick = item.onClick,
)
}
@@ -1,24 +1,38 @@
package eu.kanade.presentation.more.settings.screen.debug
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.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.profileinstaller.ProfileVerifier
import cafe.adriel.voyager.navigator.LocalNavigator
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.PreferenceScaffold
import eu.kanade.presentation.more.settings.screen.about.AboutScreen
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.WebViewUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.collections.immutable.mutate
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch
import mihon.core.common.FeatureFlags
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class DebugInfoScreen : Screen() {
@@ -47,6 +61,12 @@ class DebugInfoScreen : Screen() {
@Composable
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(
title = "App info",
preferenceItems = persistentListOf(
@@ -58,6 +78,28 @@ class DebugInfoScreen : Screen() {
title = "Build time",
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(),
Preference.PreferenceItem.TextPreference(
title = "WebView version",
@@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.util
import android.content.Context
import android.os.Build
import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.util.storage.getUriCompat
@@ -20,6 +21,7 @@ import java.time.ZoneId
class CrashLogUtil(
private val context: Context,
private val extensionManager: ExtensionManager = Injekt.get(),
private val preferences: BasePreferences = Injekt.get(),
) {
suspend fun dumpLogs(exception: Throwable? = null) = withNonCancellableContext {
@@ -44,6 +46,7 @@ class CrashLogUtil(
App ID: ${BuildConfig.APPLICATION_ID}
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME})
Preview build: $syDebugVersion
Installation ID: ${preferences.installationId().get()}
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}; build ${Build.DISPLAY})
Device brand: ${Build.BRAND}
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(),
CategoryPreferencesCleanupMigration(),
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()
}
}