Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ class PackageEventReceiver() :
}
?: return

Logger.d { "PackageEventReceiver: ${intent.action} for $packageName" }
Logger.d { "PackageEventReceiver: ${intent?.action} for $packageName" }

try {
when (intent.action) {
when (intent?.action) {
Intent.ACTION_PACKAGE_ADDED,
Intent.ACTION_PACKAGE_REPLACED,
Intent.ACTION_MY_PACKAGE_REPLACED,
Expand All @@ -112,7 +112,7 @@ class PackageEventReceiver() :
}
}
} catch (e: Exception) {
Logger.e { "PackageEventReceiver: Failed to handle ${intent.action}: ${e.message}" }
Logger.e { "PackageEventReceiver: Failed to handle ${intent?.action}: ${e.message}" }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ interface InstalledAppDao {
@Query("SELECT * FROM installed_apps WHERE repoId = :repoId")
fun getAppByRepoIdAsFlow(repoId: Long): Flow<InstalledAppEntity?>

`@Query`("SELECT * FROM installed_apps WHERE repoId = :repoId ORDER BY installedAt DESC")
@Query("SELECT * FROM installed_apps WHERE repoId = :repoId ORDER BY installedAt DESC")
suspend fun getAppsByRepoId(repoId: Long): List<InstalledAppEntity>

`@Query`("SELECT * FROM installed_apps WHERE repoId = :repoId ORDER BY installedAt DESC")
@Query("SELECT * FROM installed_apps WHERE repoId = :repoId ORDER BY installedAt DESC")
fun getAppsByRepoIdAsFlow(repoId: Long): Flow<List<InstalledAppEntity>>

@Query("SELECT COUNT(*) FROM installed_apps WHERE isUpdateAvailable = 1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import zed.rainxch.core.domain.model.AppLanguages
Expand Down Expand Up @@ -148,15 +149,29 @@ class TweaksRepositoryImpl(
}
}

override fun getDiscoveryPlatform(): Flow<DiscoveryPlatform> =
override fun getDiscoveryPlatforms(): Flow<Set<DiscoveryPlatform>> =
preferences.data.map { prefs ->
val platform = prefs[DISCOVERY_PLATFORM_KEY]
DiscoveryPlatform.fromName(platform)
val stored = prefs[DISCOVERY_PLATFORMS_KEY]
if (stored != null) {
stored
.mapNotNull { name ->
DiscoveryPlatform.entries.find { it.name == name && it != DiscoveryPlatform.All }
}.toSet()
} else {
// Legacy single-platform key migration: map old `All` to empty set.
val legacy = prefs[DISCOVERY_PLATFORM_KEY]?.let { DiscoveryPlatform.fromName(it) }
if (legacy != null && legacy != DiscoveryPlatform.All) setOf(legacy) else emptySet()
}
}
Comment on lines +152 to 165
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Migration never graduates to the new key until the user explicitly saves

The legacy fallback branch (lines 160–163) reads DISCOVERY_PLATFORM_KEY on every emission but never back-fills DISCOVERY_PLATFORMS_KEY. For existing users whose old key is set, every cold-start read of getDiscoveryPlatforms() will continue hitting the legacy path indefinitely — until setDiscoveryPlatforms is explicitly called (e.g. when the user changes their platform selection).

Consider performing a one-shot write-through when migrating, so subsequent reads go straight to the new key:

💡 Proposed fix — write-through on first migration
 } else {
     // Legacy single-platform key migration: map old `All` to empty set.
     val legacy = prefs[DISCOVERY_PLATFORM_KEY]?.let { DiscoveryPlatform.fromName(it) }
-    if (legacy != null && legacy != DiscoveryPlatform.All) setOf(legacy) else emptySet()
+    val migrated = if (legacy != null && legacy != DiscoveryPlatform.All) setOf(legacy) else emptySet()
+    // Back-fill so future reads use the new key directly.
+    // Note: DataStore.data.map is read-only; perform the write in a side-channel
+    // or remove this comment if you intentionally prefer lazy migration.
+    migrated
 }

If you intentionally prefer the lazy approach, a short comment explaining that setDiscoveryPlatforms is always called before the legacy key matters in practice would be sufficient.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
override fun getDiscoveryPlatforms(): Flow<Set<DiscoveryPlatform>> =
preferences.data.map { prefs ->
val platform = prefs[DISCOVERY_PLATFORM_KEY]
DiscoveryPlatform.fromName(platform)
val stored = prefs[DISCOVERY_PLATFORMS_KEY]
if (stored != null) {
stored
.mapNotNull { name ->
DiscoveryPlatform.entries.find { it.name == name && it != DiscoveryPlatform.All }
}.toSet()
} else {
// Legacy single-platform key migration: map old `All` to empty set.
val legacy = prefs[DISCOVERY_PLATFORM_KEY]?.let { DiscoveryPlatform.fromName(it) }
if (legacy != null && legacy != DiscoveryPlatform.All) setOf(legacy) else emptySet()
}
}
override fun getDiscoveryPlatforms(): Flow<Set<DiscoveryPlatform>> =
preferences.data.map { prefs ->
val stored = prefs[DISCOVERY_PLATFORMS_KEY]
if (stored != null) {
stored
.mapNotNull { name ->
DiscoveryPlatform.entries.find { it.name == name && it != DiscoveryPlatform.All }
}.toSet()
} else {
// Legacy single-platform key migration: map old `All` to empty set.
val legacy = prefs[DISCOVERY_PLATFORM_KEY]?.let { DiscoveryPlatform.fromName(it) }
val migrated = if (legacy != null && legacy != DiscoveryPlatform.All) setOf(legacy) else emptySet()
// Back-fill so future reads use the new key directly.
// Note: DataStore.data.map is read-only; perform the write in a side-channel
// or remove this comment if you intentionally prefer lazy migration.
migrated
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/TweaksRepositoryImpl.kt`
around lines 152 - 165, The legacy-branch in getDiscoveryPlatforms() reads
DISCOVERY_PLATFORM_KEY but never writes DISCOVERY_PLATFORMS_KEY, so migration
never completes; modify the branch so that when stored == null and a legacy
non-All value is found, perform a one-shot write-through to backfill
DISCOVERY_PLATFORMS_KEY (using preferences.edit to set the new key to a set
containing the migrated platform) and then return that set; ensure the write
only happens when migrating (stored == null && legacy != All) to avoid loops and
leave the rest of the mapping behavior unchanged (references:
getDiscoveryPlatforms(), DISCOVERY_PLATFORMS_KEY, DISCOVERY_PLATFORM_KEY,
setDiscoveryPlatforms).


override suspend fun setDiscoveryPlatform(platform: DiscoveryPlatform) {
override suspend fun setDiscoveryPlatforms(platforms: Set<DiscoveryPlatform>) {
preferences.edit { prefs ->
prefs[DISCOVERY_PLATFORM_KEY] = platform.name
val sanitized =
platforms
.filter { it != DiscoveryPlatform.All }
.map { it.name }
.toSet()
prefs[DISCOVERY_PLATFORMS_KEY] = sanitized
}
}

Expand Down Expand Up @@ -272,6 +287,7 @@ class TweaksRepositoryImpl(
private val IS_DARK_THEME_KEY = booleanPreferencesKey("is_dark_theme")
private val FONT_KEY = stringPreferencesKey("font_theme")
private val DISCOVERY_PLATFORM_KEY = stringPreferencesKey("discovery_platform")
private val DISCOVERY_PLATFORMS_KEY = stringSetPreferencesKey("discovery_platforms")
private val AUTO_DETECT_CLIPBOARD_KEY = booleanPreferencesKey("auto_detect_clipboard_links")
private val INSTALLER_TYPE_KEY = stringPreferencesKey("installer_type")
private val AUTO_UPDATE_KEY = booleanPreferencesKey("auto_update_enabled")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ enum class DiscoveryPlatform {

companion object {
fun fromName(name: String?): DiscoveryPlatform = DiscoveryPlatform.entries.find { it.name == name } ?: All

val selectablePlatforms: List<DiscoveryPlatform> =
listOf(Android, Macos, Windows, Linux)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ interface TweaksRepository {

suspend fun setHideSeenEnabled(enabled: Boolean)

fun getDiscoveryPlatform(): Flow<DiscoveryPlatform>
fun getDiscoveryPlatforms(): Flow<Set<DiscoveryPlatform>>

suspend fun setDiscoveryPlatform(platform: DiscoveryPlatform)
suspend fun setDiscoveryPlatforms(platforms: Set<DiscoveryPlatform>)

fun getScrollbarEnabled(): Flow<Boolean>

Expand Down
Binary file added feature/home/.DS_Store
Binary file not shown.
Loading