From ce31afc8e3592fb593dc0cdf64eeeb2940522b24 Mon Sep 17 00:00:00 2001 From: AE <98699388+A-EDev@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:40:29 +0300 Subject: [PATCH 01/14] fix(playlists): keep known video details when a save carries blanks --- .../flow/data/local/PlaylistRepository.kt | 2 +- .../aedev/flow/data/local/dao/VideoDao.kt | 21 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/app/src/main/java/io/github/aedev/flow/data/local/PlaylistRepository.kt b/app/src/main/java/io/github/aedev/flow/data/local/PlaylistRepository.kt index aafa330e94..492af07cab 100644 --- a/app/src/main/java/io/github/aedev/flow/data/local/PlaylistRepository.kt +++ b/app/src/main/java/io/github/aedev/flow/data/local/PlaylistRepository.kt @@ -39,7 +39,7 @@ class PlaylistRepository } suspend fun updateVideoMetadata(video: Video) { - videoDao.upsertMetadata(listOf(normalizedEntity(video))) + videoDao.mergeMetadata(listOf(normalizedEntity(video))) } private fun normalizedEntity(video: Video): VideoEntity { diff --git a/app/src/main/java/io/github/aedev/flow/data/local/dao/VideoDao.kt b/app/src/main/java/io/github/aedev/flow/data/local/dao/VideoDao.kt index 332d734afc..9530955faf 100644 --- a/app/src/main/java/io/github/aedev/flow/data/local/dao/VideoDao.kt +++ b/app/src/main/java/io/github/aedev/flow/data/local/dao/VideoDao.kt @@ -118,27 +118,6 @@ interface VideoDao { } } - /** Inserts or refreshes many videos as one change, so a list observing them updates once. */ - @Transaction - suspend fun upsertMetadata(entities: List) { - entities.forEach { entity -> - insertVideoOrIgnore(entity) - updateVideoMetadata( - id = entity.id, - title = entity.title, - channelName = entity.channelName, - channelId = entity.channelId, - thumbnailUrl = entity.thumbnailUrl, - duration = entity.duration, - viewCount = entity.viewCount, - uploadDate = entity.uploadDate, - timestamp = entity.timestamp, - description = entity.description, - channelThumbnailUrl = entity.channelThumbnailUrl, - ) - } - } - @Query("SELECT * FROM videos WHERE id = :id") suspend fun getVideo(id: String): VideoEntity? From a07622b9ef5270c48227608b588a8323859d93c1 Mon Sep 17 00:00:00 2001 From: AE <98699388+A-EDev@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:41:08 +0300 Subject: [PATCH 02/14] feat(subscriptions): read one cached feed row by video id --- .../main/java/io/github/aedev/flow/data/local/dao/CacheDao.kt | 3 +++ .../flow/data/subscriptions/SubscriptionFeedRepository.kt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/app/src/main/java/io/github/aedev/flow/data/local/dao/CacheDao.kt b/app/src/main/java/io/github/aedev/flow/data/local/dao/CacheDao.kt index 9424e6060c..cac96716b1 100644 --- a/app/src/main/java/io/github/aedev/flow/data/local/dao/CacheDao.kt +++ b/app/src/main/java/io/github/aedev/flow/data/local/dao/CacheDao.kt @@ -42,6 +42,9 @@ interface CacheDao { @Query("SELECT * FROM subscription_feed_cache WHERE channelId IN (:channelIds)") suspend fun getSubscriptionFeedForChannels(channelIds: List): List + @Query("SELECT * FROM subscription_feed_cache WHERE videoId = :videoId") + suspend fun getSubscriptionFeedRow(videoId: String): SubscriptionFeedEntity? + @Query("SELECT DISTINCT channelId, channelName FROM subscription_feed_cache WHERE channelId IN (:channelIds) AND channelName != ''") suspend fun subscriptionFeedChannelNames(channelIds: List): List diff --git a/app/src/main/java/io/github/aedev/flow/data/subscriptions/SubscriptionFeedRepository.kt b/app/src/main/java/io/github/aedev/flow/data/subscriptions/SubscriptionFeedRepository.kt index 0eb8566701..151e7a6862 100644 --- a/app/src/main/java/io/github/aedev/flow/data/subscriptions/SubscriptionFeedRepository.kt +++ b/app/src/main/java/io/github/aedev/flow/data/subscriptions/SubscriptionFeedRepository.kt @@ -328,6 +328,10 @@ class SubscriptionFeedRepository Log.d(TAG, "Seeded ${rows.size} row(s) for $channelId from the notification check") } + /** The feed's stored copy of [videoId], or null when the feed has never seen it. */ + suspend fun cachedVideo(videoId: String): Video? = + withContext(PerformanceDispatcher.diskIO) { cacheDao.getSubscriptionFeedRow(videoId)?.toVideo() } + /** Writes back metadata the on-demand player lookup resolved for already-cached rows. */ suspend fun updateEnrichedMetadata(videos: Collection