diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt index 26fac1a189ae..2ddcf2665a1b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt @@ -242,3 +242,13 @@ fun Card.totalLapsesOfNote(col: Collection) = NoteService.totalLapses(col, note( fun Card.totalReviewsForNote(col: Collection) = NoteService.totalReviews(col, note(col)) fun Card.avgIntervalOfNote(col: Collection) = NoteService.avgInterval(col, note(col)) + +suspend fun isBuryNoteAvailable(card: Card): Boolean { + return withCol { + db.queryScalar( + "select 1 from cards where nid = ? and id != ? and queue >= " + Consts.QUEUE_TYPE_NEW + " limit 1", + card.nid, + card.id + ) == 1 + } +} diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt index 7e3340b7fe5d..939a0351f0bd 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt @@ -112,6 +112,8 @@ class ReviewerFragment : override fun onMenuItemClick(item: MenuItem): Boolean { when (item.itemId) { R.id.action_add_note -> launchAddNote() + R.id.action_bury_card -> viewModel.buryCard() + R.id.action_bury_note -> viewModel.buryNote() R.id.action_card_info -> launchCardInfo() R.id.action_delete -> viewModel.deleteNote() R.id.action_edit -> launchEditNote() @@ -167,6 +169,19 @@ class ReviewerFragment : markItem.setTitle(R.string.menu_mark_note) } } + + val buryItem = menu.findItem(R.id.action_bury) + val buryCardItem = menu.findItem(R.id.action_bury_card) + viewModel.canBuryNoteFlow.flowWithLifecycle(lifecycle) + .collectLatestIn(lifecycleScope) { canBuryNote -> + if (canBuryNote) { + buryItem.isVisible = true + buryCardItem.isVisible = false + } else { + buryItem.isVisible = false + buryCardItem.isVisible = true + } + } } private val noteEditorLauncher = diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerViewModel.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerViewModel.kt index 1d1dd253a747..8ea2ae0c29e2 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerViewModel.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerViewModel.kt @@ -35,6 +35,8 @@ import com.ichi2.anki.previewer.CardViewerViewModel import com.ichi2.anki.previewer.NoteEditorDestination import com.ichi2.anki.reviewer.CardSide import com.ichi2.anki.servicelayer.NoteService +import com.ichi2.anki.servicelayer.isBuryNoteAvailable +import com.ichi2.anki.servicelayer.isSuspendNoteAvailable import com.ichi2.libanki.note import com.ichi2.libanki.sched.CurrentQueueState import com.ichi2.libanki.undoableOp @@ -59,6 +61,8 @@ class ReviewerViewModel(cardMediaPlayer: CardMediaPlayer) : var isQueueFinishedFlow = MutableSharedFlow() val isMarkedFlow = MutableStateFlow(false) val actionFeedbackFlow = MutableSharedFlow() + val canBuryNoteFlow = MutableStateFlow(true) + val canSuspendNoteFlow = MutableStateFlow(true) private val server = AnkiServer(this).also { it.start() } private val stateMutationKey = TimeManager.time.intTimeMS().toString() @@ -167,6 +171,28 @@ class ReviewerViewModel(cardMediaPlayer: CardMediaPlayer) : } } + fun buryCard() { + launchCatchingIO { + val cardId = currentCard.await().id + val noteCount = undoableOp { + sched.buryCards(cids = listOf(cardId)) + }.count + actionFeedbackFlow.emit(CollectionManager.TR.studyingCardsBuried(noteCount)) + updateCurrentCard() + } + } + + fun buryNote() { + launchCatchingIO { + val noteId = currentCard.await().nid + val noteCount = undoableOp { + sched.buryNotes(nids = listOf(noteId)) + }.count + actionFeedbackFlow.emit(CollectionManager.TR.studyingCardsBuried(noteCount)) + updateCurrentCard() + } + } + /* ********************************************************************************************* *************************************** Internal methods *************************************** ********************************************************************************************* */ @@ -249,9 +275,12 @@ class ReviewerViewModel(cardMediaPlayer: CardMediaPlayer) : return } - currentCard = CompletableDeferred(state.topCard) + val card = state.topCard + currentCard = CompletableDeferred(card) showQuestion() loadAndPlaySounds(CardSide.QUESTION) + canBuryNoteFlow.emit(isBuryNoteAvailable(card)) + canSuspendNoteFlow.emit(isSuspendNoteAvailable(card)) } // TODO diff --git a/AnkiDroid/src/main/res/menu/reviewer2.xml b/AnkiDroid/src/main/res/menu/reviewer2.xml index 1bf5f20cdabd..98dc03467555 100644 --- a/AnkiDroid/src/main/res/menu/reviewer2.xml +++ b/AnkiDroid/src/main/res/menu/reviewer2.xml @@ -46,4 +46,23 @@ android:title="@string/menu_delete_note" android:icon="@drawable/ic_delete_white" app:showAsAction="never"/> + + + + + + + \ No newline at end of file