From 545f8fd8108f04fa8cf01cafbef487789da37027 Mon Sep 17 00:00:00 2001 From: Hossain Khan Date: Sun, 8 Feb 2026 20:21:19 -0500 Subject: [PATCH] chore: address PR feedback on domain migration - Add distinctUntilChanged() to prevent duplicate emissions when DataStore write triggers re-collection (fixes Copilot review comment) - Improve runBlocking comment to explain why it's acceptable here: one-time migration, fast DataStore write, downstream deduplication - Rename test from 'no repeated saves' to 'idempotent across multiple reads' to accurately reflect what the test verifies (fixes Copilot review comment) Ref: https://github.com/usetrmnl/trmnl-android/pull/262 All 49 unit tests pass (0 failures, 0 errors) --- .../ink/trmnl/android/data/TrmnlDeviceConfigDataStore.kt | 9 ++++++--- .../trmnl/android/data/TrmnlDeviceConfigDataStoreTest.kt | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStore.kt b/app/src/main/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStore.kt index b2e83b7..1473a00 100644 --- a/app/src/main/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStore.kt +++ b/app/src/main/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStore.kt @@ -294,8 +294,11 @@ class TrmnlDeviceConfigDataStore "Migrating API base URL from ${config.apiBaseUrl} to $newUrl for TRMNL device", ) val migratedConfig = config.copy(apiBaseUrl = newUrl) - // Save the migrated config back to DataStore synchronously - // Using runBlocking is acceptable here as this is a one-time migration + // Persist the migrated config back to DataStore (one-time migration) + // Note: Using runBlocking here as Flow.map doesn't support suspend operations. + // This is acceptable because: (1) it's a one-time migration per user, + // (2) DataStore writes are fast, and (3) distinctUntilChanged() below + // prevents duplicate downstream emissions from the save triggering re-collection. runBlocking { saveDeviceConfig(migratedConfig) } @@ -303,7 +306,7 @@ class TrmnlDeviceConfigDataStore } else { config } - } + }.distinctUntilChanged() /** * Saves the complete device configuration diff --git a/app/src/test/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStoreTest.kt b/app/src/test/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStoreTest.kt index 4109234..6ffc349 100644 --- a/app/src/test/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStoreTest.kt +++ b/app/src/test/java/ink/trmnl/android/data/TrmnlDeviceConfigDataStoreTest.kt @@ -821,7 +821,7 @@ class TrmnlDeviceConfigDataStoreTest { } @Test - fun `deviceConfigFlow migration is idempotent - no repeated saves`() = + fun `deviceConfigFlow migration is idempotent across multiple reads`() = runTest { // Arrange val config =