Skip to content

Merge upstream AnkiDroid - #64

Open
float3 wants to merge 48 commits into
float3:ankiquestfrom
ankidroid:main
Open

float3 wants to merge 48 commits into
float3:ankiquestfrom
ankidroid:main

Conversation

@float3

@float3 float3 commented Oct 15, 2026

Copy link
Copy Markdown
Owner

10 new commits from ankidroid/Anki-Android main.

Merge with a merge commit, never squash or rebase, so ankiquest keeps upstream's history.

If this conflicts, merge ankidroid/Anki-Android main into a branch from ankiquest, resolve there, and merge that branch instead; this pull request then shows as merged.

criticalAY and others added 10 commits October 15, 2026 00:57
Android clears an app's cache when storage runs low, which could delete
a recording while it was still being made. Recordings now go to
noBackupFilesDir, which isn't cleared or backed up.

Assisted-by: Claude Opus 5.5
The system no longer clears recordings left behind when the app is
killed, so recordings older than 7 days are deleted at startup, like
the multimedia argument files.

Assisted-by: Claude Opus 5.5
Fixes 22420

Assisted-by: GPT-6-Astra default
Workaround before we fix 14796

Assisted-by: GPT-6-Astra xhigh
FileProvider under Robolectric/AndroidX was Unix-only. This makes it work for Windows

Use openInputStreamSafe for both reads to satisfy UnsafeOpenInputStream lint.

Prep for 14222

Assisted-by: GPT-6-Astra xhigh
Assisted-by: GPT-6.1-Sol high
So the Gallery selection can reuse it

Part of 22499

Assisted-by: GPT-6-Astra xhigh
Open the Gallery before the image editor, so cancellation goes
directly back to the Note Editor.

`NoteEditorGalleryPicker` maintains state and results, passing on the URI
to the editor.

Fixes 22499

Assisted-by: GPT-6-Astra xhigh
The non-nosuggest field could have been focused first, before
autofocus occurred asynchronously

Part of 22060
Partially fixes 22483

Assisted-by: GPT-6-Astra default
In the same style as the legacy reviewer

Part of 22060

Assisted-by: GPT-6-Astra default

� Conflicts:
�	AnkiDroid/src/test/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragmentTest.kt
We picked a name, inserted into the collection, then used
the name in the HTML.

This could be wrong, as the backend could normalize/rename a media file

Assisted-by: GPT-6-Astra default
@github-actions

Copy link
Copy Markdown

Snapshot diff report vs ankiquest. Open screenshot-diff for diffs.

  • AddEditReminderDialogScreenshotTest: 1 change
  • ChangeNoteTypeDialogScreenshotTest: 26 changes
  • CollectionTooLargeScreenshotTest: 1 change
  • DeckPickerScreenshotTest: 10 changes
  • DeckPickerTabletScreenshotTest: 2 changes
  • LocaleSelectionDialogScreenshotTest: 2 changes
  • MultimediaScreenshotTest: 5 changes
  • NavigationDrawerScreenshotTest: 2 changes
  • NoteEditorScreenshotTest: 2 changes
  • PreferencesScreenshotTest: 2 changes
  • PreviewerScreenshotTest: 1 change
  • ReviewRemindersScreenshotTest: 5 changes
  • SortOrderBottomSheetFragmentScreenshotTest: 3 changes
  • StudyScreenScreenshotTest: 6 changes
  • TagsDialogScreenshotTest: 1 change
  • TemplatePreviewerScreenshotTest: 1 change
All 70 changed screenshots

AddEditReminderDialogScreenshotTest

  • delete_confirmation_dialog_compare.png

ChangeNoteTypeDialogScreenshotTest

  • desktop_fields_fit_viewport_compare.png
  • desktop_gesture_navigation_compare.png
  • desktop_landscape_compare.png
  • desktop_long_note_type_names_large_text_landscape_compare.png
  • desktop_long_note_type_names_large_text_narrow_portrait_compare.png
  • desktop_many_fields_large_text_landscape_compare.png
  • desktop_many_fields_scrolled_to_bottom_compare.png
  • desktop_many_templates_large_text_landscape_compare.png
  • desktop_many_templates_scrolled_to_bottom_compare.png
  • desktop_portrait_compare.png
  • desktop_portrait_cutout_compare.png
  • desktop_templates_fit_viewport_compare.png
  • desktop_templates_tab_large_text_compare.png
  • fields_fit_viewport_compare.png
  • gesture_navigation_compare.png
  • landscape_compare.png
  • long_note_type_names_large_text_landscape_compare.png
  • long_note_type_names_large_text_narrow_portrait_compare.png
  • many_fields_large_text_landscape_compare.png
  • many_fields_scrolled_to_bottom_compare.png
  • many_templates_large_text_landscape_compare.png
  • many_templates_scrolled_to_bottom_compare.png
  • portrait_compare.png
  • portrait_cutout_compare.png
  • templates_fit_viewport_compare.png
  • templates_tab_large_text_compare.png

