Set labels on creation
This commit is contained in:
@ -262,7 +262,7 @@ fun LabelsSelectionSheetContent(
|
||||
savedItemLabelId = "",
|
||||
name = name.text,
|
||||
labelDescription = "",
|
||||
color = "#FFFFFF", // LabelSwatchHelper.random(),
|
||||
color = LabelSwatchHelper.random(),
|
||||
createdAt = LocalDate.now().atStartOfDay().atOffset(ZoneOffset.UTC).format(
|
||||
DateTimeFormatter.ISO_DATE_TIME),
|
||||
serverSyncStatus = ServerSyncStatus.NEEDS_CREATION.rawValue
|
||||
|
||||
@ -10,17 +10,18 @@ import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.ModalBottomSheetLayout
|
||||
import androidx.compose.material.ModalBottomSheetValue
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.DrawerValue
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||
import androidx.compose.material.pullrefresh.pullRefresh
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.material.rememberModalBottomSheetState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -49,6 +50,7 @@ fun LibraryView(
|
||||
libraryViewModel: LibraryViewModel,
|
||||
navController: NavHostController
|
||||
) {
|
||||
val scaffoldState: ScaffoldState = rememberScaffoldState()
|
||||
val showLabelsSelectionSheet: Boolean by libraryViewModel.showLabelsSelectionSheetLiveData.observeAsState(false)
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@ -67,6 +69,13 @@ fun LibraryView(
|
||||
}
|
||||
}
|
||||
|
||||
libraryViewModel.snackbarMessage?.let {
|
||||
coroutineScope.launch {
|
||||
scaffoldState.snackbarHostState.showSnackbar(it)
|
||||
libraryViewModel.clearSnackbarMessage()
|
||||
}
|
||||
}
|
||||
|
||||
ModalBottomSheetLayout(
|
||||
sheetBackgroundColor = Color.Transparent,
|
||||
sheetState = modalBottomSheetState,
|
||||
@ -76,6 +85,7 @@ fun LibraryView(
|
||||
}
|
||||
) {
|
||||
Scaffold(
|
||||
scaffoldState = scaffoldState,
|
||||
topBar = {
|
||||
LibraryNavigationBar(
|
||||
savedItemViewModel = libraryViewModel,
|
||||
@ -164,6 +174,7 @@ fun LibraryViewContent(libraryViewModel: LibraryViewModel, modifier: Modifier) {
|
||||
.fillMaxSize()
|
||||
.pullRefresh(pullRefreshState)
|
||||
) {
|
||||
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
verticalArrangement = Arrangement.Top,
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
package app.omnivore.omnivore.ui.library
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.*
|
||||
import app.omnivore.omnivore.*
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
@ -36,6 +41,9 @@ class LibraryViewModel @Inject constructor(
|
||||
private var searchIdx = 0
|
||||
private var receivedIdx = 0
|
||||
|
||||
var snackbarMessage by mutableStateOf<String?>(null)
|
||||
private set
|
||||
|
||||
// Live Data
|
||||
private var itemsLiveDataInternal = dataService.db.savedItemDao().filteredLibraryData(
|
||||
allowedArchiveStates = listOf(0),
|
||||
@ -77,6 +85,10 @@ class LibraryViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun clearSnackbarMessage() {
|
||||
snackbarMessage = null
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
cursor = null
|
||||
librarySearchCursor = null
|
||||
@ -285,27 +297,39 @@ class LibraryViewModel @Inject constructor(
|
||||
fun updateSavedItemLabels(savedItemID: String, labels: List<SavedItemLabel>) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val synced = labels.filter { it.serverSyncStatus == ServerSyncStatus.IS_SYNCED.rawValue }
|
||||
val unsynced = labels.filter { it.serverSyncStatus != ServerSyncStatus.IS_SYNCED.rawValue }
|
||||
val syncedLabels = labels.filter { it.serverSyncStatus == ServerSyncStatus.IS_SYNCED.rawValue }
|
||||
val unsyncedLabels = labels.filter { it.serverSyncStatus != ServerSyncStatus.IS_SYNCED.rawValue }
|
||||
|
||||
var labelIds = mutableListOf<String>()
|
||||
labelIds.addAll(synced.map { it.savedItemLabelId })
|
||||
|
||||
unsynced.forEach { label ->
|
||||
var labelCreationError = false
|
||||
val createdLabels = unsyncedLabels.mapNotNull { label ->
|
||||
val result = networker.createNewLabel(CreateLabelInput(
|
||||
name = label.name,
|
||||
color = presentIfNotNull(label.color),
|
||||
description = presentIfNotNull(label.labelDescription),
|
||||
))
|
||||
result?.let {
|
||||
labelIds.add(it.id)
|
||||
SavedItemLabel(
|
||||
savedItemLabelId = result.id,
|
||||
name = result.name,
|
||||
color = result.color,
|
||||
createdAt = result.createdAt.toString(),
|
||||
labelDescription = result.description,
|
||||
serverSyncStatus = ServerSyncStatus.IS_SYNCED.rawValue
|
||||
)
|
||||
} ?: run {
|
||||
labelCreationError = true
|
||||
null
|
||||
}
|
||||
}
|
||||
val input = SetLabelsInput(labelIds = labels.map { it.savedItemLabelId }, pageId = savedItemID)
|
||||
|
||||
dataService.db.savedItemLabelDao().insertAll(createdLabels)
|
||||
|
||||
val allLabels = syncedLabels + createdLabels
|
||||
|
||||
val input = SetLabelsInput(labelIds = allLabels.map { it.savedItemLabelId }, pageId = savedItemID)
|
||||
val networkResult = networker.updateLabelsForSavedItem(input)
|
||||
|
||||
// TODO: assign a server sync status to these
|
||||
val crossRefs = labels.map {
|
||||
val crossRefs = allLabels.map {
|
||||
SavedItemAndSavedItemLabelCrossRef(
|
||||
savedItemLabelId = it.savedItemLabelId,
|
||||
savedItemId = savedItemID
|
||||
@ -318,6 +342,12 @@ class LibraryViewModel @Inject constructor(
|
||||
// Add back the current labels
|
||||
dataService.db.savedItemAndSavedItemLabelCrossRefDao().insertAll(crossRefs)
|
||||
|
||||
if (!networkResult || labelCreationError) {
|
||||
snackbarMessage = "Unable to set labels"
|
||||
} else {
|
||||
snackbarMessage = "Labels updated"
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
handleFilterChanges()
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ fun SavedItemCard(savedItemViewModel: SavedItemViewModel, savedItem: SavedItemWi
|
||||
text = savedItem.savedItem.title,
|
||||
style = TextStyle(
|
||||
fontSize = 18.sp,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
),
|
||||
maxLines = 2,
|
||||
|
||||
Reference in New Issue
Block a user