* Migrate build system to uv
Closes#3787, and is a step towards #3081 and #4022
This change breaks our PyOxidizer bundling process. While we probably
could update it to work with the new venvs & lockfile, my intention
is to use this as a base to try out a uv-based packager/installer.
Some notes about the changes:
- Use uv for python download + venv installation
- Drop python/requirements* in favour of pyproject files / uv.lock
- Bumped to latest Python 3.9 version. The move to 3.13 should be
a fairly trivial change when we're ready.
- Dropped the old write_wheel.py in favour of uv/hatchling. This has
the unfortunate side-effect of dropping leading zeros in our wheels,
which we could try hack around in the future.
- Switch to Qt 6.7 for the dev repo, as it's the first PyQt version
with a Linux/ARM WebEngine wheel.
- Unified our macOS deployment target with minimum required for ARM.
- Dropped unused fluent python files
- Dropped unused python license generation
- Dropped helpers to run under Qt 5, as our wheels were already
requiring Qt 6 to install.
* Build action to create universal uv binary
* Drop some PyOxidizer-related files
* Use Windows ARM64 cargo/node binaries during build
We can't provide ARM64 wheels to users yet due to #4079, but we can
at least speed up the build.
The rustls -> native-tls change on Windows is because ring requires
clang to compile for ARM64, and I figured it's best to keep our Windows
deps consistent. We already built the wheels with native-tls.
* Make libankihelper a universal library
We were shipping a single arch library in a purelib, leading to
breakages when running on a different platform.
* Use Python wheel for mpv/lame on Windows/Mac
This is convenient, but suboptimal on a Mac at the moment. The first
run of mpv will take a number of seconds for security checks to run,
and our mpv code ends up timing out, repeating the process each time.
Our installer stub will need to invoke mpv once first to get it validated.
We could address this by distributing the audio with the installer/stub,
or perhaps by putting the binaries in a .pkg file that's notarized+stapled
and then included in the wheel.
* Add some helper scripts to build a fully-locked wheel
* Initial macOS launcher prototype
* Add a hidden env var to preload our libs and audio helpers on macOS
* qt/bundle -> qt/launcher
- remove more of the old bundling code
- handle app icon
* Fat binary, notarization & dmg
* Publish wheels on testpypi for testing
* Use our Python pin for the launcher too
* Python cleanups
* Extend launcher to other platforms + more
- Switch to Qt 6.8 for repo default, as 6.7 depends on an older
libwebp/tiff which is unavailable on newer installs
- Drop tools/mac-x86, as we no longer need to test against Qt 5
- Add flags to cross compile wheels on Mac and Linux
- Bump glibc target to 2_36, building on Debian Stable
- Increase mpv timeout on macOS to allow for initial gatekeeper checks
- Ship both arm64 and amd64 uv on Linux, with a bash stub to pick
the appropriate arch.
* Fix pylint on Linux
* Fix failure to run from /usr/local/bin
* Remove remaining pyoxidizer refs, and clean up duplicate release folder
* Rust dep updates
- Rust 1.87 for now (1.88 due out in around a week)
- Nom looks involved, so I left it for now
- prost-reflect depends on a new prost version that got yanked
* Python 3.13 + dep updates
Updated protoc binaries + add helper in order to try fix build breakage.
Ended up being due to an AI-generated update to pip-system-certs that
was not reviewed carefully enough:
https://gitlab.com/alelec/pip-system-certs/-/issues/36
The updated mypy/black needed some tweaks to our files.
* Windows compilation fixes
* Automatically run Anki after installing on Windows
* Touch pyproject.toml upon install, so we check for updates
* Update Python deps
- urllib3 for CVE
- pip-system-certs got fixed
- markdown/pytest also updated
* add left margin to browser when sidebar is closed
* listen for event instead of explicit user action
* refresh sidebar on visibility change
* Add a margin on macOS even when not collapsed
---------
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
Currently, if a user tries to close Preview which was opened inside Browse, the "parent" Browse window itself gets closed
Co-authored-by: beyondcompute <beyondcompute@users.noreply.github.com>
* Add a way to pass information from browser_will_search to browser_did_search without having it going to the backend
* Allow None for SearchContext.properties
* Adding myself in CONTRIBUTORS
* Rename SearchContext.properties to SearchContext.addon_metadata
* Revert "Adding myself in CONTRIBUTORS"
This reverts commit a993577279.
* Reapply "Adding myself in CONTRIBUTORS"
This reverts commit f3ce51c83d.
* Enable Cmd+W shortcut in "Edit Current" on Mac
* Enable Cmd+W shortcut in "Fields" editor on Mac
* Enable Cmd+W shortcut in "Cards" editing on Mac
* Enable Cmd+W shortcut in "Sync" tab modal on Mac
* Enable Cmd+W shortcut in "Custom Study" tab modal on Mac
* Enable Cmd+W shortcut in Settings view on Mac
* Enable Cmd+W shortcut in Export dialogs on Mac
* Enable Cmd+W shortcut for getText dialog on Mac
* Enable Cmd+W shortcut in "Change Deck" on Mac
* Enable Cmd+W shortcut in Reposition dialog on Mac
* Enable Cmd+W shortcut in "Grade Now" dialog on Mac
* Enable Cmd+W shortcut in "Reset…" dialog on Mac
* Remove duplicate camelCase variant of add_close_shortcut (dae)
- The camelCase variant will remain accessible with a warning.
- The removed setattr line is legacy cruft, and wasn't doing anything.
* add AnkiWebView subclasses for stats, empty cards and find dupes ui
* update ui files to use subclassed webviews instead
* remove superfluous calls to AnkiWebView.set_kind
* Avoid set_kind() race condition in legacy stats webview
Replacing the web view is a hacky workaround, but likely a reasonable compromise for a legacy view that we do not want to maintain a separate Qt form for.
* Slightly refactor AnkiWebView subclass creation and tweak inline comment
+ Extend create_ankiwebview_subclass() with the ability to set any
init time AnkiWebView argument
+ Introduce some nice-to-haves in terms of static type checking support
and IDE autocompletion
+ Mark helper function as private to discourage add-on use
* Drop `AnkiWebView.set_kind` completely
There no longer is an Anki-internal use case for changing the web view kind after initializing a web view, and add-ons almost certainly do not have any use for it either.
Given that setting the kind after web view construction can lead to known race conditions with `domDone` signals, we should remove this method to discourage uses like this in both Anki code and add-on consumers.
There currenty only seems to be one add-on calling `set_kind()`, so this seem like a justifiable API change.
---------
Co-authored-by: llama <100429699+iamllama@users.noreply.github.com>
* Feat/grade now
* pass ci
* fix from_queue
* Refactor card answering to support from_queue flag
- Add `from_queue` field to `CardAnswer` struct and proto message
- Modify `answer_card_inner` to handle queue updates based on `from_queue`
- Remove `grade_card` method and consolidate card answering logic
- Update related test cases to set `from_queue` flag
* fix current_changes() called when no op set
* Optimize queue updates for batch card processing
- Refactor `grade_now` to collect processed card IDs first
- Add new `update_queues_for_processed_cards` method for efficient batch queue updates
- Improve queue management by removing entries and updating counts in a single pass
- Remove individual queue update method in favor of batch processing
* pass ci
* keep the same style
* remove ineffective code
* remove unused imports
* Add function to restore the default name of a flag
* Call function to restore default flag name if flag renamed to empty string
* Update _load_flags to use the default_flag_names dict
* Add name to contributors file
* Add trailing comma to pass tests
* Update to follow python style guide
* Update about.py
* Revert "Update _load_flags to use the default_flag_names dict"
This reverts commit caa8fea94b.
* Use require_refresh() instead of storing default flag names
* Replace window.location in CardInfoDialog with load_sveltekit_page
* Fix format
* Fix ForgettingCurve's reactivity
* Props' default args aren't reactive
* Add global _updateCardId fn to card-info
* Use _updateCardId to reactively update card-info
* Fix format
* Fix type
* Use dummy form instead of window global for client-side nav
* Fallback to window.location in case form hasn't been rendered
* Use window.postMessage instead of dummy <form>
* fix: except only non-system-exiting exceptions
see https://youtu.be/zrVfY9SuO64
* chore: add myself to CONTRIBUTORS file
* refactor: explicitly specify possible exceptions
If an exception is not an Exception, there are only three options left.
see https://docs.python.org/3/library/exceptions.html#exception-hierarchy
* refactor: use BaseException for fallback
Co-authored-by: Damien Elmes <dae@users.noreply.github.com>
* chore: add myself to contributors
* chore: add myself to CONTRIBUTORS file
* refactor: use newer type hints for Union/Optional
* refactor: fix deprecated type annotations
use collections.abc rather than typing
* refactor: use lower letter type annotations
* style: reformat with black
* refactor: remove unused imports
* refactor: add missing imports for type hints
* fixup! refactor: use newer type hints for Union/Optional
* fix: add missing imports for type annotations
* fixup! refactor: use newer type hints for Union/Optional
* fixup! style: reformat with black
* refactor: fix remaining imports re: type hints
* Update to latest Node LTS
* Add sveltekit
* Split tslib into separate @generated and @tslib components
SvelteKit's path aliases don't support multiple locations, so our old
approach of using @tslib to refer to both ts/lib and out/ts/lib will no
longer work. Instead, all generated sources and their includes are
placed in a separate out/ts/generated folder, and imported via @generated
instead. This also allows us to generate .ts files, instead of needing
to output separate .d.ts and .js files.
* Switch package.json to module type
* Avoid usage of baseUrl
Incompatible with SvelteKit
* Move sass into ts; use relative links
SvelteKit's default sass support doesn't allow overriding loadPaths
* jest->vitest, graphs example working with yarn dev
* most pages working in dev mode
* Some fixes after rebasing
* Fix/silence some svelte-check errors
* Get image-occlusion working with Fabric types
* Post-rebase lock changes
* Editor is now checked
* SvelteKit build integrated into ninja
* Use the new SvelteKit entrypoint for pages like congrats/deck options/etc
* Run eslint once for ts/**; fix some tests
* Fix a bunch of issues introduced when rebasing over latest main
* Run eslint fix
* Fix remaining eslint+pylint issues; tests now all pass
* Fix some issues with a clean build
* Latest bufbuild no longer requires @__PURE__ hack
* Add a few missed dependencies
* Add yarn.bat to fix Windows build
* Fix pages failing to show when ANKI_API_PORT not defined
* Fix svelte-check and vitest on Windows
* Set node path in ./yarn
* Move svelte-kit output to ts/.svelte-kit
Sadly, I couldn't figure out a way to store it in out/ if out/ is
a symlink, as it breaks module resolution when SvelteKit is run.
* Allow HMR inside Anki
* Skip SvelteKit build when HMR is defined
* Fix some post-rebase issues
I should have done a normal merge instead.
* - update remove decks function to return names of all deleted decks
- update protobuf message to display deck names
- update python files to receive message in the frontend.
- add message template to ftl
* update CONTRIBUTORS
* format
* refactor: move up deck names concatenation to tooltip api call
to fix type expectations
* restore core behavior and get deck name from view
* fix type specs
* remove new type and use str instead
restore incorrectly removed lines
* Remove v1/v2 support from deck list
* Remove v1/v2 support from most routines and show error
* Remove scheduler_version from preferences
* Fix formatting
* Remove v1/v2 conditionals from Python code
* Fix legacy importer
* Remove legacy hooks
* Add missing scheduler checks
* Remove V2 logic from deck options screen
* Remove the review_did_undo hook
* Restore ability to open old options with shift (dae)
* Rollback if toggling state fails
Previously, if the search triggered by a state toggle failed, the switch
and the model would move to the new state, while the table would remain
in the previous state.
* Fix reversed sort orders of FSRS columns
* Add sep. default sort orders for notes and cards
* Add test for consistent default sort orders
* Add launch config for debugging in VSC
* Extend launch config for macOS and Linux
* Implement import log screen in Svelte
* Show filename in import log screen title
* Remove unused NoteRow property
* Show number of imported notes
* Use a single nid expression
* Use 'count' as variable name for consistency
* Import from @tslib/backend instead
* Fix summary_template typing
* Fix clippy warning
* Apply suggestions from code review
* Fix imports
* Contents -> Fields
* Increase max length of browser search bar
https://github.com/ankitects/anki/pull/2568/files#r1255227035
* Fix race condition in Bootstrap tooltip destruction
https://github.com/twbs/bootstrap/issues/37474
* summary_template -> summaryTemplate
* Make show link a button
* Run import ops on Svelte side
* Fix geometry not being restored in CSV Import page
* Make VirtualTable fill available height
* Keep CSV dialog modal
* Reword importing-existing-notes-skipped
* Avoid mentioning matching based on first field
* Change tick and cross icons
* List skipped notes last
* Pure CSS spinner
* Move set_wants_abort() call to relevant dialogs
* Show number of imported cards
* Remove bold from first sentence and indent summaries
* Update UI after import operations
* Add close button to import log page
Also make virtual table react to resize event.
* Fix typing
* Make CSV dialog non-modal again
Otherwise user can't interact with browser window.
* Update window modality after import
* Commit DB and update undo actions after import op
* Split frontend proto into separate file, so backend can ignore it
Currently the automatically-generated frontend RPC methods get placed in
'backend.js' with all the backend methods; we could optionally split them
into a separate 'frontend.js' file in the future.
* Migrate import_done from a bridgecmd to a HTTP request
* Update plural form of importing-notes-added
* Move import response handling to mediasrv
* Move task callback to script section
* Avoid unnecessary :global()
* .log cannot be missing if result exists
* Move import log search handling to mediasrv
* Type common params of ImportLogDialog
* Use else if
* Remove console.log()
* Add way to test apkg imports in new log screen
* Remove unused import
* Get actual card count for CSV imports
* Use import type
* Fix typing error
* Ignore import log when checking for changes in Python layer
* Apply suggestions from code review
* Remove imported card count for now
* Avoid non-null assertion in assignment
* Change showInBrowser to take an array of notes
* Use dataclasses for import log args
* Simplify ResultWithChanges in TS
* Only abort import when window is modal
* Fix ResultWithChanges typing
* Fix Rust warnings
* Only log one duplicate per incoming note
* Update wording about note updates
* Remove caveat about found_notes
* Reduce font size
* Remove redundant map
* Give credit to loading.io
* Remove unused line
---------
Co-authored-by: RumovZ <gp5glkw78@relay.firefox.com>
Quite a few users have been experiencing crashes recently that were
resolved by resetting their window positions/states. I presume this is
related to Qt updates, as there have been previous instances where old
state caused glitchy behaviour or crashes after a Qt upgrade.
The browser headers are now also reset when resetting window positions
in the preferences.
Way back in Qt4, there was an issue where (some?) windows would open
at a different location to where they were previously open. I've tested
the primary windows in Qt 5.14 on macOS, and the issue no longer seems
to exist, so this code is no longer useful.
The qtmajor > 5 check was a mistake introduced in 70dbd06be3ff56f13b9efe7c886c2a6c4f873ce9;
it was intended to limit the code to Qt 5.
A quick grep of an add-on snapshot indicates there are no add-ons that
were using the offset param, so it has been removed.