use SavedItemCardData to populate library list
This commit is contained in:
@ -3,11 +3,12 @@ package app.omnivore.omnivore.networking
|
||||
import app.omnivore.omnivore.graphql.generated.SearchQuery
|
||||
import app.omnivore.omnivore.graphql.generated.TypeaheadSearchQuery
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemCardData
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
|
||||
data class SearchQueryResponse(
|
||||
val cursor: String?,
|
||||
val items: List<SavedItem>
|
||||
val cardsData: List<SavedItemCardData>
|
||||
)
|
||||
|
||||
suspend fun Networker.typeaheadSearch(
|
||||
@ -20,31 +21,21 @@ suspend fun Networker.typeaheadSearch(
|
||||
|
||||
val itemList = result.data?.typeaheadSearch?.onTypeaheadSearchSuccess?.items ?: listOf()
|
||||
|
||||
val items = itemList.map {
|
||||
SavedItem(
|
||||
val cardsData = itemList.map {
|
||||
SavedItemCardData(
|
||||
id = it.id,
|
||||
title = it.title,
|
||||
createdAt = "",
|
||||
savedAt = "",
|
||||
readAt = "",
|
||||
updatedAt = "",
|
||||
readingProgress = 0.0,
|
||||
readingProgressAnchor = 0,
|
||||
imageURLString = null,
|
||||
pageURLString = "",
|
||||
descriptionText = "",
|
||||
publisherURLString = "",
|
||||
siteName = it.siteName,
|
||||
author = "",
|
||||
publishDate = null,
|
||||
slug = it.slug,
|
||||
publisherURLString = "",
|
||||
title = it.title,
|
||||
author = "",
|
||||
imageURLString = null,
|
||||
isArchived = false,
|
||||
pageURLString = "",
|
||||
contentReader = null,
|
||||
content = null
|
||||
)
|
||||
}
|
||||
|
||||
return SearchQueryResponse(null, items)
|
||||
return SearchQueryResponse(null, cardsData)
|
||||
} catch (e: java.lang.Exception) {
|
||||
return SearchQueryResponse(null, listOf())
|
||||
}
|
||||
@ -68,31 +59,21 @@ suspend fun Networker.search(
|
||||
val newCursor = result.data?.search?.onSearchSuccess?.pageInfo?.endCursor
|
||||
val itemList = result.data?.search?.onSearchSuccess?.edges ?: listOf()
|
||||
|
||||
val items = itemList.map {
|
||||
SavedItem(
|
||||
val cardsData = itemList.map {
|
||||
SavedItemCardData(
|
||||
id = it.node.id,
|
||||
title = it.node.title,
|
||||
createdAt = it.node.createdAt as String,
|
||||
savedAt = it.node.savedAt as String,
|
||||
readAt = it.node.readAt as String?,
|
||||
updatedAt = it.node.updatedAt as String?,
|
||||
readingProgress = it.node.readingProgressPercent,
|
||||
readingProgressAnchor = it.node.readingProgressAnchorIndex,
|
||||
imageURLString = it.node.image,
|
||||
pageURLString = it.node.url,
|
||||
descriptionText = it.node.description,
|
||||
publisherURLString = it.node.originalArticleUrl,
|
||||
siteName = it.node.siteName,
|
||||
author = it.node.author,
|
||||
publishDate = it.node.publishedAt as String?,
|
||||
slug = it.node.slug,
|
||||
publisherURLString = it.node.originalArticleUrl,
|
||||
title = it.node.title,
|
||||
author = it.node.author,
|
||||
imageURLString = it.node.image,
|
||||
isArchived = it.node.isArchived,
|
||||
pageURLString = it.node.url,
|
||||
contentReader = it.node.contentReader.rawValue,
|
||||
content = null
|
||||
)
|
||||
}
|
||||
|
||||
return SearchQueryResponse(newCursor, items)
|
||||
return SearchQueryResponse(newCursor, cardsData)
|
||||
} catch (e: java.lang.Exception) {
|
||||
return SearchQueryResponse(null, listOf())
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import app.omnivore.omnivore.Routes
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemCardData
|
||||
import app.omnivore.omnivore.ui.savedItemViews.SavedItemCard
|
||||
import app.omnivore.omnivore.ui.reader.PDFReaderActivity
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@ -70,7 +71,7 @@ fun LibraryViewContent(
|
||||
onRefresh = { libraryViewModel.refresh() }
|
||||
)
|
||||
|
||||
val savedItems: List<SavedItem> by libraryViewModel.itemsLiveData.observeAsState(listOf())
|
||||
val cardsData: List<SavedItemCardData> by libraryViewModel.itemsLiveData.observeAsState(listOf())
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@ -86,19 +87,19 @@ fun LibraryViewContent(
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 6.dp)
|
||||
) {
|
||||
items(savedItems) { item ->
|
||||
items(cardsData) { cardData ->
|
||||
SavedItemCard(
|
||||
item = item,
|
||||
cardData = cardData,
|
||||
onClickHandler = {
|
||||
if (item.isPDF()) {
|
||||
if (cardData.isPDF()) {
|
||||
val intent = Intent(context, PDFReaderActivity::class.java)
|
||||
intent.putExtra("SAVED_ITEM_SLUG", item.slug)
|
||||
intent.putExtra("SAVED_ITEM_SLUG", cardData.slug)
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
navController.navigate("WebReader/${item.slug}")
|
||||
navController.navigate("WebReader/${cardData.slug}")
|
||||
}
|
||||
},
|
||||
actionHandler = { libraryViewModel.handleSavedItemAction(item.id, it) }
|
||||
actionHandler = { libraryViewModel.handleSavedItemAction(cardData.id, it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.omnivore.omnivore.DataService
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemCardData
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -23,8 +23,8 @@ class LibraryViewModel @Inject constructor(
|
||||
private val dataService: DataService
|
||||
): ViewModel() {
|
||||
private var cursor: String? = null
|
||||
private var items: List<SavedItem> = listOf()
|
||||
private var searchedItems: List<SavedItem> = listOf()
|
||||
private var items: List<SavedItemCardData> = listOf()
|
||||
private var searchedItems: List<SavedItemCardData> = listOf()
|
||||
|
||||
// These are used to make sure we handle search result
|
||||
// responses in the right order
|
||||
@ -33,7 +33,7 @@ class LibraryViewModel @Inject constructor(
|
||||
|
||||
// Live Data
|
||||
val searchTextLiveData = MutableLiveData("")
|
||||
val itemsLiveData = MutableLiveData<List<SavedItem>>(listOf())
|
||||
val itemsLiveData = MutableLiveData<List<SavedItemCardData>>(listOf())
|
||||
var isRefreshing by mutableStateOf(false)
|
||||
|
||||
fun updateSearchText(text: String) {
|
||||
@ -82,18 +82,18 @@ class LibraryViewModel @Inject constructor(
|
||||
|
||||
if (searchTextLiveData.value != "" || clearPreviousSearch) {
|
||||
val previousItems = if (clearPreviousSearch) listOf() else searchedItems
|
||||
searchedItems = previousItems.plus(searchResult.items)
|
||||
searchedItems = previousItems.plus(searchResult.cardsData)
|
||||
itemsLiveData.postValue(searchedItems)
|
||||
} else {
|
||||
items = items.plus(searchResult.items)
|
||||
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")
|
||||
}
|
||||
// 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
|
||||
|
||||
@ -13,14 +13,15 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemCardData
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun SavedItemCard(item: SavedItem, onClickHandler: () -> Unit, actionHandler: (SavedItemAction) -> Unit) {
|
||||
fun SavedItemCard(cardData: SavedItemCardData, onClickHandler: () -> Unit, actionHandler: (SavedItemAction) -> Unit) {
|
||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||
val publisherDisplayName = item.publisherDisplayName()
|
||||
val publisherDisplayName = cardData.publisherDisplayName()
|
||||
|
||||
Column {
|
||||
Row(
|
||||
@ -42,14 +43,14 @@ fun SavedItemCard(item: SavedItem, onClickHandler: () -> Unit, actionHandler: (S
|
||||
.padding(end = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = item.title,
|
||||
text = cardData.title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
lineHeight = 20.sp
|
||||
)
|
||||
|
||||
if (item.author != null && item.author != "") {
|
||||
if (cardData.author != null && cardData.author != "") {
|
||||
Text(
|
||||
text = "By ${item.author}",
|
||||
text = "By ${cardData.author}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -66,9 +67,9 @@ fun SavedItemCard(item: SavedItem, onClickHandler: () -> Unit, actionHandler: (S
|
||||
}
|
||||
}
|
||||
|
||||
if (item.imageURLString != null) {
|
||||
if (cardData.imageURLString != null) {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(item.imageURLString),
|
||||
painter = rememberAsyncImagePainter(cardData.imageURLString),
|
||||
contentDescription = "Image associated with saved item",
|
||||
modifier = Modifier
|
||||
.padding(top = 6.dp)
|
||||
@ -82,7 +83,7 @@ fun SavedItemCard(item: SavedItem, onClickHandler: () -> Unit, actionHandler: (S
|
||||
|
||||
SavedItemContextMenu(
|
||||
isExpanded = isMenuExpanded,
|
||||
isArchived = item.isArchived,
|
||||
isArchived = cardData.isArchived,
|
||||
onDismiss = { isMenuExpanded = false },
|
||||
actionHandler = actionHandler
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user