rename linkedItem to savedItem

This commit is contained in:
Satindar Dhillon
2023-01-04 09:25:52 -08:00
parent 8f695ee06d
commit 3f2fb0b2e0
19 changed files with 83 additions and 90 deletions

View File

@ -5,7 +5,7 @@ import app.omnivore.omnivore.graphql.generated.SetLinkArchivedMutation
import app.omnivore.omnivore.graphql.generated.type.ArchiveLinkInput
import app.omnivore.omnivore.graphql.generated.type.SetBookmarkArticleInput
suspend fun Networker.deleteLinkedItem(itemID: String): Boolean {
suspend fun Networker.deleteSavedItem(itemID: String): Boolean {
return try {
val input = SetBookmarkArticleInput(itemID, false)
val result = authenticatedApolloClient().mutation(SetBookmarkArticleMutation(input)).execute()
@ -15,15 +15,15 @@ suspend fun Networker.deleteLinkedItem(itemID: String): Boolean {
}
}
suspend fun Networker.archiveLinkedItem(itemID: String): Boolean {
return updateArchiveStatusLinkedItem(itemID, true)
suspend fun Networker.archiveSavedItem(itemID: String): Boolean {
return updateArchiveStatusSavedItem(itemID, true)
}
suspend fun Networker.unarchiveLinkedItem(itemID: String): Boolean {
return updateArchiveStatusLinkedItem(itemID, false)
suspend fun Networker.unarchiveSavedItem(itemID: String): Boolean {
return updateArchiveStatusSavedItem(itemID, false)
}
private suspend fun Networker.updateArchiveStatusLinkedItem(itemID: String, setAsArchived: Boolean): Boolean {
private suspend fun Networker.updateArchiveStatusSavedItem(itemID: String, setAsArchived: Boolean): Boolean {
return try {
val input = ArchiveLinkInput(setAsArchived, itemID)
val result = authenticatedApolloClient().mutation(SetLinkArchivedMutation(input)).execute()

View File

@ -1,35 +1,35 @@
package app.omnivore.omnivore.networking
import app.omnivore.omnivore.graphql.generated.GetArticleQuery
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.persistence.entities.LinkedItemLabel
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
import app.omnivore.omnivore.persistence.entities.Highlight
data class LinkedItemQueryResponse(
val item: LinkedItem?,
data class SavedItemQueryResponse(
val item: SavedItem?,
val highlights: List<Highlight>,
val labels: List<LinkedItemLabel>
val labels: List<SavedItemLabel>
) {
companion object {
fun emptyResponse(): LinkedItemQueryResponse {
return LinkedItemQueryResponse(null, listOf(), listOf())
fun emptyResponse(): SavedItemQueryResponse {
return SavedItemQueryResponse(null, listOf(), listOf())
}
}
}
suspend fun Networker.linkedItem(slug: String): LinkedItemQueryResponse {
suspend fun Networker.savedItem(slug: String): SavedItemQueryResponse {
try {
val result = authenticatedApolloClient().query(
GetArticleQuery(slug = slug)
).execute()
val article = result.data?.article?.onArticleSuccess?.article
?: return LinkedItemQueryResponse.emptyResponse()
?: return SavedItemQueryResponse.emptyResponse()
val labels = article.labels ?: listOf()
val linkedItemLabels = labels.map {
LinkedItemLabel(
val savedItemLabels = labels.map {
SavedItemLabel(
id = it.labelFields.id,
name = it.labelFields.name,
color = it.labelFields.color,
@ -59,7 +59,7 @@ suspend fun Networker.linkedItem(slug: String): LinkedItemQueryResponse {
// TODO: handle errors
val linkedItem = LinkedItem(
val savedItem = SavedItem(
id = article.articleFields.id,
title = article.articleFields.title,
createdAt = article.articleFields.createdAt as String,
@ -81,8 +81,8 @@ suspend fun Networker.linkedItem(slug: String): LinkedItemQueryResponse {
content = article.articleFields.content
)
return LinkedItemQueryResponse(item = linkedItem, highlights, labels = linkedItemLabels)
return SavedItemQueryResponse(item = savedItem, highlights, labels = savedItemLabels)
} catch (e: java.lang.Exception) {
return LinkedItemQueryResponse(item = null, listOf(), labels = listOf())
return SavedItemQueryResponse(item = null, listOf(), labels = listOf())
}
}

View File

@ -2,12 +2,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.LinkedItem
import app.omnivore.omnivore.persistence.entities.SavedItem
import com.apollographql.apollo3.api.Optional
data class SearchQueryResponse(
val cursor: String?,
val items: List<LinkedItem>
val items: List<SavedItem>
)
suspend fun Networker.typeaheadSearch(
@ -21,7 +21,7 @@ suspend fun Networker.typeaheadSearch(
val itemList = result.data?.typeaheadSearch?.onTypeaheadSearchSuccess?.items ?: listOf()
val items = itemList.map {
LinkedItem(
SavedItem(
id = it.id,
title = it.title,
createdAt = "",
@ -69,7 +69,7 @@ suspend fun Networker.search(
val itemList = result.data?.search?.onSearchSuccess?.edges ?: listOf()
val items = itemList.map {
LinkedItem(
SavedItem(
id = it.node.id,
title = it.node.title,
createdAt = it.node.createdAt as String,

View File

@ -20,7 +20,7 @@ data class Highlight(
val suffix: String?,
val updatedAt: LocalDate?
// has many LinkedItemLabels (inverse: labels have many highlights)
// has one linkedItem (inverse: linkedItem has many highlights
// has many SavedItemLabels (inverse: labels have many highlights)
// has one savedItem (inverse: savedItem has many highlights
// has a UserProfile (no inverse)
)

View File

@ -11,5 +11,5 @@ data class Recommendation(
val recommendedAt: String?
)
// hasOne LinkedItem
// hasOne SavedItem
// hasOne UserProfile

View File

@ -6,7 +6,7 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class LinkedItem(
data class SavedItem(
@PrimaryKey val id: String,
val title: String,
val createdAt: String,
@ -41,7 +41,7 @@ data class LinkedItem(
// hasMany highlights
// hasMany labels
// has Many recommendations (rec has one linkedItem)
// has Many recommendations (rec has one savedItem)
) {
fun publisherDisplayName(): String? {
return publisherURLString?.toUri()?.host
@ -56,7 +56,7 @@ data class LinkedItem(
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as LinkedItem
other as SavedItem
if (id != other.id) return false

View File

@ -4,7 +4,7 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class LinkedItemLabel(
data class SavedItemLabel(
@PrimaryKey val id: String,
val name: String,
val color: String,
@ -14,4 +14,4 @@ data class LinkedItemLabel(
)
// has many highlights
// has many linkedItems
// has many savedItems

View File

@ -4,15 +4,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.*
import androidx.lifecycle.viewmodel.compose.viewModel
import app.omnivore.omnivore.*
import app.omnivore.omnivore.graphql.generated.SearchQuery
import app.omnivore.omnivore.graphql.generated.ValidateUsernameQuery
import app.omnivore.omnivore.networking.LinkedItemQueryResponse
import app.omnivore.omnivore.networking.Networker
import app.omnivore.omnivore.networking.viewer
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.Optional
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task

View File

@ -20,8 +20,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import app.omnivore.omnivore.Routes
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.ui.linkedItemViews.LinkedItemCard
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.ui.savedItemViews.SavedItemCard
import app.omnivore.omnivore.ui.reader.PDFReaderActivity
import kotlinx.coroutines.flow.distinctUntilChanged
@ -70,7 +70,7 @@ fun LibraryViewContent(
onRefresh = { libraryViewModel.refresh() }
)
val linkedItems: List<LinkedItem> by libraryViewModel.itemsLiveData.observeAsState(listOf())
val savedItems: List<SavedItem> by libraryViewModel.itemsLiveData.observeAsState(listOf())
Box(
modifier = Modifier
@ -86,19 +86,19 @@ fun LibraryViewContent(
.fillMaxSize()
.padding(horizontal = 6.dp)
) {
items(linkedItems) { item ->
LinkedItemCard(
items(savedItems) { item ->
SavedItemCard(
item = item,
onClickHandler = {
if (item.isPDF()) {
val intent = Intent(context, PDFReaderActivity::class.java)
intent.putExtra("LINKED_ITEM_SLUG", item.slug)
intent.putExtra("SAVED_ITEM_SLUG", item.slug)
context.startActivity(intent)
} else {
navController.navigate("WebReader/${item.slug}")
}
},
actionHandler = { libraryViewModel.handleLinkedItemAction(item.id, it) }
actionHandler = { libraryViewModel.handleSavedItemAction(item.id, it) }
)
}
}

View File

@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.omnivore.omnivore.DataService
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.networking.*
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
@ -23,8 +23,8 @@ class LibraryViewModel @Inject constructor(
private val dataService: DataService
): ViewModel() {
private var cursor: String? = null
private var items: List<LinkedItem> = listOf()
private var searchedItems: List<LinkedItem> = listOf()
private var items: List<SavedItem> = listOf()
private var searchedItems: List<SavedItem> = 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<LinkedItem>>(listOf())
val itemsLiveData = MutableLiveData<List<SavedItem>>(listOf())
var isRefreshing by mutableStateOf(false)
fun updateSearchText(text: String) {
@ -100,25 +100,25 @@ class LibraryViewModel @Inject constructor(
}
}
fun handleLinkedItemAction(itemID: String, action: LinkedItemAction) {
fun handleSavedItemAction(itemID: String, action: SavedItemAction) {
when (action) {
LinkedItemAction.Delete -> {
SavedItemAction.Delete -> {
removeItemFromList(itemID)
viewModelScope.launch {
networker.deleteLinkedItem(itemID)
networker.deleteSavedItem(itemID)
}
}
LinkedItemAction.Archive -> {
SavedItemAction.Archive -> {
removeItemFromList(itemID)
viewModelScope.launch {
networker.archiveLinkedItem(itemID)
networker.archiveSavedItem(itemID)
}
}
LinkedItemAction.Unarchive -> {
SavedItemAction.Unarchive -> {
removeItemFromList(itemID)
viewModelScope.launch {
networker.unarchiveLinkedItem(itemID)
networker.unarchiveSavedItem(itemID)
}
}
}
@ -142,7 +142,7 @@ class LibraryViewModel @Inject constructor(
}
}
enum class LinkedItemAction {
enum class SavedItemAction {
Delete,
Archive,
Unarchive

View File

@ -78,7 +78,7 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener, TextSelectionMan
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
viewModel.pdfReaderParamsLiveData.observe(this, pdfParamsObserver)
val slug = intent.getStringExtra("LINKED_ITEM_SLUG") ?: ""
val slug = intent.getStringExtra("SAVED_ITEM_SLUG") ?: ""
viewModel.loadItem(slug, this)
}

View File

@ -10,7 +10,7 @@ import app.omnivore.omnivore.DatastoreRepository
import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput
import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput
import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.networking.*
import com.apollographql.apollo3.api.Optional
import com.google.gson.Gson
@ -29,7 +29,7 @@ import java.util.*
import javax.inject.Inject
data class PDFReaderParams(
val item: LinkedItem,
val item: SavedItem,
val articleContent: ArticleContent,
val localFileUri: Uri
)
@ -45,7 +45,7 @@ class PDFReaderViewModel @Inject constructor(
fun loadItem(slug: String, context: Context) {
viewModelScope.launch {
val articleQueryResult = networker.linkedItem(slug)
val articleQueryResult = networker.savedItem(slug)
val article = articleQueryResult.item ?: return@launch

View File

@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.*
import androidx.compose.runtime.*
@ -29,14 +28,12 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat.getSystemService
import app.omnivore.omnivore.R
import app.omnivore.omnivore.ui.linkedItemViews.LinkedItemContextMenu
import app.omnivore.omnivore.ui.savedItemViews.SavedItemContextMenu
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.util.*
import kotlin.math.roundToInt
@ -112,11 +109,11 @@ fun WebReaderLoadingContainer(slug: String, webReaderViewModel: WebReaderViewMod
contentDescription = null
)
}
LinkedItemContextMenu(
SavedItemContextMenu(
isExpanded = isMenuExpanded,
isArchived = webReaderParams!!.item.isArchived,
onDismiss = { isMenuExpanded = false },
actionHandler = { webReaderViewModel.handleLinkedItemAction(webReaderParams!!.item.id, it) }
actionHandler = { webReaderViewModel.handleSavedItemAction(webReaderParams!!.item.id, it) }
)
}
)

View File

@ -1,7 +1,7 @@
package app.omnivore.omnivore.ui.reader
import android.util.Log
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.persistence.entities.Highlight
import com.google.gson.Gson
@ -39,7 +39,7 @@ data class ArticleContent(
data class WebReaderContent(
val preferences: WebPreferences,
val item: LinkedItem,
val item: SavedItem,
val articleContent: ArticleContent,
) {
fun styledContent(): String {

View File

@ -7,9 +7,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.omnivore.omnivore.DatastoreKeys
import app.omnivore.omnivore.DatastoreRepository
import app.omnivore.omnivore.persistence.entities.LinkedItem
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.networking.*
import app.omnivore.omnivore.ui.library.LinkedItemAction
import app.omnivore.omnivore.ui.library.SavedItemAction
import com.google.gson.Gson
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
@ -20,7 +20,7 @@ import java.util.*
import javax.inject.Inject
data class WebReaderParams(
val item: LinkedItem,
val item: SavedItem,
val articleContent: ArticleContent
)
@ -47,7 +47,7 @@ class WebReaderViewModel @Inject constructor(
fun loadItem(slug: String) {
viewModelScope.launch {
val articleQueryResult = networker.linkedItem(slug)
val articleQueryResult = networker.savedItem(slug)
val article = articleQueryResult.item ?: return@launch
@ -64,23 +64,23 @@ class WebReaderViewModel @Inject constructor(
}
}
fun handleLinkedItemAction(itemID: String, action: LinkedItemAction) {
fun handleSavedItemAction(itemID: String, action: SavedItemAction) {
when (action) {
LinkedItemAction.Delete -> {
SavedItemAction.Delete -> {
viewModelScope.launch {
networker.deleteLinkedItem(itemID)
networker.deleteSavedItem(itemID)
popToLibraryView(itemID)
}
}
LinkedItemAction.Archive -> {
SavedItemAction.Archive -> {
viewModelScope.launch {
networker.archiveLinkedItem(itemID)
networker.archiveSavedItem(itemID)
popToLibraryView(itemID)
}
}
LinkedItemAction.Unarchive -> {
SavedItemAction.Unarchive -> {
viewModelScope.launch {
networker.unarchiveLinkedItem(itemID)
networker.unarchiveSavedItem(itemID)
popToLibraryView(itemID)
}
}

View File

@ -1,4 +1,4 @@
package app.omnivore.omnivore.ui.linkedItemViews
package app.omnivore.omnivore.ui.savedItemViews
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
@ -12,13 +12,13 @@ import androidx.compose.ui.graphics.Color
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.LinkedItem
import app.omnivore.omnivore.ui.library.LinkedItemAction
import app.omnivore.omnivore.persistence.entities.SavedItem
import app.omnivore.omnivore.ui.library.SavedItemAction
import coil.compose.rememberAsyncImagePainter
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LinkedItemCard(item: LinkedItem, onClickHandler: () -> Unit, actionHandler: (LinkedItemAction) -> Unit) {
fun SavedItemCard(item: SavedItem, onClickHandler: () -> Unit, actionHandler: (SavedItemAction) -> Unit) {
var isMenuExpanded by remember { mutableStateOf(false) }
val publisherDisplayName = item.publisherDisplayName()
@ -69,7 +69,7 @@ fun LinkedItemCard(item: LinkedItem, onClickHandler: () -> Unit, actionHandler:
if (item.imageURLString != null) {
Image(
painter = rememberAsyncImagePainter(item.imageURLString),
contentDescription = "Image associated with linked item",
contentDescription = "Image associated with saved item",
modifier = Modifier
.padding(top = 6.dp)
.clip(RoundedCornerShape(6.dp))
@ -80,7 +80,7 @@ fun LinkedItemCard(item: LinkedItem, onClickHandler: () -> Unit, actionHandler:
Divider(color = MaterialTheme.colorScheme.outlineVariant, thickness = 1.dp)
LinkedItemContextMenu(
SavedItemContextMenu(
isExpanded = isMenuExpanded,
isArchived = item.isArchived,
onDismiss = { isMenuExpanded = false },

View File

@ -1,4 +1,4 @@
package app.omnivore.omnivore.ui.linkedItemViews
package app.omnivore.omnivore.ui.savedItemViews
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
@ -8,14 +8,14 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import app.omnivore.omnivore.ui.library.LinkedItemAction
import app.omnivore.omnivore.ui.library.SavedItemAction
@Composable
fun LinkedItemContextMenu(
fun SavedItemContextMenu(
isExpanded: Boolean,
isArchived: Boolean,
onDismiss: () -> Unit,
actionHandler: (LinkedItemAction) -> Unit
actionHandler: (SavedItemAction) -> Unit
) {
DropdownMenu(
expanded = isExpanded,
@ -24,7 +24,7 @@ fun LinkedItemContextMenu(
DropdownMenuItem(
text = { Text(if (isArchived) "Unarchive" else "Archive") },
onClick = {
val action = if (isArchived) LinkedItemAction.Unarchive else LinkedItemAction.Archive
val action = if (isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive
actionHandler(action)
onDismiss()
},
@ -38,7 +38,7 @@ fun LinkedItemContextMenu(
DropdownMenuItem(
text = { Text("Remove Item") },
onClick = {
actionHandler(LinkedItemAction.Delete)
actionHandler(SavedItemAction.Delete)
onDismiss()
},
leadingIcon = {