소스 검색

sync improvement

Milan Jurkulak 3 년 전
부모
커밋
a93bd9b86b

+ 1 - 0
app/src/main/kotlin/org/mjdev/tvapp/activity/IPTVActivity.kt

@@ -48,6 +48,7 @@ class IPTVActivity : ComposableActivity() {
     override fun onIntent(navController: NavHostControllerEx, intent: Intent?) {
         val data = intent?.getSerializableExtra(IPTV_DATA)
         when (data) {
+            null -> finish()
             is Movie -> navController.openAsTop<IPTVScreen>(data)
             is ItemAudio -> navController.openAsTop<IPTVScreen>(data)
             is ItemVideo -> navController.openAsTop<IPTVScreen>(data)

+ 86 - 36
app/src/main/kotlin/org/mjdev/tvapp/sync/SyncAdapter.kt

@@ -9,7 +9,6 @@ import android.os.Bundle
 import io.objectbox.Box
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.channelFlow
 import kotlinx.coroutines.launch
 import org.mjdev.tvapp.data.local.Movie
 import org.mjdev.tvapp.database.DAO
@@ -33,10 +32,6 @@ class SyncAdapter(
 
     private val movieDao: Box<Movie> get() = dao.movieDao
 
-    private val moviesSynced by lazy {
-        movieDao.all.toMutableList()
-    }
-
     override fun onPerformSync(
         account: Account?,
         extras: Bundle?,
@@ -46,53 +41,108 @@ class SyncAdapter(
     ) {
         try {
             coroutineScope.launch {
-                channelFlow {
-                    val streams = apiService.streams().safeGet()
-                    val channels = apiService.channels().safeGet()
-                    streams.forEach { stream ->
-                        channels.firstOrNull { channel ->
-                            channel.id == stream.channelId
-                        }.also { channel ->
-                            (channel?.categories ?: listOf(null)).forEach { ctg ->
-                                send(Movie().apply {
-                                    title = channel?.name ?: stream.channelId
-                                    uri = stream.url
-                                    category = ctg
-                                    image = channel?.logo
-                                    country = channel?.country
-                                    isNsfw = channel?.isNsfw ?: false
-                                })
-                            }
+
+                val streams = apiService.streams().safeGet()
+                val channels = apiService.channels().safeGet()
+
+                val oldMovies = movieDao.all
+                val newMovies = mutableListOf<Movie>()
+
+                streams.forEach { stream ->
+                    channels.firstOrNull { channel ->
+                        channel.id == stream.channelId
+                    }.also { channel ->
+                        (channel?.categories ?: listOf(null)).forEach { ctg ->
+                            newMovies.add(Movie().apply {
+                                title = channel?.name ?: stream.channelId
+                                uri = stream.url
+                                category = ctg
+                                image = channel?.logo
+                                country = channel?.country
+                                isNsfw = channel?.isNsfw ?: false
+                            })
                         }
                     }
-                }.collect { movie ->
-                    val exists = moviesSynced.firstOrNull { synced ->
-                        synced.uri == movie.uri
-                    }
-                    if (exists != null) {
-                        try {
-                            dao.movieDao.tx {
-                                remove(exists)
-                            }
-                            Timber.d("Movie: $exists removed.")
-                        } catch (e: Exception) {
-                            Timber.e(e)
+                }
+
+                val syncItems = SyncItems(oldMovies, newMovies)
+
+                syncItems.toAdd.forEach { movie ->
+                    try {
+                        dao.movieDao.tx {
+                            put(movie)
                         }
+                        Timber.d("Movie: $movie stored.")
+                    } catch (e: Exception) {
+                        Timber.e(e)
                     }
+                }
+
+                syncItems.toUpdate.forEach { movie ->
                     try {
                         dao.movieDao.tx {
                             put(movie)
                         }
-                        moviesSynced.add(movie)
-                        Timber.d("Movie: $movie stored.")
+                        Timber.d("Movie: $movie updated.")
                     } catch (e: Exception) {
                         Timber.e(e)
                     }
                 }
+
+                syncItems.toRemove.forEach { movie ->
+                    try {
+                        dao.movieDao.tx {
+                            remove(movie)
+                        }
+                        Timber.d("Movie: $movie removed.")
+                    } catch (e: Exception) {
+                        Timber.e(e)
+                    }
+                }
+
             }
         } catch (e: Exception) {
             Timber.e(e)
         }
     }
 
+    class SyncItems(
+        private val oldMovies: List<Movie>,
+        private val newMovies: List<Movie>
+    ) {
+
+        val toAdd = mutableListOf<Movie>()
+        val toUpdate = mutableListOf<Movie>()
+        val toRemove = mutableListOf<Movie>()
+
+        init {
+
+            newMovies.filter { newMovie ->
+                newMovie.hasUri && (oldMovies.count { oldMovie ->
+                    oldMovie.uri.contentEquals(newMovie.uri)
+                } == 0)
+            }.also { addMovies ->
+                toAdd.addAll(addMovies)
+            }
+
+            newMovies.filter { newMovie ->
+                newMovie.hasUri && (oldMovies.count { oldMovie ->
+                    oldMovie.uri.contentEquals(newMovie.uri)
+                } > 0)
+            }.also { updateMovies ->
+                toUpdate.addAll(updateMovies)
+            }
+
+            oldMovies.filter { oldMovie ->
+                 (newMovies.count { newMovie ->
+                    newMovie.uri.contentEquals(oldMovie.uri)
+                } == 0)
+            }.also { addMovies ->
+                toRemove.addAll(addMovies)
+            }
+
+        }
+
+    }
+
 }

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithUri.kt

@@ -12,7 +12,6 @@ interface ItemWithUri<T> {
 
     val uri: T?
 
-    val hasUri
-        get() = (uri != null) && (uri.toString().isNotEmpty())
+    val hasUri get() = (uri != null) && (uri.toString().isNotEmpty())
 
 }