Repository navigation
Merge upstream AnkiDroid main (2026-10-30) - #73
Merged
Merged
Conversation
…yIfNoReviews `wasScopeReviewedToday` only matched `cards.did` against the reminder's deck, so reviews of cards in a subdeck, or of cards temporarily moved into a filtered deck (home deck in `odid`), were ignored and the reminder still fired. The due count in the notification already includes subdecks. Check the deck and its children against both `did` and `odid`. Fixes 22848 Assisted-by: Claude Opus 5.5
Assisted-by: GPT-6.1 Terra medium
Backend 0.1.75 moved the Android adapters, native libraries, and web assets into `rsdroid-android`. See https://redirect.github.com/ankidroid/Anki-Android-Backend/pull/767 Assisted-by: GPT-6-Astra max
The publish job sometimes ran out of heap while packaging a universal APK, after Play already had the build, so no GitHub release was made. release.sh restarts Gradle for every build, so raise the heap from 3 GB to 4 GB in the Gradle user home, where each new daemon picks it up. Fixes 22855 Assisted-by: Claude Opus 5.5
the class should be as generic as possible. Its implementers should be the ones handling their own listeners Currently, CongratsPage deals with all of that, so the listener isn't necessary Assisted-by: Claude Opus 5.5
Importing from the device storage failed on phones where the system External Storage app has lost "All files access", and each failure was sent as a crash report. We now read the picked file through MediaStore, which accepts the access we already have. Fixes 22822 Assisted-by: Claude Opus 5.5
Rebuild, Empty and Unbury acted on the collection's selected deck, while the panel's other actions use the deck it shows. If the panel was out of date, for example after a failed refresh, they could act on a deck that wasn't shown. They now act on the shown deck. Assisted-by: Claude Opus 5.5
Only withProgressDialog reads and writes it, so it no longer needs to live on AnkiDroidApp. Assisted-by: Claude Opus 5.5
withProgressDialog and the progress observer both use it, and it only needs a Window. The package is unchanged, so callers are too. Assisted-by: Claude Opus 5.5
withProgressDialog is its only user, and the attributes and dimension it reads already live there. CustomButtonBarButtonStyle moves with it, since only this style uses it. Assisted-by: Claude Opus 5.5
Widgets checked storage access on the main thread before every update. That check can wait on Android's storage service, for example at boot while an SD card is being mounted, which caused an ANR. Fixes 22825 Assisted-by: Claude Opus 5.5
ProfileManager.wrap gives a context the active profile's prefs and folders without creating the directories again. Default contexts come back unchanged. Assisted-by: Claude Opus 5.5
Activities were still reading and writing the Default profile's prefs and files. AnkiActivity and the intent handlers now wrap their base context for the active profile. Assisted-by: Claude Opus 5.5
Each public method of SafeWebViewLayout had its own
`if (warnIfNotActive("name")) return` line before using `webView`.
The guard was easy to forget, the method-name strings could drift on
rename, and each return type needed its own default.
`activeWebView` returns the inner WebView only while it is active, so
the check and the access are one expression and defaults come from
`?:`. Behavior is unchanged, except that the warning no longer names
the method.
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
zoomBy was added after the destroyed-state guard and called the inner WebView directly, so ReviewerFragment.resetZoom() could reach a destroyed WebView, which the WebView.destroy() contract forbids. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
The raw reference may point at a destroyed WebView. Naming it `uncheckedWebView` makes direct use a visible choice, so new methods reach for `activeWebView` instead. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Both callers of recreateInnerWebView reach it only after onRenderProcessGone removed the terminated WebView from the layout, so the `parent == this` check never matched. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Extract findFragmentOrNull, which tryRecoverDestroyedWebViewIfNeeded also needs, and handle fragment and activity hosts with one implements-the-listener check instead of two copies. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Every implementation ignored the parameter and reconfigured through SafeWebViewLayout, which guards calls on a destroyed WebView. Dropping it removes the only way the raw WebView left the layout. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
CardViewerFragment, used by the reviewer and the previewer, was the only host calling destroy(), which only calls WebView.destroy(). Use safeDestroy() like every other host, so the WebView also stops loading, drops its clients and is removed from the layout. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
destroy() no longer has callers outside tests and repeated safeDestroy()'s destroyed-state handling. Remove it, and rename safeDestroy() to destroy(), like WebView.destroy(). Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
SafeWebViewLayout always passed a callback, so the WebView serialized and returned every script result even when the caller ignored it. Chromium skips that work when the callback is null. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
settings, scale and setAcceptThirdPartyCookies call into the WebView, which must be used on the main thread, like the other methods. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
The property kept its own copy of the style, which nothing read and which drifted from the WebView after a recreation. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Espresso could pick the activity window while a reminder dialog was still taking focus, then wait 10 s (RootViewWithoutFocusException), and a slow tap on the picker's mode button only showed its tooltip. Look in the dialog window and set the time on the picker directly. Assisted-by: Claude Opus 5.5
|
Snapshot diff report vs
All 1 changed screenshotsAnkiquestHomeScreenshotTest
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges the 27 commits on upstream AnkiDroid main since #69.
Merged cleanly. Upstream bumped the backend to 0.1.75 and the version to 2.26.0alpha10, refactored the WebView, routed activity storage through the active profile, and moved the progress dialog and touch blocking into
:common:android.AnkiDroid/build.gradle.kts,AnkiDroidApp.ktandlibs.versions.tomlchanged on both sides, in different places.ktlint,
assemblePlayDebugand the AnkiQuest unit tests pass in the Nix dev shell.