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 {
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
+42
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user