From 49af48a6950f832436a2bdda6eb29afc8024fc70 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 15 May 2023 14:59:22 +0800 Subject: [PATCH] Set labels on creation --- .../ui/components/LabelsSelectionSheet.kt | 2 +- .../omnivore/ui/library/LibraryView.kt | 19 +++++-- .../omnivore/ui/library/LibraryViewModel.kt | 50 +++++++++++++++---- .../ui/savedItemViews/SavedItemCard.kt | 1 + 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt index 6d64c6501..468d08306 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt @@ -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 diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt index 631ec9418..c8a268a72 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt @@ -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, diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt index d08496186..ce6334c5d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt @@ -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(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) { 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() - 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() } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt index 3abedc409..6e60e0d77 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt @@ -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,