handle label chages from within web reader activity

This commit is contained in:
Satindar Dhillon 2023-03-14 09:38:26 -07:00
parent e27a0dd3f0
commit 21ab6dd9cd
3 changed files with 105 additions and 9 deletions

View file

@ -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)
}

View file

@ -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) {

View file

@ -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))
}
}
}
}
}