-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Introduce ChangeNoteType Dialog #18602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -56,6 +56,7 @@ import com.ichi2.anki.libanki.Card | |||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.CardId | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.CardType | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.DeckId | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.NoteId | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.QueueType | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.QueueType.ManuallyBuried | ||||||||||||||||||||||||||||||||||||
| import com.ichi2.anki.libanki.QueueType.SiblingBuried | ||||||||||||||||||||||||||||||||||||
|
|
@@ -267,6 +268,8 @@ class CardBrowserViewModel( | |||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
| val flowOfCardStateChanged = MutableSharedFlow<Unit>() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| val flowOfChangeNoteType = MutableSharedFlow<ChangeNoteTypeResponse>() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * Opens a prompt for the user to input a saved search name | ||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||
|
|
@@ -284,6 +287,19 @@ class CardBrowserViewModel( | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| suspend fun queryAllSelectedNoteIds() = selectedRows.queryNoteIds(this.cardsOrNotes) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| fun requestChangeNoteType() = | ||||||||||||||||||||||||||||||||||||
| viewModelScope.launch { | ||||||||||||||||||||||||||||||||||||
| val noteIds = queryAllSelectedNoteIds() | ||||||||||||||||||||||||||||||||||||
| Timber.i("requestChangeNoteType: querying %d selected notes", noteIds.size) | ||||||||||||||||||||||||||||||||||||
| flowOfChangeNoteType.emit( | ||||||||||||||||||||||||||||||||||||
| when { | ||||||||||||||||||||||||||||||||||||
| noteIds.isEmpty() -> ChangeNoteTypeResponse.NoSelection | ||||||||||||||||||||||||||||||||||||
| !noteIds.allOfSameNoteType() -> ChangeNoteTypeResponse.MixedSelection | ||||||||||||||||||||||||||||||||||||
| else -> ChangeNoteTypeResponse.ChangeNoteType.from(noteIds) | ||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @VisibleForTesting | ||||||||||||||||||||||||||||||||||||
| internal suspend fun queryAllCardIds() = cards.queryCardIds() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
@@ -1351,6 +1367,25 @@ class CardBrowserViewModel( | |||||||||||||||||||||||||||||||||||
| SELECT_NONE, | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| sealed interface ChangeNoteTypeResponse { | ||||||||||||||||||||||||||||||||||||
| data object NoSelection : ChangeNoteTypeResponse | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| data object MixedSelection : ChangeNoteTypeResponse | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @ConsistentCopyVisibility | ||||||||||||||||||||||||||||||||||||
Haz3-jolt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
| data class ChangeNoteType private constructor( | ||||||||||||||||||||||||||||||||||||
| val noteIds: List<NoteId>, | ||||||||||||||||||||||||||||||||||||
| ) : ChangeNoteTypeResponse { | ||||||||||||||||||||||||||||||||||||
| companion object { | ||||||||||||||||||||||||||||||||||||
| @CheckResult | ||||||||||||||||||||||||||||||||||||
| fun from(ids: List<NoteId>): ChangeNoteType { | ||||||||||||||||||||||||||||||||||||
| require(ids.isNotEmpty()) { "a non-empty list must be provided" } | ||||||||||||||||||||||||||||||||||||
| return ChangeNoteType(ids.distinct()) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * @param wasBuried `true` if all cards were buried, `false` if unburied | ||||||||||||||||||||||||||||||||||||
| * @param count the number of affected cards | ||||||||||||||||||||||||||||||||||||
|
|
@@ -1515,6 +1550,16 @@ sealed class RepositionCardsRequest { | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| fun BrowserColumns.Column.getLabel(cardsOrNotes: CardsOrNotes): String = if (cardsOrNotes == CARDS) cardsModeLabel else notesModeLabel | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||
| * Whether the provided notes all have the same the same [note type][com.ichi2.anki.libanki.NoteTypeId] | ||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
| private suspend fun List<NoteId>.allOfSameNoteType(): Boolean { | ||||||||||||||||||||||||||||||||||||
david-allison marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
| val noteIds = this | ||||||||||||||||||||||||||||||||||||
| return withCol { notetypes.nids(getNote(noteIds.first()).noteTypeId) }.toSet().let { set -> | ||||||||||||||||||||||||||||||||||||
| noteIds.all { set.contains(it) } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1554
to
+1559
|
||||||||||||||||||||||||||||||||||||
| * Whether the provided notes all have the same the same [note type][com.ichi2.anki.libanki.NoteTypeId] | |
| */ | |
| private suspend fun List<NoteId>.allOfSameNoteType(): Boolean { | |
| val noteIds = this | |
| return withCol { notetypes.nids(getNote(noteIds.first()).noteTypeId) }.toSet().let { set -> | |
| noteIds.all { set.contains(it) } | |
| * Whether the provided notes all have the same [note type][com.ichi2.anki.libanki.NoteTypeId]. | |
| * | |
| * Performance: This function previously loaded all note IDs of the first note's type, which could be | |
| * expensive for large collections. It now fetches the note type for each provided note ID and checks | |
| * if they are all the same. This is more efficient when the number of selected notes is small. | |
| */ | |
| private suspend fun List<NoteId>.allOfSameNoteType(): Boolean { | |
| if (isEmpty()) return true | |
| return withCol { | |
| val firstType = getNote(this@allOfSameNoteType.first()).noteTypeId | |
| this@allOfSameNoteType.all { getNote(it).noteTypeId == firstType } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bad suggestion
Uh oh!
There was an error while loading. Please reload this page.