Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ open class CardBrowser :
launchCatchingTask {
if (viewModel.isInMultiSelectMode) {
viewModel.toggleRowSelection(id)
viewModel.saveScrollingState(id)
viewModel.oldCardTopOffset = calculateTopOffset(viewModel.lastSelectedPosition)
} else {
val cardId = viewModel.queryDataForCardEdit(id)
openNoteEditorForCard(cardId)
Expand All @@ -357,6 +359,8 @@ open class CardBrowser :
if (viewModel.isInMultiSelectMode && viewModel.lastSelectedId != null) {
viewModel.selectRowsBetween(viewModel.lastSelectedId!!, id)
} else {
viewModel.saveScrollingState(id)
viewModel.oldCardTopOffset = calculateTopOffset(viewModel.lastSelectedPosition)
viewModel.toggleRowSelection(id)
}
}
Expand Down Expand Up @@ -509,6 +513,7 @@ open class CardBrowser :
// Due to the ripple on long press, we set padding
browserColumnHeadings.updatePaddingRelative(start = 48.dp)
multiSelectOnBackPressedCallback.isEnabled = true
autoScrollTo(viewModel.lastSelectedPosition, viewModel.oldCardTopOffset)
} else {
Timber.d("end multiselect mode")
// update adapter to remove check boxes
Expand All @@ -517,6 +522,7 @@ open class CardBrowser :
actionBarTitle.visibility = View.GONE
browserColumnHeadings.updatePaddingRelative(start = 0.dp)
multiSelectOnBackPressedCallback.isEnabled = false
autoScrollTo(viewModel.lastSelectedPosition, viewModel.oldCardTopOffset)
}
// reload the actionbar using the multi-select mode actionbar
invalidateOptionsMenu()
Expand Down Expand Up @@ -1865,6 +1871,20 @@ open class CardBrowser :
viewModel: CardBrowserViewModel,
): Intent = NoteEditorLauncher.AddNoteFromCardBrowser(viewModel).getIntent(context)
}

private fun calculateTopOffset(cardPosition: Int): Int {
val layoutManager = cardsListView.layoutManager as LinearLayoutManager
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
val view = cardsListView.getChildAt(cardPosition - firstVisiblePosition)
return view?.top ?: 0
}

private fun autoScrollTo(
newPosition: Int,
offset: Int,
) {
(cardsListView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(newPosition, offset)
}
}

suspend fun searchForRows(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class CardBrowserViewModel(
private val manualInit: Boolean = false,
) : ViewModel(),
SharedPreferencesProvider by preferences {
var lastSelectedPosition: Int = 0
var oldCardTopOffset: Int = 0

// TODO: abstract so we can use a `Context` and `pref_display_filenames_in_browser_key`
val showMediaFilenames = sharedPrefs().getBoolean("card_browser_show_media_filenames", false)

Expand Down Expand Up @@ -1030,6 +1033,12 @@ class CardBrowserViewModel(
val error: String,
) : SearchState
}

fun saveScrollingState(id: CardOrNoteId) {
cards.indexOf(id).takeIf { it >= 0 }?.let { position ->
lastSelectedPosition = position
}
}
}

enum class SaveSearchResult {
Expand Down
17 changes: 17 additions & 0 deletions AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,23 @@ class CardBrowserTest : RobolectricTest() {
assertThat(cardBrowser.viewModel.rowCount, equalTo(3))
}

@Test
fun checkIfScrollPositionSavedOnLongPress() =
runTest {
val cardBrowser = getBrowserWithNotes(10)
cardBrowser.longClickRowAtPosition(5)
assertThat(cardBrowser.viewModel.lastSelectedPosition, equalTo(5))
}

@Test
fun checkIfScrollPositionSavedOnTap() =
runTest {
val cardBrowser = getBrowserWithNotes(10)
cardBrowser.longClickRowAtPosition(1)
cardBrowser.clickRowAtPosition(5)
assertThat(cardBrowser.viewModel.lastSelectedPosition, equalTo(5))
}

@Test
fun `column spinner positions are set if no preferences exist`() =
runBlocking {
Expand Down
Loading