mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
load library list using room db
This commit is contained in:
parent
eeddb810b3
commit
8faf23d4ba
3 changed files with 75 additions and 48 deletions
|
|
@ -18,15 +18,32 @@ class DataService @Inject constructor(
|
|||
).build()
|
||||
}
|
||||
|
||||
suspend fun DataService.sync(since: String, cursor: String?, limit: Int = 15): Boolean {
|
||||
val syncResult = networker.savedItemUpdates(cursor = cursor, limit = limit, since = since) ?: return false
|
||||
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")
|
||||
// TODO: Store items in Room DB
|
||||
|
||||
return true
|
||||
db.savedItemDao().insertAll(syncResult.items)
|
||||
|
||||
return SavedItemSyncMarker(
|
||||
hasError = false,
|
||||
hasMoreItems = syncResult.hasMoreItems,
|
||||
cursor = syncResult.cursor,
|
||||
count = syncResult.items.size
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun DataService.syncOfflineItemsWithServerIfNeeded() {
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
data class SavedItemSyncMarker(
|
||||
val hasError: Boolean,
|
||||
val hasMoreItems: Boolean,
|
||||
val count: Int,
|
||||
val cursor: String?
|
||||
) {
|
||||
companion object {
|
||||
val errorResult = SavedItemSyncMarker(hasError = true, hasMoreItems = true, cursor = null, count = 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ suspend fun Networker.savedItem(slug: String): SavedItemQueryResponse {
|
|||
updatedAt = null, //updatedAtString?.let { str -> LocalDate.parse(str) }, TODO: fix date parsing
|
||||
createdByMe = it.highlightFields.createdByMe,
|
||||
markedForDeletion = false,
|
||||
serverSyncStatus = 0
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,63 +56,72 @@ class LibraryViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun syncItems() {
|
||||
private suspend fun syncItems() {
|
||||
val syncStart = LocalDateTime.now()
|
||||
val lastSyncDate = getLastSyncTime() ?: LocalDateTime.MIN
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
dataService.syncOfflineItemsWithServerIfNeeded()
|
||||
dataService.sync(since = lastSyncDate.toString(), cursor = null)
|
||||
performItemSync(cursor = null, since = lastSyncDate.toString(), count = 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun load(clearPreviousSearch: Boolean = false) {
|
||||
private suspend fun performItemSync(cursor: String?, since: String, count: Int) {
|
||||
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")
|
||||
|
||||
if (totalCount < 180 && !result.hasError && result.hasMoreItems && result.cursor != null) {
|
||||
performItemSync(cursor = result.cursor, since = since, count = totalCount)
|
||||
} else {
|
||||
Log.d("sync", "grabbed $count total items")
|
||||
|
||||
val items = dataService.db.savedItemDao().getLibraryData()
|
||||
|
||||
itemsLiveData.postValue(items)
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun performSearch(clearPreviousSearch: Boolean) {
|
||||
if (clearPreviousSearch) {
|
||||
cursor = null
|
||||
}
|
||||
|
||||
val thisSearchIdx = searchIdx
|
||||
searchIdx += 1
|
||||
|
||||
// Execute the search
|
||||
val searchResult = networker.typeaheadSearch(searchTextLiveData.value ?: "")
|
||||
|
||||
// Search results aren't guaranteed to return in order so this
|
||||
// will discard old results that are returned while a user is typing.
|
||||
// For example if a user types 'Canucks', often the search results
|
||||
// for 'C' are returned after 'Canucks' because it takes the backend
|
||||
// much longer to compute.
|
||||
if (thisSearchIdx in 1..receivedIdx) {
|
||||
return
|
||||
}
|
||||
|
||||
val previousItems = if (clearPreviousSearch) listOf() else searchedItems
|
||||
searchedItems = previousItems.plus(searchResult.cardsData)
|
||||
itemsLiveData.postValue(searchedItems)
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
fun load(clearPreviousSearch: Boolean = false) {
|
||||
viewModelScope.launch {
|
||||
syncItems()
|
||||
val thisSearchIdx = searchIdx
|
||||
searchIdx += 1
|
||||
|
||||
// Execute the search
|
||||
val searchResult =
|
||||
if (searchTextLiveData.value != "") {
|
||||
networker.typeaheadSearch(searchTextLiveData.value ?: "")
|
||||
} else {
|
||||
networker.search(cursor = cursor, query = searchQuery())
|
||||
}
|
||||
|
||||
// Search results aren't guaranteed to return in order so this
|
||||
// will discard old results that are returned while a user is typing.
|
||||
// For example if a user types 'Canucks', often the search results
|
||||
// for 'C' are returned after 'Canucks' because it takes the backend
|
||||
// much longer to compute.
|
||||
if (thisSearchIdx in 1..receivedIdx) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
receivedIdx = thisSearchIdx
|
||||
cursor = searchResult.cursor
|
||||
|
||||
if (searchTextLiveData.value != "" || clearPreviousSearch) {
|
||||
val previousItems = if (clearPreviousSearch) listOf() else searchedItems
|
||||
searchedItems = previousItems.plus(searchResult.cardsData)
|
||||
itemsLiveData.postValue(searchedItems)
|
||||
if (searchTextLiveData.value != "") {
|
||||
performSearch(clearPreviousSearch)
|
||||
} else {
|
||||
items = items.plus(searchResult.cardsData)
|
||||
itemsLiveData.postValue(items)
|
||||
}
|
||||
|
||||
// withContext(Dispatchers.IO) {
|
||||
// dataService.db.savedItemDao().insertAll(items)
|
||||
// val items = dataService.db.savedItemDao().getLibraryData()
|
||||
// Log.d("appDatabase", "libraryData: $items")
|
||||
// }
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
isRefreshing = false
|
||||
syncItems()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue