diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DataService.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DataService.kt index 80790f8c1..cac359629 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DataService.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DataService.kt @@ -21,8 +21,6 @@ class DataService @Inject constructor( suspend fun DataService.sync(since: String, cursor: String?, limit: Int = 15): SavedItemSyncMarker { val syncResult = networker.savedItemUpdates(cursor = cursor, limit = limit, since = since) ?: return SavedItemSyncMarker.errorResult - Log.d("sync", "count: ${syncResult.totalCount}; sync result: $syncResult") - db.savedItemDao().insertAll(syncResult.items) return SavedItemSyncMarker( diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt index 1f0935697..0a9a1c58c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt @@ -1,9 +1,9 @@ package app.omnivore.omnivore.persistence.entities import androidx.core.net.toUri +import androidx.lifecycle.LiveData import androidx.room.* -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.persistence.BaseDao +import java.util.* @Entity data class SavedItem( @@ -105,12 +105,15 @@ data class SavedItemCardData( @Dao interface SavedItemDao { - @Query("SELECT id, slug, publisherURLString, title, author, imageURLString, isArchived, pageURLString, contentReader FROM SavedItem") - fun getLibraryData(): List + @Query("SELECT id, slug, publisherURLString, title, author, imageURLString, isArchived, pageURLString, contentReader FROM SavedItem ORDER BY savedAt DESC") + fun getLibraryLiveData(): LiveData> @Query("SELECT * FROM savedItem") fun getAll(): List @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertAll(items: List) + + @Query("DELETE FROM savedItem WHERE id = :itemID") + fun deleteById(itemID: String) } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt index 35a16552d..cf6bac4c7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt @@ -72,6 +72,8 @@ fun LibraryViewContent( ) val cardsData: List by libraryViewModel.itemsLiveData.observeAsState(listOf()) + val searchedCardsData: List by libraryViewModel.searchItemsLiveData.observeAsState(listOf()) + val searchText: String by libraryViewModel.searchTextLiveData.observeAsState("") Box( modifier = Modifier @@ -87,7 +89,7 @@ fun LibraryViewContent( .fillMaxSize() .padding(horizontal = 6.dp) ) { - items(cardsData) { cardData -> + items(if (searchText.isNotEmpty()) searchedCardsData else cardsData) { cardData -> SavedItemCard( cardData = cardData, onClickHandler = { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt index b555199d6..31226c063 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt @@ -22,8 +22,6 @@ class LibraryViewModel @Inject constructor( private val datastoreRepo: DatastoreRepository ): ViewModel() { private var cursor: String? = null - private var items: List = listOf() - private var searchedItems: List = listOf() // These are used to make sure we handle search result // responses in the right order @@ -32,14 +30,16 @@ class LibraryViewModel @Inject constructor( // Live Data val searchTextLiveData = MutableLiveData("") - val itemsLiveData = MutableLiveData>(listOf()) + val searchItemsLiveData = MutableLiveData>(listOf()) + val itemsLiveData = dataService.db.savedItemDao().getLibraryLiveData() + var isRefreshing by mutableStateOf(false) fun updateSearchText(text: String) { searchTextLiveData.value = text if (text == "") { - itemsLiveData.value = items + searchItemsLiveData.value = listOf() } else { load(clearPreviousSearch = true) } @@ -75,25 +75,21 @@ class LibraryViewModel @Inject constructor( } withContext(Dispatchers.IO) { - performItemSync(cursor = null, since = lastSyncDate.toString(), count = 0) + performItemSync(cursor = null, since = lastSyncDate.toString(), count = 0, startTime = syncStart.toString()) } } - private suspend fun performItemSync(cursor: String?, since: String, count: Int) { + private suspend fun performItemSync(cursor: String?, since: String, count: Int, startTime: String) { dataService.syncOfflineItemsWithServerIfNeeded() val result = dataService.sync(since = since, cursor = cursor) val totalCount = count + result.count - Log.d("sync", "grabbed ${result.count} items in this batch") + Log.d("sync", "fetched ${result.count} items") if (totalCount < 180 && !result.hasError && result.hasMoreItems && result.cursor != null) { - performItemSync(cursor = result.cursor, since = since, count = totalCount) + performItemSync(cursor = result.cursor, since = since, count = totalCount, startTime = startTime) } else { - Log.d("sync", "grabbed $count total items") - - val items = dataService.db.savedItemDao().getLibraryData() - - itemsLiveData.postValue(items) + datastoreRepo.putString(DatastoreKeys.libraryLastSyncTimestamp, startTime) } } @@ -117,9 +113,7 @@ class LibraryViewModel @Inject constructor( return } - val previousItems = if (clearPreviousSearch) listOf() else searchedItems - searchedItems = searchResult.cardsData - itemsLiveData.postValue(searchedItems) + searchItemsLiveData.postValue(searchResult.cardsData) CoroutineScope(Dispatchers.Main).launch { isRefreshing = false @@ -151,9 +145,10 @@ class LibraryViewModel @Inject constructor( } private fun removeItemFromList(itemID: String) { - itemsLiveData.value?.let { - val newList = it.filter { item -> item.id != itemID } - itemsLiveData.postValue(newList) + viewModelScope.launch { + withContext(Dispatchers.IO) { + dataService.db.savedItemDao().deleteById(itemID) + } } }