CollectionTooLargeScreenshotTest

  • collection_too_large_dialog_compare.png

DeckPickerScreenshotTest

  • deck_list_after_dismissing_create_deck_dialog_compare.png
  • edgeToEdge_30_decks_compare.png
  • hierarchy_lines_collapsed_compare.png
  • hierarchy_lines_compare.png
  • hierarchy_lines_deep_nesting_compare.png
  • hierarchy_lines_many_siblings_compare.png
  • keyboard_open_scrolled_to_bottom_compare.png
  • keyboard_studied_line_overlaying_deck_name_compare.png
  • snackbar_keyboard_closed_compare.png
  • snackbar_keyboard_open_compare.png

DeckPickerTabletScreenshotTest

  • 30_decks_tablet_compare.png
  • keyboard_open_compare.png

LocaleSelectionDialogScreenshotTest

  • landscape_compare.png
  • portrait_compare.png

MultimediaScreenshotTest

  • image_editor_camera_compare.png
  • image_editor_compare.png
  • image_editor_drawing_compare.png
  • image_editor_error_compare.png
  • landscape_compare.png

NavigationDrawerScreenshotTest

  • navigationDrawer_compare.png
  • sideNavigationBar_compare.png

NoteEditorScreenshotTest

  • tablet_compare.png
  • tablet_keyboard_compare.png

PreferencesScreenshotTest

  • AnkiquestStudySettingsFragment_compare.png
  • SwitchProfilesFragment_compare.png

PreviewerScreenshotTest

  • base_compare.png

ReviewRemindersScreenshotTest

  • studyOptionsFragmentHost_scheduleReminders_compare.png
  • studyOptionsFragmentHost_systemBars_compare.png
  • studyOptionsFragmentHost_systemBars_scrolledToEnd_compare.png
  • studyOptionsFragmentHost_troubleshooting_compare.png
  • studyOptionsFragmentHost_troubleshooting_systemBars_compare.png

SortOrderBottomSheetFragmentScreenshotTest

  • landscape_compare.png
  • landscape_scrolled_to_bottom_compare.png
  • landscape_scrollshot_compare.png

StudyScreenScreenshotTest

  • bar=BOTTOM_frame=CARDbttns=false_compare.png
  • bar=BOTTOM_frame=CARDbttns=true_compare.png
  • bar=NONE_frame=CARDbttns=false_compare.png
  • bar=NONE_frame=CARDbttns=true_compare.png
  • bar=TOP_frame=CARDbttns=false_compare.png
  • bar=TOP_frame=CARDbttns=true_compare.png

TagsDialogScreenshotTest

  • empty_tags_compare.png

TemplatePreviewerScreenshotTest

  • base_compare.png

criticalAY and others added 18 commits October 15, 2026 10:41
The Deck Picker kept its full-size background bitmap for as long as
the activity lived, even while reviewing or in the background. Load
it when the screen starts and drop it when it stops, still reporting
a broken image only once.

Fixes 22514

Co-authored-by: Mike Hardy <github@mikehardy.net>
Assisted-by: Claude Opus 5.5
Rename request key constants while preserving their string values.

Part of 22409

Assisted-by: GPT-6-Astra default
Fixes 22409

Assisted-by: GPT-6-Astra default
Dependency PRs compared their screenshots against an old baseline,
because one was only stored when the "Dependency updates" PR ran.
Store one on every push to dependency-updates, so each bump only
shows its own changes.

Compare now only takes a baseline from a push, as that PR's own
run screenshots its merge into main.

Fixes 21071

Assisted-by: Claude Opus 5.5
Publish runs didn't say which release they made, so finding the latest
alpha, beta or production release meant opening the logs. Add the
release name, a link to it and whether it was public to the summary.

Fixes 22519

Assisted-by: Claude Opus 5.5
The test mocked the whole app to hide the profile manager. ACRA calls
the app from a background thread at startup, so a call landing while
MockK swapped the mock failed with "can't find stub". Set the profile
manager directly instead.

Fixes 22527

Assisted-by: Claude Opus 5.5
HTTP(S) links were caught in the GHSL-2026-085 check
for external app opening.

A user should not need to relax genuine security measures
to open links.

Fixes 22490
66efa71

Assisted-by: GPT-6-Astra default
Assisted-by: GPT-6-Astra xhigh
Pass HTTP(S) links to a native App Link handler, if one is available.
This will work if no browser is installed.

Assisted-by: GPT-6-Astra xhigh
Show an error message, rather than falling back to the WebView to handle
the navigation.

Assisted-by: GPT-6-Astra xhigh
Catch `Exception`, matching the new study screen.

