diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt index 1362ca9cd..285e0fe80 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt @@ -48,22 +48,13 @@ suspend fun DataService.createWebHighlight(jsonString: String) { } } -suspend fun DataService.createNoteHighlight(savedItemId: String, note: String) { +suspend fun DataService.createNoteHighlight(savedItemId: String, note: String): String { val shortId = UUID.randomUUID().toString() val createHighlightId = UUID.randomUUID().toString() -// val createHighlightParams = CreateHighlightParams( -// type = HighlightType.NOTE,, -// shortId = shortId, -// id = createHighlightId, -// quote = null, -// patch = null, -// articleId = null, -// annotation = note, -// ) withContext(Dispatchers.IO) { val highlight = Highlight( - type = "HIGHLIGHT", + type = "NOTE", highlightId = createHighlightId, shortId = shortId, quote = null, @@ -87,12 +78,12 @@ suspend fun DataService.createNoteHighlight(savedItemId: String, note: String) { db.savedItemAndHighlightCrossRefDao().insertAll(listOf(crossRef)) val newHighlight = networker.createHighlight(input = CreateHighlightParams( - type = HighlightType.HIGHLIGHT, - shortId = shortId, + type = HighlightType.NOTE, + articleId = savedItemId, id = createHighlightId, + shortId = shortId, quote = null, patch = null, - articleId = null, annotation = note, ).asCreateHighlightInput()) @@ -100,6 +91,8 @@ suspend fun DataService.createNoteHighlight(savedItemId: String, note: String) { db.highlightDao().update(it) } } + + return createHighlightId } suspend fun DataService.mergeWebHighlights(jsonString: String) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt index fc6baa8a2..691b15ecd 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt @@ -91,6 +91,10 @@ interface HighlightDao { @Query("SELECT * FROM highlight WHERE highlightId = :highlightId") fun findById(highlightId: String): Highlight? + // Server sync status is passed in here to work around Room compile-time query rules, but should always be NEEDS_UPDATE + @Query("UPDATE highlight SET annotation = :note, serverSyncStatus = :serverSyncStatus WHERE highlightId = :highlightId") + fun updateNote(highlightId: String, note: String, serverSyncStatus: Int = ServerSyncStatus.NEEDS_UPDATE.rawValue) + @Update fun update(highlight: Highlight) } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt index 626975ae3..2b3bcda91 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt @@ -23,6 +23,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.TextButton import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment @@ -36,6 +37,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -149,28 +151,31 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditArticl @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @Composable -fun EditNoteModal(onDismiss: (text: String) -> Unit) { +fun EditNoteModal(initialValue: String?, onDismiss: (save: Boolean, text: String?) -> Unit) { val focusRequester = remember { FocusRequester() } - val annotation = remember { mutableStateOf("") } + val annotation = remember { mutableStateOf(initialValue ?: "") } BottomSheetUI() { Scaffold( topBar = { - TopAppBar( - title = { Text("Edit Note") }, + CenterAlignedTopAppBar( + title = { Text("Note") }, modifier = Modifier.statusBarsPadding(), colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.background ), navigationIcon = { - IconButton(onClick = { - onDismiss(annotation.value) + TextButton(onClick = { + onDismiss(false, initialValue) }) { - Icon( - imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack, - modifier = Modifier, - contentDescription = "Back" - ) + Text(text = "Cancel") + } + }, + actions = { + TextButton(onClick = { + onDismiss(true, annotation.value) + }) { + Text(text = "Save") } } ) @@ -190,10 +195,6 @@ fun EditNoteModal(onDismiss: (text: String) -> Unit) { } } - BackHandler(enabled = true) { - onDismiss(annotation.value) - } - LaunchedEffect(Unit) { focusRequester.requestFocus() } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt index 22a795d2a..ce1dc43fc 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.liveData import androidx.lifecycle.map import app.omnivore.omnivore.DatastoreRepository import app.omnivore.omnivore.dataService.DataService +import app.omnivore.omnivore.dataService.createNoteHighlight import app.omnivore.omnivore.networking.Networker import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights import app.omnivore.omnivore.ui.library.SavedItemViewModel @@ -27,11 +28,11 @@ class NotebookViewModel @Inject constructor( println("this is an item: $item") return item?.let { item -> println("this is an item: $item") - val noteHighlight = item.highlights.first { it.type == "NOTE" } + val noteHighlight = item.highlights.firstOrNull { it.type == "NOTE" } noteHighlight?.let { - + dataService.db.highlightDao().updateNote(highlightId = noteHighlight.highlightId, note = note) } ?: run { - + dataService.createNoteHighlight(savedItemId, note) } return true } ?: false diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt index 01bb77603..7e7e99c1f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt @@ -233,11 +233,18 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, } BottomSheetState.ADDNOTE -> { webReaderParams?.let { params -> - EditNoteModal(onDismiss = { - coroutineScope.launch { - notebookViewModel.addArticleNote(savedItemId = params.item.savedItemId, note = it) + EditNoteModal( + initialValue = null, + onDismiss = { save, note -> + if (save && note != null) { + coroutineScope.launch { + notebookViewModel.addArticleNote( + savedItemId = params.item.savedItemId, + note = note + ) + } + } webReaderViewModel.setBottomSheet(BottomSheetState.NOTEBOOK) - } }) } }