Repository navigation
Merge upstream AnkiDroid - #57
Merged
Merged
Conversation
Part of 19572 Assisted-by: GPT-6
This enables `UnusedResources` and `StringFormatMatches` to run cross-module, which will be necessary when our strings move to `:common:android` Part of 21500 Assisted-by: Claude Fable 5
`sdkmanager` can fail with "Error on ZipFile unknown archive" before the emulator starts. Pre-install the emulator to work around this while upstream fixes the bug Fixes 21885 Related to https://redirect.github.com/ReactiveCircus/android-emulator-runner/issues/496 Assisted-by: GPT-6
This allows searching when tags are loading, or with an empty collection. Part of 10397 Assisted-by: GPT-6
In preparation for better handling of progress, errors and overlap protection. Part of 10397 Assisted-by: GPT-6
Stops an operation from clearing progress while another is running. This now ignores requests made while an operation is in progress (the UI should block operations when this occurs). * Remember the unfinished job * Check completion via 'isCompleted' * set the instance variable for the next job before running it * State is only modified for accepted requests Part of 10397 Assisted-by: GPT-6
e.g. a tag rename Part of 10397 Assisted-by: GPT-6
Part of 10397 Assisted-by: GPT-6
A screen rotation could hide a snackbar before a user had time to see it Part of 10397 Assisted-by: GPT-6
Gradle task validation failed when lint and jacocoUnitTestReport ran in one invocation because report tasks scanned all of build/ for coverage.
Assisted-by: GPT-6
RuntimeEnvironment.setQualifiers(+night) recreates ActivityThread leftovers (often DeckPicker), which flakes ThemesTest mid-suite. Add an after-test guard and dispose the current offenders. tearDown force-removes owned controllers only; clearAll would hide ActivityScenario leftovers from NoLiveRobolectricActivitiesRule. Preserve original test failures alongside leak reports via MultipleFailureException, and use a low Rule.order so the check runs outside other rules after their activity cleanup finishes. Dispose AppCompat delegates during leak cleanup, and report owned activity cleanup failures after remaining teardown finishes. Assisted-by: GPT-6 Co-authored-by: Cursor <cursoragent@cursor.com>
checkDependencies rejects setting WrongThread to informational while :common leaves that Android check disabled. Informational enables it without failing :common:lint. Co-authored-by: Cursor <cursoragent@cursor.com>
For a locale-only tag such as {{tts fr_FR:Front}}, voiceForTag fell
back on the first voice matching the language without checking
availability. Android can list voices flagged KEY_FEATURE_NOT_INSTALLED,
so an uninstalled voice could be chosen and fail on playback with
ERROR_NOT_INSTALLED_YET even when an installed voice for that language
was available.
The language fallback now prefers an installed voice, only settling for
an unavailable one when nothing else matches.
The fix and its tests come from David Allison's review suggestion,
generated with GPT-6.
Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com>
Assisted-by: GPT-6 [fix and tests]
An Activity can report `STARTED` after a `finish()` call: if a WebView renderer callback executed, if this opens a dialog, it crashes. In these exceptional cases, skip displaying the dialog. Fixes 6244 Assisted-by: GPT-6
* Manage Fields * Deck Picker + Study Options Part of 21794 Assisted-by: GPT-6
FAB is still in the background Part of 21794 Assisted-by: GPT-6
Content was covered when entering custom study options Part of 21794 Assisted-by: GPT-6
WebView text-only zoom (`textZoom`) does not scale em-based layouts (used by MathJax). It would have required fragile, font-specific workarounds to fix on the MathJax level: * `text-size-adjust` had no effect. * `font-size-adjust` required compensation for each font. Instead, set `textZoom` to 100 (from 130 [system-dependent]) and scale using CSS zoom. This scales the text size and layout together. BREAKING CHANGE: Some layouts are changed by this, see my list on 20776 Fixes 20776 Assisted-by: GPT-6
Part of 20776 Assisted-by: GPT-6
Keeps a strong reference to a pending snackbar so it can't be GCed The reference is removed when the snackbar is shown or dismissed (without clearing a newer replacement). Fixes 22076 Assisted-by: GPT-6
`AppLifecycleObserver.onStop` blocked on the collection queue,
This blocked WorkManager's timeout callback, crashing the app if
`dataSync` timed out.
```
android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException: A foreground service of type dataSync did not stop within its timeout: ComponentInfo{com.ichi2.anki/androidx.work.impl.foreground.SystemForegroundService}
at android.app.ActivityThread.generateForegroundServiceDidNotStopInTimeException(ActivityThread.java:2875)
at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2837)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException(Unknown Source:0)
```
Fixes 19749
Assisted-by: GPT-6
With the keyboard up in landscape, Filter by tag froze AnkiDroid for seconds at a time and could end in "AnkiDroid isn't responding". The dialog had so little height left that the tag list was laid out with a negative height, which RecyclerView read as a huge one, so it built a row for every tag, again on each keystroke. The list now sits in its own container, so it shrinks to nothing instead. Part of 22082 Assisted-by: Opus 5.5
On a phone in landscape, opening the keyboard squeezed the tags dialog into the strip above it: the toolbar was cut off and no tags were visible. On short screens the dialog now keeps its size and the keyboard covers its lower part, so the search field and the first matches stay in view, and the buttons come back once the keyboard closes. Rotating with the dialog open switches between the two. Fixes 22082 Assisted-by: Opus 5.5
Add a ViewModelSavedStateHandle alias and a factory that supplies an empty set of default arguments to AndroidX. Keep the remaining creation extras intact so saved-state ownership and restoration still use AndroidX. Document that the alias alone does not filter arguments and previously saved values remain intact. Launch inputs belong in constructor parameters. Existing ViewModels are not migrated in this preparatory change. Test activity and fragment owners with EmptyApplication, including an unfiltered model that must still receive the original owner arguments. Both cases fail when the factory copies those arguments. Part of 21953 Assisted-by: GPT-6
Part of 21953 Assisted-by: GPT-6
ExportReadyViewModel copied any intent extras from AnkiActivity into its instance state, potentially triggering a `TransactionTooLargeException`. Use our new `savedStateViewModelFactory` to avoid this. Part of 21953 Assisted-by: GPT-6
Calling `.cancel()` on the progress monitor did not wait for completion, so a notification + 'Cancel', associated with a completed WorkManager could appear. Fix: make the monitor a child of the sync operation via `coroutineScope`. The scope will then wait for the monitor to finish before cleaning up notifications. Fixes 19830 Assisted-by: GPT-6
Assisted-by: GPT-6
13 files AnkiDroid is standardizing licenses to SPDX. Issue 20954 This change was not performed using LLMs and I have verified that it is correct
build(deps): bump actions/setup-java from 6.0.0 to 6.0.1 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 6.0.0 to 6.0.1. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](actions/setup-java@v6...de7274f) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> build(deps): bump com.google.testparameterinjector:test-parameter-injector Bumps com.google.testparameterinjector:test-parameter-injector from 1.23 to 1.24. --- updated-dependencies: - dependency-name: com.google.testparameterinjector:test-parameter-injector dependency-version: '1.24' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> build(deps): bump the non-breaking group Bumps the non-breaking group in /tools/localization with 7 updates: | Package | From | To | | --- | --- | --- | | [dotenv](https://github.com/motdotla/dotenv) | `18.0.2` | `18.0.4` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.6.2` | `26.6.3` | | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.70.1` | `8.71.0` | | [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.70.1` | `8.71.0` | | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) | `18.3.0` | `18.4.0` | | [prettier](https://github.com/prettier/prettier) | `3.9.8` | `3.9.9` | | [ts-jest](https://github.com/kulshekhar/ts-jest) | `29.4.12` | `29.4.14` | Updates `dotenv` from 18.0.2 to 18.0.4 - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](motdotla/dotenv@v18.0.2...v18.0.4) Updates `@types/node` from 26.6.2 to 26.6.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@typescript-eslint/eslint-plugin` from 8.70.1 to 8.71.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.0/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.70.1 to 8.71.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.0/packages/parser) Updates `eslint-plugin-n` from 18.3.0 to 18.4.0 - [Release notes](https://github.com/eslint-community/eslint-plugin-n/releases) - [Changelog](https://github.com/eslint-community/eslint-plugin-n/blob/master/CHANGELOG.md) - [Commits](eslint-community/eslint-plugin-n@v18.3.0...v18.4.0) Updates `prettier` from 3.9.8 to 3.9.9 - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.9.8...3.9.9) Updates `ts-jest` from 29.4.12 to 29.4.14 - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](kulshekhar/ts-jest@v29.4.12...v29.4.14) --- updated-dependencies: - dependency-name: dotenv dependency-version: 18.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: non-breaking - dependency-name: "@types/node" dependency-version: 26.6.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: non-breaking - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.71.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking - dependency-name: "@typescript-eslint/parser" dependency-version: 8.71.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking - dependency-name: eslint-plugin-n dependency-version: 18.4.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking - dependency-name: prettier dependency-version: 3.9.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: non-breaking - dependency-name: ts-jest dependency-version: 29.4.14 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: non-breaking ... Signed-off-by: dependabot[bot] <support@github.com> build(deps): bump dawidd6/action-download-artifact from 25 to 26 Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 25 to 26. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](dawidd6/action-download-artifact@634d83b...27e4ae6) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-version: '26' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> build(deps): bump gradle/actions/setup-gradle from 6.3.0 to 6.4.0 Bumps [gradle/actions/setup-gradle](https://github.com/gradle/actions) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/gradle/actions/releases) - [Commits](gradle/actions@9c97196...3f5f9ad) --- updated-dependencies: - dependency-name: gradle/actions/setup-gradle dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> build(deps): bump dawidd6/action-download-artifact from 26 to 27 Fixes a bug in GitHub which meant the latest workflow was not returned, breaking our screenshot baselines. dawidd6/action-download-artifact@eab87c9 Fixes 21888 See https://redirect.github.com/dawidd6/action-download-artifact/pull/432 Assisted-by: GPT-6
My own copyright lines were not added to the licenses header.
A concurrent scroll and call to `clearCardsList` could cause an inconsistent state: * The adapter thinks it has rows * but the rows were cleared To fix this, use and update a snapshot of the rows in the adapter, to ensure they're consistent. Fixes 17759 Assisted-by: GPT-6
Using 'Edit Tags' so there are intermediate states: With BOTH tags `B` and `B`::child` selected on a note. * Deselect `B` * B appears partially checked, as the child remained selected * Submit * `B` remains selected. The user's intention was to remove `B`, but this didn't occur, as we used the visible state of the tag rather than our concept of 'preserved tags'. This fix separates out the display state, so we don't over-select tags Assisted-by: GPT-6
`TMPDIR` can be unwritable (`/data/local/tmp`). In this case, set the 'overwrite' flag to true, and overwrite the envvar with `context.cacheDir.path` when we start up. Fixes 19545 Assisted-by: GPT-6
* different heights * 200% font sizes Prep for 18524 Assisted-by: GPT-6
Handle the padding and deck name Part of 18524 Assisted-by: GPT-6
Names and card counts are centered within each row Part of 18524 Assisted-by: GPT-6
* Measure the rows so only complete rows are shown * Center the list * Refresh the list if widget is resized Part of 18524 Assisted-by: GPT-6
If there's not enough space for the first row, shrink its text so it is visible. Fixes 18524 Assisted-by: GPT-6
As the API uses a content provider, a query could theoretically hit the backend before `Application.onCreate`'s init routine. Assisted-by: GPT-6
The exception is user-facing and non-actionable by us. Filters `BackendSchedulerUpgradeRequiredException`. Fixes 17385 Assisted-by: GPT-6
When an in-flight request to the API failed, it could be picked up by the media handler, showing an unexpected `.bin` file failing to load. Fixes 16510 Assisted-by: GPT-6
Hardening for 16510 Assisted-by: GPT-6
Mostly for media throttling Part of 16510 Assisted-by: GPT-6
Assisted-by: Claude Sonnet 5 [tests]
This is very heavily documented as there are subtle issues, such as `ViewModel.onCleared` not necessarily being a permanent dismissal. As part of our IdsFile changes, where we want to keep a file on disk and reference this in our activity state, but also allow multiple concurrent files on disk in case an activity exists twice in the task graph. Part of 19572 Assisted-by: GPT-6
* Delete only after the replacement is written * Delete the final snapshot via `onPermanentDismissal` Part of 19572 Assisted-by: Claude Fable 5.1 Assisted-by: GPT-6
Buggy if the build logic classloaders are reused between builds, potentially using outdated data from the cache. Caused a 0.004 ms saving (warmed-lookup estimate) - not worth keeping Assisted-by: GPT-6
Previously, if our `alert` implementation failed, we returned `false`, which had the WebView show the default. Now, we cancel the alert, confirming the request without a fallback. This could fail for the same reason - for example, I suspect this was caused by our Congrats page continuing to refresh (and failing), when the app is backgrounded and can no longer show alerts. **Bug Reporting** If we hit a window-limit failure, ensure we're only reporting it if silent mode is enabled otherwise, this shows a dialog itself. This is defensive handling for a legacy bug, it has likely already been resolved by Anki updates the congrats screen and our lifecycle fixes. Part of 15658 Assisted-by: GPT-6
Restore the expanded add menu views and Back behavior when DeckPicker is recreated. GPT-5.6 added the recreation handling and regression test. Fixes #22241 Assisted-by: GPT-5.6
The sort chip is icon only, so TalkBack announced it as an unlabelled button, and the flipped icon was the only hint of the sort direction. Give it a content description with the same text as the sort snackbar, such as "Sort by Created · Newest first" or "No sorting". The ViewModel now keeps the current sort as state, so the label is right as soon as the browser opens, and it is rebuilt after a language change. Assisted-by: Claude Opus 5.5
Cards and notes mode keep separate sort settings, but switching modes didn't reload them. The sort chip kept showing the old mode's direction, and its TalkBack label still named the old mode's sort. Assisted-by: Claude Opus 5.5
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.
33 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.