Assisted-by: GPT-6-Astra xhigh
Assisted-by: GPT-6-Astra xhigh
Assisted-by: GPT-6-Astra default
Prep for a new Note Editor:

* Jetpack Compose
* Wrapping a custom 'fields' component from the AnkiDroid backend (based on Anki's Svelte fields)

Part of 1377
Part of 21353

Assisted-by: GPT-6-Astra default
Assisted-by: GPT-6-Astra xhigh
* `:note-editor`
* `:common:android` - chevron

Assisted-by: GPT-6-Astra xhigh
Assisted-by: GPT-6-Astra xhigh
Assisted-by: GPT-6-Astra default
`AnkiDroidPreview` now provides all app themes via `AnkiDroidThemeProvider`

Assisted-by: GPT-6-Astra xhigh
Part of 22410

Assisted-by: GPT-6-Astra default
david-allison and others added 20 commits October 15, 2026 16:38
Part of 22410

Assisted-by: GPT-6-Astra default
Assisted-by: GPT-6-Astra default
Prep for a `FullSync` class

Prep for 22313

Assisted-by: GPT-6-Astra xhigh
`serverUsn` meant two things:

* USN was not available/known
* A media sync was not requested

This partially documents this differences

Prep for 22313

Assisted-by: GPT-6-Astra xhigh
The back stack is now only cleared if closing a side panel.

So initialization and refreshing will not clear an import dialog.

Fixes 22538

Assisted-by: GPT-6-Astra default
Adding a card type from one that was just added said "This will
create 0 cards", since the count came from the current card type's
existing cards. Count the notes the new card type would make a card
for instead, so the dialog matches what gets created.

Fixes 20093

Assisted-by: Claude Opus 5.5
Wait for submitted checks and layout - done on a background thread

Assisted-by: GPT-6-Astra default
Wait for playback to finish before asserting

Assisted-by: GPT-6-Astra default
Full uploads and downloads no longer run the media sync in the backend,
They now run through WorkManager so we can apply network restrictions.

Fixes 22313

Assisted-by: GPT-6-Astra default
Assisted-by: GPT-6-Astra xhigh
Currently it shows as 'success'; technically true, but it
makes it seem like we publish more than we actually do.

Fixes 22449

Assisted-by: GPT-6-Astra default
The alpha5 release pushed its version bump after the Play upload, which
takes about ten minutes. Main moved in the meantime, the push was
rejected, and the script carried on, so main never got the bump and the
next release reused alpha5's version code.

Push the bump right after committing, and stop if that fails, before
anything is published. Only the tag waits for Play to accept the build.

Fixes 22547

Assisted-by: Claude Opus 5.5
Rename the intent extra key constants that didn't follow the EXTRA_
convention. The key strings stay the same.

Issue 22405

Assisted-by: Claude Opus 5.5
Constants used as intent extra keys now need the EXTRA_ prefix, so new
keys follow the same naming as the rest.

Fixes 22405

Assisted-by: Claude Opus 5.5
A failed tag push was ignored, and the GitHub release was created
without checking the tag, so a release could end up on an old tag or
on a new one gh made from main. Stop if the tag push fails, and let gh
refuse to create a release for a tag that isn't on GitHub.

Fixes 22555

Assisted-by: Claude Opus 5.5
BUILD_TIME falls back to the time Gradle configures the build, so every
Gradle run that asked for different tasks or flags got a new BuildConfig
and rebuilt the release APKs, R8 included. The emulator tests rebuilt
what Warm Gradle Cache had just built, with the emulator already
running. Use one build time for every Gradle run in the job, as
release.sh does for a release.

Issue 22535

Assisted-by: Claude Opus 5.5
The smoke test was the last line of the emulator test script. When its
build failed after every emulator test had passed, the job only said
"The process '/usr/bin/sh' failed with exit code 1" and the test report
listed no failures.

Build it in a step without the emulator, then boot the emulator in a
separate step to run it, so a failure names the step that broke.

Issue 22535

Assisted-by: Claude Opus 5.5
Tablet-only bugs kept slipping through because every emulator job runs
on a small phone. Scheduled and manual runs now add one Pixel Tablet
job. Per-change runs are unchanged, and the phone job keeps its name
because it is a required check.

Like the 16 KB emulator, the tablet skips the AVD cache and always gets
the warm-up. Artifact names now include the device so the two jobs
don't clash.

Fixes 22541

Assisted-by: Claude Opus 5.5
The test buried a card by hand, but the study options counts never
include manually buried cards. It only passed because the deck tree
unburied the card partway through the refresh, so on a run where
something else asked for the deck tree first, the count was 0. Count a
buried sibling instead, which is what the screen shows.

Fixes 22558

Assisted-by: Claude Opus 5.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants