mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
handle label chages from within web reader activity
This commit is contained in:
parent
e27a0dd3f0
commit
21ab6dd9cd
3 changed files with 105 additions and 9 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package app.omnivore.omnivore.ui.components
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
|
|
@ -11,21 +10,50 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AddCircle
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.ui.library.LibraryViewModel
|
||||
import app.omnivore.omnivore.ui.reader.WebPreferencesView
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderParams
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderViewModel
|
||||
|
||||
@Composable
|
||||
fun WebReaderLabelsSelectionSheet(viewModel: WebReaderViewModel) {
|
||||
val isActive: Boolean by viewModel.showLabelsSelectionSheetLiveData.observeAsState(false)
|
||||
val labels: List<SavedItemLabel> by viewModel.savedItemLabelsLiveData.observeAsState(listOf())
|
||||
val webReaderParams: WebReaderParams? by viewModel.webReaderParamsLiveData.observeAsState(null)
|
||||
|
||||
if (isActive) {
|
||||
Dialog(onDismissRequest = {
|
||||
viewModel.showLabelsSelectionSheetLiveData.value = false
|
||||
} ) {
|
||||
LabelsSelectionSheetContent(
|
||||
labels = labels,
|
||||
initialSelectedLabels = webReaderParams?.labels ?: listOf(),
|
||||
onCancel = {
|
||||
viewModel.showLabelsSelectionSheetLiveData.value = false
|
||||
},
|
||||
isLibraryMode = false,
|
||||
onSave = {
|
||||
if (it != labels) {
|
||||
viewModel.updateSavedItemLabels(savedItemID = webReaderParams?.item?.savedItemId ?: "", labels = it)
|
||||
}
|
||||
viewModel.showLabelsSelectionSheetLiveData.value = false
|
||||
},
|
||||
onCreateLabel = { newLabelName, labelHexValue ->
|
||||
viewModel.createNewSavedItemLabel(newLabelName, labelHexValue)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LabelsSelectionSheet(viewModel: LibraryViewModel) {
|
||||
val isActive: Boolean by viewModel.showLabelsSelectionSheetLiveData.observeAsState(false)
|
||||
|
|
@ -150,7 +178,8 @@ fun LabelsSelectionSheetContent(
|
|||
.fillMaxWidth()
|
||||
.clickable {
|
||||
if (isLabelSelected) {
|
||||
selectedLabels.value = selectedLabels.value.filter { it.savedItemLabelId != label.savedItemLabelId }
|
||||
selectedLabels.value =
|
||||
selectedLabels.value.filter { it.savedItemLabelId != label.savedItemLabelId }
|
||||
} else {
|
||||
selectedLabels.value = selectedLabels.value + listOf(label)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import app.omnivore.omnivore.MainActivity
|
||||
import app.omnivore.omnivore.ui.components.WebReaderLabelsSelectionSheet
|
||||
import app.omnivore.omnivore.ui.savedItemViews.SavedItemContextMenu
|
||||
import app.omnivore.omnivore.ui.theme.OmnivoreTheme
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
|
|
@ -188,6 +190,8 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
WebReaderLabelsSelectionSheet(webReaderViewModel)
|
||||
}
|
||||
|
||||
LaunchedEffect(shouldPopView) {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,12 @@ import androidx.lifecycle.viewModelScope
|
|||
import app.omnivore.omnivore.DatastoreKeys
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemAndSavedItemLabelCrossRef
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
|
@ -23,7 +27,8 @@ import javax.inject.Inject
|
|||
|
||||
data class WebReaderParams(
|
||||
val item: SavedItem,
|
||||
val articleContent: ArticleContent
|
||||
val articleContent: ArticleContent,
|
||||
val labels: List<SavedItemLabel>
|
||||
)
|
||||
|
||||
data class AnnotationWebViewMessage(
|
||||
|
|
@ -46,12 +51,16 @@ class WebReaderViewModel @Inject constructor(
|
|||
val shouldPopViewLiveData = MutableLiveData(false)
|
||||
val hasFetchError = MutableLiveData(false)
|
||||
val currentToolbarHeightLiveData = MutableLiveData(0.0f)
|
||||
val showLabelsSelectionSheetLiveData = MutableLiveData(false)
|
||||
val savedItemLabelsLiveData = dataService.db.savedItemLabelDao().getSavedItemLabelsLiveData()
|
||||
|
||||
var hasTappedExistingHighlight = false
|
||||
var lastTapCoordinates: TapCoordinates? = null
|
||||
private var isLoading = false
|
||||
private var slug: String? = null
|
||||
|
||||
fun loadItem(slug: String?, requestID: String?) {
|
||||
this.slug = slug
|
||||
if (isLoading || webReaderParamsLiveData.value != null) { return }
|
||||
isLoading = true
|
||||
Log.d("reader", "load item called")
|
||||
|
|
@ -88,6 +97,7 @@ class WebReaderViewModel @Inject constructor(
|
|||
val isSuccessful = webReaderParams?.articleContent?.contentStatus == "SUCCEEDED"
|
||||
|
||||
if (webReaderParams != null && isSuccessful) {
|
||||
this.slug = webReaderParams.item.slug
|
||||
webReaderParamsLiveData.postValue(webReaderParams)
|
||||
isLoading = false
|
||||
} else if (requestCount < 7) {
|
||||
|
|
@ -114,7 +124,13 @@ class WebReaderViewModel @Inject constructor(
|
|||
)
|
||||
|
||||
Log.d("sync", "data loaded from db")
|
||||
webReaderParamsLiveData.postValue(WebReaderParams(persistedItem.savedItem, articleContent))
|
||||
webReaderParamsLiveData.postValue(
|
||||
WebReaderParams(
|
||||
persistedItem.savedItem,
|
||||
articleContent,
|
||||
persistedItem.labels
|
||||
)
|
||||
)
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
|
|
@ -134,7 +150,7 @@ class WebReaderViewModel @Inject constructor(
|
|||
labelsJSONString = Gson().toJson(articleQueryResult.labels)
|
||||
)
|
||||
|
||||
return WebReaderParams(article, articleContent)
|
||||
return WebReaderParams(article, articleContent, articleQueryResult.labels)
|
||||
}
|
||||
|
||||
fun handleSavedItemAction(itemID: String, action: SavedItemAction) {
|
||||
|
|
@ -158,7 +174,7 @@ class WebReaderViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
SavedItemAction.EditLabels -> {
|
||||
Log.d("label", "itemID")
|
||||
showLabelsSelectionSheetLiveData.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -317,4 +333,51 @@ class WebReaderViewModel @Inject constructor(
|
|||
val script = "var event = new Event('updateFontFamily');event.fontFamily = '${font.rawValue}';document.dispatchEvent(event);"
|
||||
enqueueScript(script)
|
||||
}
|
||||
|
||||
fun updateSavedItemLabels(savedItemID: String, labels: List<SavedItemLabel>) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val input = SetLabelsInput(labelIds = labels.map { it.savedItemLabelId }, pageId = savedItemID)
|
||||
val networkResult = networker.updateLabelsForSavedItem(input)
|
||||
|
||||
// TODO: assign a server sync status to these
|
||||
val crossRefs = labels.map {
|
||||
SavedItemAndSavedItemLabelCrossRef(
|
||||
savedItemLabelId = it.savedItemLabelId,
|
||||
savedItemId = savedItemID
|
||||
)
|
||||
}
|
||||
|
||||
// Remove all labels first
|
||||
dataService.db.savedItemAndSavedItemLabelCrossRefDao().deleteRefsBySavedItemId(savedItemID)
|
||||
|
||||
// Add back the current labels
|
||||
dataService.db.savedItemAndSavedItemLabelCrossRefDao().insertAll(crossRefs)
|
||||
|
||||
slug?.let {
|
||||
loadItemFromDB(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createNewSavedItemLabel(labelName: String, hexColorValue: String) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val newLabel = networker.createNewLabel(CreateLabelInput(color = hexColorValue, name = labelName))
|
||||
|
||||
newLabel?.let {
|
||||
val savedItemLabel = SavedItemLabel(
|
||||
savedItemLabelId = it.id,
|
||||
name = it.name,
|
||||
color = it.color,
|
||||
createdAt = it.createdAt as String?,
|
||||
labelDescription = it.description
|
||||
)
|
||||
|
||||
dataService.db.savedItemLabelDao().insertAll(listOf(savedItemLabel))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue