Commit Graph

1888 Commits

Author SHA1 Message Date
Damien Elmes
0301ae1d8a fsrs_memory_state -> memory_state 2023-09-17 11:50:38 +10:00
Damien Elmes
5004cd332b
Integrate FSRS into Anki (#2654)
* Pack FSRS data into card.data

* Update FSRS card data when preset or weights change

+ Show FSRS stats in card stats

* Show a warning when there's a limited review history

* Add some translations; tweak UI

* Fix default requested retention

* Add browser columns, fix calculation of R

* Property searches

eg prop:d>0.1

* Integrate FSRS into reviewer

* Warn about long learning steps

* Hide minimum interval when FSRS is on

* Don't apply interval multiplier to FSRS intervals

* Expose memory state to Python

* Don't set memory state on new cards

* Port Jarret's new tests; add some helpers to make tests more compact

https://github.com/open-spaced-repetition/fsrs-rs/pull/64

* Fix learning cards not being given memory state

* Require update to v3 scheduler

* Don't exclude single learning step when calculating memory state

* Use relearning step when learning steps unavailable

* Update docstring

* fix single_card_revlog_to_items (#2656)

* not need check the review_kind for unique_dates

* add email address to CONTRIBUTORS

* fix last first learn & keep early review

* cargo fmt

* cargo clippy --fix

* Add Jarrett to about screen

* Fix fsrs_memory_state being initialized to default in get_card()

* Set initial memory state on graduate

* Update to latest FSRS

* Fix experiment.log being empty

* Fix broken colpkg imports

Introduced by "Update FSRS card data when preset or weights change"

* Update memory state during (re)learning; use FSRS for graduating intervals

* Reset memory state when cards are manually rescheduled as new

* Add difficulty graph; hide eases when FSRS enabled

* Add retrievability graph

* Derive memory_state from revlog when it's missing and shouldn't be

---------

Co-authored-by: Jarrett Ye <jarrett.ye@outlook.com>
2023-09-16 16:09:26 +10:00
Abdo
6f0bf58d49
Add a backend method to add notes in bulk (#2659)
* Add a backend method to add notes in bulk

* i -> idx

* Remove duplicate assignment

* Allow add_notes to work with multiple deck IDs

* Rename note_deck_id to requests
2023-09-16 13:51:32 +10:00
Damien Elmes
30ae9f7c54 Fix merge_undoable_ops() not updating counter 2023-09-15 16:53:00 +10:00
Abdo
e2603a73f5
Fix unescaped HTML in type-in-the-answer (#2658) 2023-09-14 11:34:22 +10:00
RumovZ
850043b49b
Tooltips for CSV import and import page refactoring (#2655)
* Make enum selector generic

* Refactor ImportCsvPage to support tooltips

* Improve csv import defaults

* Unify import pages

* Improve import page styling

* Fix life cycle issue with import properties

* Remove size constraints to fix scrollbar styling

* Add help strings and urls to csv import page

* Show ErrorPage on ImportPage error

* Fix escaping of import path

* Unify ImportPage and ImportLogPage

* Apply suggestions from code review (dae)

* Fix import progress

* Fix preview overflowing container

* Don't include <br> in FileIoErrors (dae)

e.g. 500: Failed to read '/home/dae/foo2.csv':<br>stream did not contain valid UTF-8

I thought about using {@html ...} here, but that's a potential security issue,
as the filename is not something we control.
2023-09-14 09:06:15 +10:00
Damien Elmes
bfef908c6c
Refactor media sync handling (#2647)
* Refactor media sync handling

- The media USN is now returned in sync/meta, which avoids an extra
round-trip.
- Media syncing is now automatically started by the syncing code at
the end of a normal or full sync, which avoids it competing for bandwidth
and resources, and avoids duplicate invalid login messages when the auth
token is invalid.
- Added a new media_sync_progress() method to both check if media is
syncing, and get access to the latest progress.
- Updated the sync log screen to only show the latest line, like AnkiMobile.
- Show media sync errors in a pop-up, so they don't get missed. Use a non-modal
pop-up to avoid potential conflicts with other modals.

* Remove print statement
2023-09-10 13:22:20 +10:00
RumovZ
14de8451dc
Merging Notetypes on Import (#2612)
* Remember original id when importing notetype

* Reuse notetypes with matching original id

* Add field and template ids

* Enable merging imported notetypes

* Fix test

Note should be updated if the incoming note's notetype is
remapped to the existing note's notetype.
On the other hand, it should be skipped if its notetype id is mapped
to some new notetype.

* Change field and template ids to i32

* Add merge notetypes flag to proto message

* Add dialog for apkg import

* Move HelpModal into components

* Generalize import dialog

* Move SettingTitle into components

* Add help modal to ImportAnkiPackagePage

* Move SwitchRow into components

* Fix backend method import

* Make testable in browser

* Fix broken modal

* Wrap in container and fix margins

* Update commented Anki version of new proto fields

* Check ids when comparing notetype schemas

* Add tooltip for merging notetypes.

* Allow updating notes regardless of mtime

* Gitignore yarn-error.log

* Allow updating notetypes regardless of mtime

* Fix apkg help carousel

* Use i64s for template and field ids

* Add option to omit importing scheduling info

* Restore last settings in apkg import dialog

* Display error when getting metadata in webview

* Update manual links for apkg importing

* Apply suggestions from code review

Co-authored-by: Damien Elmes <dae@users.noreply.github.com>

* Omit schduling -> Import all cards as new cards

* Tweak importing-update-notes-help

* UpdateCondition → ImportAnkiPackageUpdateCondition

* Load keyboard.ftl

* Skip updating dupes in 'update alwyas' case

* Explain more when merging notetypes is required

* "omit scheduling" → "with scheduling"

* Skip updating notetype dupes if 'update always'

* Merge duplicated notetypes from previous imports

* Fix rebase aftermath

* Fix panic when merging

* Clarify 'update notetypes' help

* Mention 'merge notetypes' in the log

* Add a test which covers the previously panicking path

* Use nested ftl messages to ensure consistency

* Make order of merged fields deterministic

* Rewrite test to trigger panic

* Update version comment on new fields
2023-09-09 09:00:55 +10:00
Damien Elmes
9595101065 Wrap backend in an outer Arc
Necessary to allow backend commands that run in the background instead
of blocking.
2023-09-07 14:10:50 +10:00
Damien Elmes
ffd392de21
Change Anki's version scheme; bump to 23.09 (#2640)
* Accept iterables as inputs to backend methods

* Shift add-on check to backend; use new endpoint

The new endpoint will return info on a suitable branch if found,
instead of returning all branches. This simplifies the frontend code,
and means that you can now drop support for certain versions without
it also remotely disabling the add-on for people who are running one of
the excluded versions, like in

https://forums.ankiweb.net/t/prevent-add-ons-from-being-disabled-remote-stealthily-surreptitiously/33427

* Bump version to 23.09

This changes Anki's version numbering system to year.month.patch, as
previously mentioned on https://forums.ankiweb.net/t/use-a-different-versioning-system-semver-perhaps/20046/5

This is shaping up to be a big release, with the introduction of FSRS and
image occlusion, and it seems like a good time to be finally updating the
version scheme as well. AnkiWeb has been updated to understand the new
format, and add-on authors will now specify version compatibility using
the full version number, as can be seen here:

https://ankiweb.net/shared/info/3918629684

* Shift update check to backend, and tidy up update.py

* Use the shared client for sync connections too
2023-09-07 12:37:15 +10:00
Damien Elmes
6d34d19808 Drop legacy schema option 2023-09-06 15:49:14 +10:00
Damien Elmes
0c6e3eaa93
Integrate the FSRS optimizer (#2633)
* Support searching for deck configs by name

* Integrate FSRS optimizer into Anki

* Hack in a rough implementation of evaluate_weights()

* Interrupt calculation if user closes dialog

* Fix interrupted error check

* log_loss/rmse

* Update to latest fsrs commit; add progress info to weight evaluation

* Fix progress not appearing when pretrain takes a while

* Update to latest commit
2023-09-05 18:45:05 +10:00
Damien Elmes
fe8cf5ae7d Read csv text in eagerly
This allows us to display a more useful "not utf-8" message, instead of a
generic "invalid csv" message when the metadata can't be fetched.
2023-09-05 18:33:23 +10:00
Damien Elmes
ecaba5e655 Fix stack overflow in request::Error mapping 2023-09-05 15:27:17 +10:00
Abdo
d3d67c2083
Support searching for custom data strings (#2634)
* Add extract_custom_data

* Add tests for has-cd

* Add `prop:cds` query
2023-09-04 11:17:13 +10:00
Damien Elmes
ff53625408 Update nightly formatter
Rustfmt is now capable of formatting let Some(..) else {} blocks
2023-09-02 16:13:50 +10:00
Abdo
064b973a2a
Allow searching for missing custom data properties (#2626)
* Allow searching for missing custom data properties

* Add has-cd query
2023-09-01 14:13:31 +10:00
Nil Admirari
9d3f01043b
Support AVIF (#2630) 2023-08-31 08:44:10 +10:00
Damien Elmes
e86cebd45e Fix importing link 2023-08-31 07:52:21 +10:00
Damien Elmes
408b48834b Fix clippy issues in Rust 1.72 2023-08-25 07:56:38 +10:00
Damien Elmes
cdcd9bcce0 New collections now start with the v3 scheduler 2023-08-19 13:31:01 +10:00
Damien Elmes
d2022d1a6d Avoid allocating in extract_latex() if possible; make public 2023-08-19 08:05:39 +10:00
Damien Elmes
b73cb15888 Take another approach to dealing with conflicting flattened keys
The approach in #2542 unfortunately introduced a regression, as whilst
it ensured that duplicate keys are removed when downgrading, it no longer
prevented the duplicates from being removed when converting to a legacy
Schema11 object. This resulted in things like backend.get_notetype_legacy()
returning duplicate keys, and could break syncing:

https://forums.ankiweb.net/t/windows-desktop-sync-error/33128

As syncing and schema11 object usage is quite common compared to downgrading,
the extra Value deserialization seemed a bit expensive, so I've switched
back to explicitly removing the problem keys. To ensure we don't forget to
add new keys in the future, I've added some new tests that should alert us
whenever a newly-added key is missing from the reserved list.
2023-08-15 11:25:53 +10:00
Damien Elmes
c112236dd9 Support include_filtered=false, skip_default=true case 2023-08-08 15:34:43 +10:00
Damien Elmes
934f582804 Support importing AnkiDroid's legacy backups
They were missing the media map, and were not importable by the desktop.
2023-08-03 19:33:16 +10:00
Abdo
98715e593a
Improve presentation of importing results (#2568)
* 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>
2023-08-02 20:29:44 +10:00
Damien Elmes
a35c1a058d Extract inline images as part of media check
We also need to get to the bottom of what's causing this:
https://forums.ankiweb.net/t/anki-browse-extremely-laggy/32533
2023-07-31 12:23:16 +10:00
Damien Elmes
a623dff0da Tolerate {{FrontSide}} on the front side
https://forums.ankiweb.net/t/display-the-template-for-the-front-has-a-problem/32035
2023-07-13 21:39:16 +10:00
Damien Elmes
9711044290 Improve performance of invalid ID fix in DB check
Fixes https://forums.ankiweb.net/t/check-database-is-stuck-on-checking-history/31891
2023-07-07 22:53:41 +10:00
Damien Elmes
fc0bff4166 Add updated script for transforming ftl text 2023-07-06 22:27:09 +10:00
Damien Elmes
516abf7cfa Stop including Qt translations when EXTRA_FTL_ROOT provided
This was causing index mismatches when switching between release and
non-release builds, presumably as the build script wasn't being rerun
in that case. We could add a rerun-if-changed=RELEASE, but easier to
strip this out, as it's rare to run the checks from an external repo.
2023-07-04 18:26:27 +10:00
Damien Elmes
e835922ded Fix i18n build script not responding to env var changes
Not much use declaring the cargo flag when we bake the env var into
the binary! Also treat an empty variable as missing.
2023-07-04 17:17:41 +10:00
Damien Elmes
13572a86b2 Move i18n helpers into ftl/, with a single main.rs
Clap gives us a nice help message and better arg parsing
2023-07-04 10:47:15 +10:00
Damien Elmes
78b4a391cc Fix some ftl args not being passed correctly in TypeScript 2023-07-04 00:47:59 +10:00
Damien Elmes
cb8007ce30 Move .py i18n method generation to Rust 2023-07-03 15:58:46 +10:00
Damien Elmes
4c76e3150b Move .ts i18n method generation to Rust
Based on a similar approach I used for AnkiDroid. The separate modules
file has been integrated into ftl.js.
2023-07-03 14:36:09 +10:00
Damien Elmes
f3b6deefe9 Combine all backend methods into a single js/d.ts file, like in Python
Easier to import from, and allows us to declare the output of the build
action without having to iterate over all the proto filenames. Have
confirmed it doesn't break esbuild's tree shaking.
2023-07-03 13:46:38 +10:00
Damien Elmes
ffadbf577b deckconfig.proto -> deck_config.proto
Makes it consistent with our other proto files, and matches the service
name.
2023-07-03 13:44:54 +10:00
Damien Elmes
8c712cd118 Support creating a standalone sync server 2023-07-02 18:22:44 +10:00
Damien Elmes
0f77de896d Fix building outside workspace
rslib/build.rs needs descriptors, even if env var not set
2023-07-02 18:22:44 +10:00
Damien Elmes
58c0f61d31 Fix progress not updating after one-way sync 2023-07-02 15:47:09 +10:00
Damien Elmes
5149cd13d4 Fix newly-added image occlusion notetype not syncing
https://forums.ankiweb.net/t/synchronisation-issue/31505/7
2023-07-01 22:10:29 +10:00
Damien Elmes
85c2769f80
Update Rust and Python deps (#2567)
* Update Python deps

* Update semver-compat Rust deps

* Update most crates to latest semver

* Update to latest axum-client-ip
2023-07-01 18:26:43 +10:00
Damien Elmes
f032242b65 Add must_use annotations to generated protobufs 2023-06-30 17:02:36 +10:00
Damien Elmes
5506f9bf2d Fix full template render choking on empty fields 2023-06-27 16:30:41 +10:00
Damien Elmes
dc56a2ca7d Rework RenderCardOutput::question/answer
Instead of flattening the output (which was missing FrontSide), alter
the behaviour of render() instead. The non-partial output is now exposed
via Protobuf, so the non-Python clients can take advantage of it.
2023-06-27 00:37:41 +10:00
Damien Elmes
21a03265a2 Rename sanity check fields avoid conflict with outer span 2023-06-26 15:04:58 +10:00
Damien Elmes
cf39455487 Handle invalid float mtimes in DB check
Likely an add-on or third-party tool created them, and they were breaking
DB queries for a user.

https://sqlite.org/stricttables.html could help us avoid this class of
issue in the future, though we'd need to check what client versions we'd
break with this change, and would need to change the 'sfld is an integer'
hack.
2023-06-26 13:40:54 +10:00
Damien Elmes
b2e7ab522b Remove some unused Rust dependencies 2023-06-24 19:30:29 +10:00
Damien Elmes
40e1520acb Drop workspace-hack in favor of workspace deps
Workspace deps were introduced in Rust 1.64. They don't cover all the
cases that Hakari did unfortunately, but they are simpler to maintain,
and they avoid a couple of issues that Hakari had:

- It sometimes made updating dependencies harder due to the locked versions,
so you had to disable Hakari, do the updates, and then re-generate (
e.g. 943dddf28f)
- The current Hakari config was breaking AnkiDroid's build, as it was
stopping a cross-compile from functioning correctly.
2023-06-23 17:41:31 +10:00
Damien Elmes
5023356dd2 Make Command::run() accept a single string for convenience
We can fall back on the standard constructor when we have dynamic input
2023-06-23 11:31:39 +10:00
Damien Elmes
a96d5a920b Add copy_file to anki_io, and ensure strings parent folder is created 2023-06-22 19:33:34 +10:00
Damien Elmes
1be9c36863 Fix ts interface being output to wrong filenames 2023-06-22 09:58:12 +10:00
Damien Elmes
0173ebf384 Fix lack of progress/error when importing a .colpkg
We should be accessing the backend progress state, instead of the
collection's state.
2023-06-22 09:46:09 +10:00
Damien Elmes
b37063e20a More service generation refactoring
- Dropped the protobuf extensions in favor of explicitly listing out
methods in both services if we want to implement both, as it's clearer.
- Move Service/Method wrappers into a separate crate that the various
clients can import, to easily get at the list of backend services and
their correct indices and comments.
2023-06-22 09:46:09 +10:00
Damien Elmes
c0f73d5f97 Drop the generated method map
I'd been thinking it might be useful for a future API service, but
I think that's better implemented with more codegen, so we have a
statically-typed interface.
2023-06-22 09:46:09 +10:00
Damien Elmes
7619891d4f Fix total note count not being logged in apkg import
https://forums.ankiweb.net/t/2-1-65-conflicting-import-message-when-importing-decks-with-v1-scheduler/31352/3
2023-06-22 09:46:09 +10:00
Damien Elmes
ba6325b47f Make some more fields/methods public
Continuation of https://github.com/ankitects/anki/issues/2494
2023-06-20 21:59:49 +10:00
Damien Elmes
c447999b4a Report actual error when DbError occurs 2023-06-20 21:58:27 +10:00
Damien Elmes
46722d792d Use a separate service definition for backend-only services
Realised this is clearer than tagging each method individually. The
enum has been retained for the case where we want to implement the backend
method separately from the collection one.
2023-06-19 22:06:50 +10:00
Damien Elmes
6f9b152028 Handle case where cards are imported into a collection with a newer start
https://forums.ankiweb.net/t/bug-report-when-the-original-due-is-less-than-0-the-due-will-be-weird-when-empty-the-filter-deck/31279

The 0 day case isn't fixed by this, but I don't think we can fix that
with the current schema.
2023-06-19 18:39:00 +10:00
Damien Elmes
553303fc12
Refactor service generation (#2552)
* Automatically elide empty inputs and outputs to backend methods

* Refactor service generation

Despite the fact that the majority of our Protobuf service methods require
an open collection, they were not accessible with just a Collection
object. To access the methods (e.g. because we haven't gotten around to
exposing the correct API in Collection yet), you had to wrap the collection
in a Backend object, and pay a mutex-acquisition cost for each call, even
if you have exclusive access to the object.

This commit migrates the majority of service methods to the Collection, so
they can now be used directly, and improves the ergonomics a bit at the
same time.

The approach taken:

- The service generation now happens in rslib instead of anki_proto, which
avoids the need for trait constraints and associated types.
- Service methods are assumed to be collection-based by default. Instead of
implementing the service on Backend, we now implement it on Collection, which
means our methods no longer need to use self.with_col(...).
- We automatically generate methods in Backend which use self.with_col() to
delegate to the Collection method.
- For methods that are only appropriate for the backend, we add a flag in
the .proto file. The codegen uses this flag to write the method into a
BackendFooService instead of FooService, which the backend implements.
- The flag can also allows us to define separate implementations for collection
and backend, so we can e.g. skip the collection mutex in the i18n service
while also providing the service on a collection.
2023-06-19 15:33:40 +10:00
Damien Elmes
dac532953e
Refactor progress handling (#2549)
Previously it was Backend's responsibility to store the last progress,
and when calling routines in Collection, one had to construct and pass
in a Fn, which wasn't the most ergonomic. This PR adds the last progress
state to the collection, so that the routines no longer need a separate
progress arg, and makes some other tweaks to improve ergonomics.

ThrottlingProgressHandler has been tweaked so that it now stores the
current state, so that callers don't need to store it separately. When
a long-running routine starts, it calls col.new_progress_handler(),
which automatically initializes the data to defaults, and updates the
shared UI state, so we no longer need to manually update the state at
the start of an operation.

The backend shares the Arc<Mutex<>> with the collection, so it can get
at the current state, and so we can update the state when importing a
backup.

Other tweaks:

- The current Incrementor was awkward to use in the media check, which
uses a single incrementing value across multiple method calls, so I've
added a simpler alternative for such cases. The old incrementor method
has been kept, but implemented directly on ThrottlingProgressHandler.
- The full sync code was passing the progress handler in a complicated
way that may once have been required, but no longer is.
- On the Qt side, timers are now stopped before deletion, or they keep
running for a few seconds.
- I left the ChangeTracker using a closure, as it's used for both importing
and syncing.
2023-06-19 13:48:32 +10:00
Damien Elmes
93da201f07 Include cmdline in error display; show cargo install progress 2023-06-17 14:55:55 +10:00
Damien Elmes
dd95f6f749 Check for stale licenses.json in minilints
+ Add an anki_process library with some helpers for command running.
2023-06-17 14:01:27 +10:00
Damien Elmes
84b3abab6c Fix rsbridge build when 1.61 snafu feature enabled 2023-06-17 12:44:25 +10:00
Damien Elmes
cf47e4c98d Drop num_integer crate 2023-06-17 00:09:41 +10:00
Damien Elmes
9b028e8f3d Bump Chrono now that Rumo's TZ parser has been merged
https://github.com/chronotope/chrono/pull/978

+ Update workspace hack/licenses
2023-06-16 11:43:12 +10:00
Damien Elmes
81ac5a91ad Include backend comments in Python and Rust codegen
This is of limited usefulness at the moment, as it doesn't help consumers
of the public API.

Also removed detached comments from the included comments.
2023-06-16 10:59:00 +10:00
Damien Elmes
02a1c891a6 Don't require DESCRIPTORS_BIN in an external workspace
Consumers may not require it
2023-06-15 22:32:16 +10:00
Damien Elmes
de8f62f831 Don't fail silently when an empty csv is imported 2023-06-15 17:47:46 +10:00
Damien Elmes
f4fca1f5fd Skip writing descriptors if unchanged 2023-06-15 17:17:56 +10:00
Damien Elmes
9701055eb5 Add support for using n2 instead of ninja
Provides better visibility into what the build is currently doing.
Motivated by slow node.js downloads making the build appear stuck.

You can test this out by running ./tools/install-n2 then building
normally. Please report any problems, and 'cargo uninstall n2' to get
back to the old behaviour. It works on Windows, but prints a new line
each second instead of redrawing the same area.

A couple of changes were required for compatibility:

- n2 doesn't resolve $variable names inside other variables, so the
resolution needs to be done by our build generator.
- Our inputs and outputs in build.ninja need to be listed in a deterministic
order to avoid unwanted rebuilds. I've made a few other tweaks so the
build file should now be fully-deterministic.
2023-06-15 17:17:56 +10:00
Damien Elmes
45f5709214
Migrate to protobuf-es (#2547)
* Fix .no-reduce-motion missing from graphs spinner, and not being honored

* Begin migration from protobuf.js -> protobuf-es

Motivation:

- Protobuf-es has a nicer API: messages are represented as classes, and
fields which should exist are not marked as nullable.
- As it uses modules, only the proto messages we actually use get included
in our bundle output. Protobuf.js put everything in a namespace, which
prevented tree-shaking, and made it awkward to access inner messages.
- ./run after touching a proto file drops from about 8s to 6s on my machine. The tradeoff
is slower decoding/encoding (#2043), but that was mainly a concern for the
graphs page, and was unblocked by
37151213cd

Approach/notes:

- We generate the new protobuf-es interface in addition to existing
protobuf.js interface, so we can migrate a module at a time, starting
with the graphs module.
- rslib:proto now generates RPC methods for TS in addition to the Python
interface. The input-arg-unrolling behaviour of the Python generation is
not required here, as we declare the input arg as a PlainMessage<T>, which
marks it as requiring all fields to be provided.
- i64 is represented as bigint in protobuf-es. We were using a patch to
protobuf.js to get it to output Javascript numbers instead of long.js
types, but now that our supported browser versions support bigint, it's
probably worth biting the bullet and migrating to bigint use. Our IDs
fit comfortably within MAX_SAFE_INTEGER, but that may not hold for future
fields we add.
- Oneofs are handled differently in protobuf-es, and are going to need
some refactoring.

Other notable changes:

- Added a --mkdir arg to our build runner, so we can create a dir easily
during the build on Windows.
- Simplified the preference handling code, by wrapping the preferences
in an outer store, instead of a separate store for each individual
preference. This means a change to one preference will trigger a redraw
of all components that depend on the preference store, but the redrawing
is cheap after moving the data processing to Rust, and it makes the code
easier to follow.
- Drop async(Reactive).ts in favour of more explicit handling with await
blocks/updating.
- Renamed add_inputs_to_group() -> add_dependency(), and fixed it not adding
dependencies to parent groups. Renamed add() -> add_action() for clarity.

* Remove a couple of unused proto imports

* Migrate card info

* Migrate congrats, image occlusion, and tag editor

+ Fix imports for multi-word proto files.

* Migrate change-notetype

* Migrate deck options

* Bump target to es2020; simplify ts lib list

Have used caniuse.com to confirm Chromium 77, iOS 14.5 and the Chrome
on Android support the full es2017-es2020 features.

* Migrate import-csv

* Migrate i18n and fix missing output types in .js

* Migrate custom scheduling, and remove protobuf.js

To mostly maintain our old API contract, we make use of protobuf-es's
ability to convert to JSON, which follows the same format as protobuf.js
did. It doesn't cover all case: users who were previously changing the
variant of a type will need to update their code, as assigning to a new
variant no longer automatically removes the old one, which will cause an
error when we try to convert back from JSON. But I suspect the large majority
of users are adjusting the current variant rather than creating a new one,
and this saves us having to write proxy wrappers, so it seems like a
reasonable compromise.

One other change I made at the same time was to rename value->kind for
the oneofs in our custom study protos, as 'value' was easily confused
with the 'case/value' output that protobuf-es has.

With protobuf.js codegen removed, touching a proto file and invoking
./run drops from about 8s to 6s.

This closes #2043.

* Allow tree-shaking on protobuf types

* Display backend error messages in our ts alert()

* Make sourcemap generation opt-in for ts-run

Considerably slows down build, and not used most of the time.
2023-06-14 22:47:37 +10:00
Damien Elmes
f6fdf64c5d Fix build failure in fresh checkout 2023-06-12 17:10:22 +10:00
Damien Elmes
850e564a99 Fix build failure on Windows 2023-06-12 16:06:40 +10:00
Damien Elmes
d380f3034c Split io.rs into separate crate, and use it in proto build
Will be handy to use it in our other scripts in the future too - thanks
Rumo!

Results of benchmarking ./run before and after these crate splits:

- Touching a proto file leads to a slight increase: about +90ms
- Touching an rslib file leads to a bigger decrease, as there's less to
recompile: about -700ms

And ./ninja test is even better: about +200ms and -3800ms.
2023-06-12 15:47:51 +10:00
Damien Elmes
a83c4a7da7 Move generated protobuf into anki_proto
Due to the orphan rule, this meant removing our usages of impl ProtoStruct,
or converting them to a trait when they were used commonly.

rslib now directly references anki_proto and anki_i18n, instead of
'pub use'-ing them, and we can put the generated files back in OUT_DIR.
2023-06-12 15:47:51 +10:00
RumovZ
651ba88393
Automate schema 11 other duplicates clearing (#2542)
* Skip linting target folder

Contains build files not passing the copyright header check.

* Implicitly clear duplicate keys when serializing

Fixes `originalStockKind` not being cleared from `other`, as it had
mistakenly been added to the field list for `NoteFieldSchema11`.
2023-06-12 11:14:14 +10:00
Damien Elmes
bac05039a7 Move protobuf generation into a separate crate; write .py interface in Rust
A couple of motivations for this:

- genbackend.py was somewhat messy, and difficult to change with the
lack of types. The mobile clients used it as a base for their generation,
so improving it will make life easier for them too, once they're ported.
- It will make it easier to write a .ts generator in the future
- We currently implement a bunch of helper methods on protobuf types
which don't allow us to compile the protobuf types until we compile
the Anki crate. If we change this in the future, we will be able to
do more of the compilation up-front.

We no longer need to record the services in the proto file, as we can
extract the service order from the compiled protos. Support for map types
has also been added.
2023-06-12 09:52:00 +10:00
Damien Elmes
7a9c6172ef When cards are intraday learning queue, don't use original due
https://forums.ankiweb.net/t/backlog-with-no-backlo/30832
2023-06-07 16:20:44 +10:00
Damien Elmes
f758b33346
Default to current deck in csv import if settings allow it (#2527)
* Default to current deck in csv import if settings allow it

Reuses defaults_for_adding(). In the future we might also want to update
the last deck/notetype on successful completion, if entries weren't
specified in the file.

https://forums.ankiweb.net/t/importing-new-notes-to-wrong-deck-in-anki-2-1-63/30598

* Address review feedback from Rumo
2023-05-31 13:47:12 +10:00
Damien Elmes
7f6c410ca5
Various changes to I/O handling (#2513)
* Store coordinates as ratios of full size

* Use single definition for cappedCanvasSize()

* Move I/O review code into ts/image-occlusion

A bit simpler when it's all in one place.

* Reduce number precision, and round to whole pixels

>>> n=10000
>>> for i in range(1, int(n)): assert i == round(float("%0.4f" % (i/n))*n)

* Minor typing tweak

So, it turns out that typing is mostly broken in ts/image-occlusion.
We're importing from fabric which is a js file without types, so types
like fabric.Canvas are resolving to any.

I first tried switching to `@types/fabric`, which introduced a slew of
typing errors. Wasted a few hours trying to address them, before deciding
to give up on it, since the types were not complete. Then found fabric
has a 6.0 beta that introduces typing, and spent some time with that, but
ran into some new issues as it still seems to be a work in progress.
I think we're probably best off waiting until it's out and stabilized
before sinking more effort into this.

* Refactor (de)serialization of occlusions

To make the code easier to follow/maintain, cloze deletions are now decoded/
encoded into simple data classes, which can then be converted to Fabric objects
and back. The data objects handle converting from absolute/normal positions, and
producing values suitable for writing to text (eg truncated floats).

Various other changes:

- Polygon points are now stored as 'x,y x2,y2 ...' instead of JSON in cloze
divs, as that makes the handling consistent with reading from cloze deletion
text.
- Fixed the reviewer not showing updated placement when a polygon was moved.
- Disabled rotation controls in the editor, since we don't support rotation during
review.
- Renamed hideInactive to occludeInactive, as it wasn't clear whether the former
meant to hide the occlusions, or keep them (hiding the content). It's stored
as 'oi=1' in the cloze text.

* Increase canvas size limit, and double pixels when required.

* Size canvas based on container size

This results in sharper masks when the intrinsic image size is smaller
than the container, and more legible ones when the container is smaller than
the intrinsic image size.

By using the container instead of the viewport, we account for margins,
and when the pixel ratio is 1x, the canvas size and container size should
match.

* Disable zoom animation on editor load

* Default to rectangle when adding new occlusions

* Allow users to add/update notes directly from mask editing page

* The mask editor needs to work with css pixels, not actual pixels

The canvas and image were being scaled too large, which impacted
performance.
2023-05-31 13:45:12 +10:00
Damien Elmes
921e8c7985 percent-encoding -> percent-encoding-iri
Closes #2526
2023-05-29 14:46:02 +10:00
Damien Elmes
15dcb09036
Detect incorrect usage of triple slash in TypeScript (#2524)
* Migrate check_copyright to Rust

* Add a new lint to check accidental usages of /// in ts/svelte comments

* Fix a bunch of incorrect jdoc comments

* Move contributor check into minilints

Will allow users to detect the issue locally with './ninja check'
before pushing to CI.

* Make Cargo.toml consistent with other crates
2023-05-26 12:49:44 +10:00
Damien Elmes
7686cb8de8
Fix misaligned image occlusions (#2512)
* Cloze styling is not required in I/O notetype

* Use raw string for IO template

* Rename to notetype.css and use more specific ids

* Move internal i/o styling into runtime

Storing it in the notetype makes it difficult to make changes, and
makes it easier for the user to break.

* Fix misaligned occlusions

At larger screen sizes, the canvas was not increasing above its configured
size, so it ended up being placed top center instead of expanding to fit
the entire container area.

To resolve this, both the image and canvas are forced to the container
size, and the container is constrained to the size of the viewport,
with the same aspect ratio as the image.

Closes #2492
2023-05-23 11:59:50 +10:00
Joel Koen
6b1c799cbf
Expose some collection methods already public in rslib backend (#2510)
* Expose some collection methods already public in rslib backend
2023-05-22 13:44:18 +10:00
Damien Elmes
c520b59311 Support prop queries in filtered decks
https://forums.ankiweb.net/t/phantom-overdue-reviews/30300
2023-05-20 10:49:00 +10:00
Damien Elmes
40a68afad3 Add the ability to search for custom data properties
Closes #2491
2023-05-18 15:54:01 +10:00
Damien Elmes
a19cb75768 Fix broken media importing in non-legacy apkg path
- Ensure our unit tests cover the non-legacy path, and check file
contents and not just existence.
- Pass `compressed` into copy_and_ensure_sha1_set(). We can't just
test for self.sha1.is_none(), as that fails in the case where an existing
media file was found in the legacy path.

https://forums.ankiweb.net/t/anki-media-file-corruption-when-exporting-png-files/30315
2023-05-18 11:33:01 +10:00
Damien Elmes
63fd70ad34 Add a .with_desktop_media_paths() helper 2023-05-18 11:02:02 +10:00
Damien Elmes
cff613bfef Display a more informative message when attempting media op without folder 2023-05-18 10:48:25 +10:00
Damien Elmes
3999c99af7 Fix a panic when user sets a huge learning step 2023-05-11 09:10:22 +10:00
XeR
0d58a04596
Fix sync client ignoring directories (#2490)
* Fix sync client ignoring directories

Current implementation of the sync client does not properly send requests to a
self-hosted sync server if the URL has directories.

If the self-hosted sync URL is `https://example.org/foo/bar/`, Anki is expected
to send requests to `https://example.org/foo/bar/sync/hostKey`. Instead, it will
discard the directories and wrongly send requests to
`https://example.org/sync/hostKey`.

Fixes: e5d5d1d ("Fix panic with invalid sync server URL with port")

* Add XeR to contributors
2023-05-08 11:40:57 +10:00
Damien Elmes
894b7862e3
Improve import messaging when notetype has changed (#2483)
* Fix file extension not being appended on export

Regressed in #2427

* Improve import messaging when notetype has changed

- If the local notes are up to date, we don't need to warn about the
changed notetype, as no updates are required.
- Make it clearer that a changed notetype only affects updates.

Will update the docs as well.
2023-04-28 11:39:18 +10:00
Damien Elmes
f6486da233
Various tweaks to I/O code (#2478)
* Allow user to select I/O notetype instead of enforcing a specific name

* Display a clearer error when I/O note is missing an image

Opening the card layout screen from "manage notetypes" was showing an
error about the Anki version being too old.

Replacement error is not currently translatable.

* Preserve existing notetype when adding I/O notetype

* Add a 'from clipboard' string

The intention is to use this in the future to allow an image occlusion
to be created from an image on the clipboard.

* Tweak I/O init

- Use union type instead of multiple nullable values
- Pass the notetype id in to initialization

* Fix image insertion in I/O note

- The regex expected double quotes, and we were using single ones
- Image tags don't need to be closed

* Use more consistent naming in image_occlusion.proto

* Tweaks to default I/O notetype

- Show the header on the front side as well (I presume this is what
users expect; if not am happy to revert)
- Don't show comments on card (again, I presume users expect to use
this field to add notes that aren't displayed during review, as they
can use back extra for that)

* Fix sticky footer missing background

Caused by earlier CSS refactoring
2023-04-19 15:30:18 +10:00
Damien Elmes
dd13e78eca
Add ability to restore a notetype to its original configuration (#2472)
* Store the original stock notetype kind in the notetype

Will allow us to provide a command to restore a notetype to its default
settings/templates.

* Add a new action to restore a notetype to its original state
2023-04-18 14:07:51 +10:00
Damien Elmes
8f460b2ba9 Use original deck name if card is in filtered deck
https://forums.ankiweb.net/t/inconsistent-read-deck-name-and-seed-from-ctx-will-recognize-the-filtered-deck-as-the-deck-name/29327
2023-04-13 14:46:47 +10:00
Damien Elmes
6fe9728b80 Bring chrono minimum back down for AnkiDroid
Accidentally bumped in recent deps update
2023-04-12 08:45:51 +10:00
Damien Elmes
0466e220f3 Move ascii_percent_encoding into a separate repo
This makes it easier to update independently, and means we don't need
to exclude it from formatting/tests.
2023-04-12 08:45:23 +10:00
Damien Elmes
dc8c4438d7 Update iana-time-zone and windows crates, as windows 0.47 yanked 2023-04-12 08:25:53 +10:00
Damien Elmes
f0d430623c Update to Rumo's latest linkchecker code
cf838122a4 (r107719275)
2023-04-12 07:25:39 +10:00
Damien Elmes
d9624819e9 Add a fully-random review order
https://forums.ankiweb.net/t/bug-the-random-option-in-the-review-sort-order-setting-is-not-truly-random/29199
2023-04-11 16:16:45 +10:00
Damien Elmes
f2e61c8982 Fix a line failing cargo fmt with stable Rust
https://github.com/ankidroid/Anki-Android-Backend/pull/280#issuecomment-1493144833
2023-04-03 09:39:30 +10:00
Damien Elmes
26c640805c Update Rust deps
axum-client-ip excluded, as it will need further work.
2023-03-31 14:38:24 +10:00
Damien Elmes
f497bd6a33 Bump Rust version 2023-03-31 14:11:33 +10:00
Mani
2bf134dc72
Feature image occlusion (#2367)
* add note types with occlusions and image fields

* generate image occlusion cloze div data
- generate div element with data-* atrributes for canvas shape generate for reviewer

* getting image data & deck id and adding notes
the implementation added into backend
- added service index in backend.proto for image occlusion request
- created image_occlusion.proto with required message and service
- implementation in backend for getting image and adding notes, also during editing return imagecloze note and update notes
- add notes to selected deck, if no notetype then add image occlusion notetypes
- reuse notetype from stock notetypes when not exist

* script for generating shapes using canvas api in reviewer
- the flash issues fixed by loading image and using image size to draw canvas, also when image get resized, calculate scale using natural width and canvas width to draw shape at right position
- limit size of canvas for safari

* init image occlusion page in ts and build page
with
- fabricjs for editing shapes
- panzoom for drag and zoom
- pickr for color picker
- build page using web.rs

* implement top toolbar for canvas shapes
- undo & redo tools
- zoom in, zoom out and zoom fit
- group & ungroup
- copy & paste
- set transparency of shapes
- align tools

* implement side toolbar for drawing shapes
add top toolbar and the side toolbar contains following tools
- cursor for selecting shapes
- zoom for drag and zoom shapes in mask editor
- rectangle for creating it
- ellipse for creating it
- polygon for creating it using points
- shape fill color
- question mask color (currently only single color can be added for all shapes)

* add maskeditor page for editing mask
- add side toolbar and sidebar include toptoolbar
- load maskeditor in two mode
     - for adding note using path to image
     - for editing note using note id

* implement note editor page for adding notes
- the note editor page have simple button (B/I/U) and option to toggle html view
- option to select deck for adding notes into that deck
- option to generate to hide all, guess one & hide one, guess one notes

* add image occlusion page
add side toolbar, top toolbar, mask editor and note editor
- option to switch between mask editor and note editor

* implement generates notes and save notes
implemention to show toast components for messages

* removed pickr & implemented color picker component
- remove pickr
- implemented using html5 canvas
- range input for changing color
- another range input for opacity changes
- hex and rgba value support

* rename methods name & rust unwrap safety
- change plural names to singular
- create respone message in proto and return response with imagecloze note or error if not found with note id
- remove image_occlusion from post handler list
- rename service name in mediasrv.py
- rename methods name for image occlusion in backend and image_occlusion
- update frontend also for update functions' names
- handle error in frontend mask-editor.ts, when error getting notes then toast message shown to frontend

* extract to function & add comments & remove global
- extract function in mask-editor.ts to reduce duplicate
- remove unused global from css
- add comments to store.ts explaining usage
- changes id to noteId in lib.ts
- add comments for limitSize, becuase of duplicate implementation

* remove image_occlusion notetype
- remove from stock notetype, stdmodels
- add implementation for notetype to image occlusion
- add i18n for errors

* update smooth scroll, always show cursor tools
- change questionmask to qmask
- make selectable for shape true in all tools to simplify edits and draw shapes
- update image occlusion in reviewer ts to load image properly

* add and get notetype else return errors

* fix: not showing occlusion

* Use a oneof for ImageClozeNoteResponse

Makes it clearer that only one of them can be returned

* Don't crash if image filename not provided

The second unwrap should be ok, as the input is utf8

* Refactor get_image_cloze_note

- fixes crash when note doesn't exist - Ok(None) case was not covered
- decouples business logic from native error->proto error conversion
- no need for original copy
- field[x] is more idiomatic than field.get(x).unwrap()
- don't need mutable access to fields

* Fix crash if image file unreadable

+ Use our read_file helper for better error context

* Add metadata() helper

* Fix crash if file metadata can't be read

* remove color picker, qmask and shape color
- remove strings from ftl
- remove color picker component
- remove from cloze generation
- remove icons for two buttons
- use constant color for shapes

* update color in reviewer and ftl strings

* fix shape position in canvas & add border to shape
- rename mask to inactive shape and active shape color
- border witdth and border color
- change decimal point deserializing string and toFixed(2)
- add thin border in mask editor, may be image background was transparent

* fix shape position in canvas after modified
- do not draw fixed ratio shapes by turn of uniformScaling
- fix rectangle width,height
- fix ellipse rx,ry,width,height
- fix polygon postion and points
- draw outside of canvas also

* fix border width and color in reviewer canvas
- rename variable

* refactor cloze div generate and remove angle

* fix origin when drawn outside of canvas from right

* fix shape at boundry & not include rx,ry rectangle
- move shapes at boundry when pointer is outside of canvas
- include rx, ry for ellipse only
- include points for polygon only

* fix lint errors & update image size in editor canvas based on height and width

* remove unsupported layerX & layerX for touchscreen
- fix shapes at edges

* implemented undo redo with canvas state

- implemented undo redo using fabric canvas events
- polygon is special case and implemented only added and modified event
- rectangle and ellipse have object:added, object:modified and object:removed case
- change id to undo and redo

* remove background image from canvas and used css to put image tag below canvas editor

- set image width and height after adding image

* fix for polygon points, add br in cloze strings, & toogle masks button

- fix shapes at edges
- toggle masks button to show/hide masks
- hide clozes string, it contains <br>
- set height for div container (used 'relative' in css)

* refactor top toolbar, add space and border radius
- rename cursor tools
- add left and right border

* fix undo after undo happen, use transparent color in draw mode
2023-03-29 12:33:19 +10:00
Kieran Black
fe591f6be7
fix stats calendar incorrect due to daylight savings time (#2456)
* fix stats calendar daylight saving time offset bug

Previously, when computing counts for the calendar in the stats menu, it was assumed that days had 86,400 seconds. However, this assumption does not hold true on the day when daylight savings occurs.

* add self to CONTRIBUTORS and about.py

* fix stats calendar anki day to calendar day mapping

Since Anki days don't necessarily roll over at midnight, mapping an Anki day into a calendar day needs to have a linear shift applied. By providing the frontend with access to the scheduler's rollover hour, we can account for this offset.
2023-03-28 15:35:06 +10:00
Damien Elmes
39e503d0aa Add time of date to browser date columns 2023-03-26 14:49:49 +10:00
Abdo
946eb46813
Add option to exclude fields from search (#2394)
* Add option to exclude fields from unqualified searches

* Use temp tables instead

This is slightly faster according to my (very rough) tests.

* Make query a bit more readable

* exclude_from_search -> excludeFromSearch

* Remove superfluous notetypes table from query

* Rework to use field search logic

Thanks to Rumo for the suggestion: https://github.com/ankitects/anki/pull/2394#issuecomment-1446702402

* Exclude fields from field searches too

* Fix error on notetypes with no included fields

* Add back the exclude_fields function

This approach seems to perform better on average than the previously
benchmarked ones.

* Use pure-SQL approach to excluding fields

* Change single field search to use new approach

* Fix flawed any_excluded/sortf_excluded logic

* Support field exclusion in the nc operator

Also fix search text being wrapped in % in the any_excluded=true case.

* Support field exclusion in the re and w operators

* Label field exclusion as being slower

* Unqualified search should be wrapped in % in all cases

I was under the impression that it shouldn't be wrapped with the new
field exclusion logic.

* Remove unnecessary .collect()

* Refactor some complex return types into structs

* Do not exclude fields in field searches

* Add a test and docstring for CollectRanges

* Avoid destructuring in closures

* Remove the exclude_fields function

Minor wording tweaks by dae:
* num_fields -> total_fields_in_note
* fields -> field_ranges_to_search
* fields -> fields_to_search
* SingleField -> FieldQualified
* mid -> ntid
2023-03-20 07:46:03 +10:00
RumovZ
fdfa33fea4
Fix invalid ids on import (#2449) 2023-03-20 07:04:59 +10:00
RumovZ
039ebfeed6
Fix invalid ids on db check (#2445)
* Move open_test_collection into Collection test impl

* Fix invalid ids when checking database

* Report fixed invalid ids

* Improve message when trying to export invalid ids

Also move ImportError due to namespace conflicts with snafu macro.

* Take a human name in DeckAdder::new

* Mention timestamps in the db check message (dae)

Will help to correlate the fix with the message shown when importing/
exporting.
2023-03-19 10:58:35 +10:00
RumovZ
662dbbd4ca
Fix new limit being decremented unduly (#2447) 2023-03-18 11:48:50 +10:00
RumovZ
bd88c6d352
Ensure state mutator runs after card is rendered (#2421)
* Ensure state mutator runs after card is rendered

* Ensure ease buttons only show when states are ready

* Pass context into states mutator

* Revert queuing of state mutator hook

Now that context data is exposed users shouldn't rely on the question
having been rendered anymore.

* Use callbacks instead of signals and timeout

... to track whether the states mutator ran or failed.

* Make mutator async

* Remove State enum

* Reduce requests and compute seed on backend
2023-03-16 16:31:00 +10:00
RumovZ
f9126927b1
Check URLs in TS code (#2436)
* Move help page URLs in ts to new file

* Unnest linkchecker test module

* Check TS help pages

* Add a comment (dae)
2023-03-15 15:46:03 +10:00
RumovZ
c4d5eeb7a3
Revert bury restriction (#2432)
* Remove outdated comment.

* Revert removal of independent bury rules

* Revert 'hierarchical bury modes'

It's now again allowed to bury new, but not review cards e.g., but
siblings of previously gathered card queues will not be buried.

* Tweak docs (dae)

* Add missing Learn and PreviewRepeat queues
2023-03-11 17:49:18 +10:00
RumovZ
0d92bd2ca8
Fix backup creation for collections > 1 GiB (#2423)
Co-authored-by: Damien Elmes <dae@users.noreply.github.com>
2023-03-06 19:56:27 +10:00
RumovZ
84167d6e6b
Export static references from sound tags (#2420) 2023-03-06 19:29:19 +10:00
RumovZ
bb297b95bc
Global new ignore review limit (#2417)
* Add CardAdder test helper

* Add option to have new cards ignore the review limit

Also entails a lot of refactoring because the old code was deeply
coupled to the previous behaviour.

* Add global option to ignore review limit

* Refactor decrementation

* Unify testing
2023-03-06 19:06:12 +10:00
Daniel Tang
e5d5d1d4bd
Fix panic with invalid sync server URL with port (#2412) 2023-03-03 20:28:11 +10:00
Damien Elmes
4a053e5f88 Ensure good is at least previous+1 even if low hard factor set
https://forums.ankiweb.net/t/anki-scheduler-broken/27987/8
2023-03-03 15:34:08 +10:00
Damien Elmes
d9d36078f1 Make some methods/fields public 2023-03-01 19:46:06 +10:00
Damien Elmes
96a606d78c Add custom display for SyncError 2023-03-01 19:46:06 +10:00
Damien Elmes
7ebf8dd84a Implement HttpError directly so that sources can be extracted properly
When disabling the default snafu source handling, <dyn Error>.source()
doesn't work.
2023-03-01 19:46:06 +10:00
Damien Elmes
d5772ac43a Refactor MediaIter
Removes the dependency on a local path, and allows the unicode checks
to be skipped if appropriate.
2023-03-01 18:57:48 +10:00
Damien Elmes
ce35ba123b Allow .or_http_err() to work with anyhow 2023-03-01 18:54:01 +10:00
RumovZ
85aebae573
Add option to tag notes with missing media (#2379)
* Keep track of notes with missing media files

* Add option to tag notes with missing media

* Update ftl/core/media-check.ftl (dae)
2023-02-20 18:48:09 +10:00
Damien Elmes
e9385d2999 Trigger rebuild on STRINGS_JSON change 2023-02-17 19:03:33 +10:00
Damien Elmes
9e0a6d5bf7 Fix card ease being reset on schema upgrade
d20a7d291f introduced a serious regression,
causing cards to be reset to the default ease when upgrading to the latest
schema version. This could also be triggered when exporting a colpkg with
legacy support.
2023-02-17 12:27:19 +10:00
RumovZ
cdfb84f19a
Implement TTS using windows crate (#2371)
* Implement TTS using windows crate

* Use API calls instead of SSML

* Properly stop player in case of TTS error

* Add context to WindowsErrors

* Validate available voices

* Remove TTS text from synthesize error

* Limit maximum buffer size

* Make validation optional and list it in tts filter

* We no longer need the winrt module (dae)

* Use a separate request object so the meaning of the bool is clear (dae)

* Slightly shorten runtime error message (dae)

The default message appears to clip slightly.

* Alternate buffer implementation (dae)

* Use array instead of vec

* Drop the max buffer size to 128k (dae)
2023-02-17 12:26:07 +10:00
RumovZ
5a53da23ca
Deck scoped dupe check (#2372)
* Support limiting dupe check to deck

* Expose deck limiting dupe check on frontend

* Make CSV dupe options configurable with headers

* Rename duplicate file headers

* Change dupe check limit to enum
2023-02-16 17:53:36 +10:00
Damien Elmes
0be31b1b17 Fix excess missed markers in non-Latin text 2023-02-10 15:11:36 +10:00
Damien Elmes
f616bea580 Allow the network timeout to be customized
https://forums.ankiweb.net/t/local-sync-server-collection-exceeds-size-limit/27183/7
2023-02-08 14:33:02 +10:00
RumovZ
ed54cf71ec
Improve HttpError mapping (#2370)
* Use reqwest From impl in HttpError From impl

* Map timeouts to NetworkError (dae)
2023-02-08 12:54:42 +10:00
Damien Elmes
567ba06b5c Show custom data in stats screen
https://forums.ankiweb.net/t/feature-request-display-custom-data-in-card-info/27187
2023-02-07 12:27:43 +10:00
Damien Elmes
92cf5cd898 Don't enforce download size on client
https://forums.ankiweb.net/t/local-sync-server-collection-exceeds-size-limit/27183/6
2023-02-07 11:58:07 +10:00
RumovZ
855dc9d75b
Add Rust bin to deprecate unused ftl entries (#2364)
* Add Rust bin to deprecate unused ftl entries

* Align function names with bin names

* Support passing in multiple ftl roots

* Use source instead of jsons for deprecating

* Fix CargoRun not working more than once (dae)

* Add ftl:deprecate (dae)

* Deprecate some strings (dae)

This is not all of the strings that are currently unused

* Check json files before deprecating; add allowlist (dae)

The scheduler messages we'll probably want to reuse for the v2->v3
transition, so I'd prefer to keep them undeprecated for now.

* Deprecate old bury options (dae)

* Support gathering usages from Kotlin files for AnkiDroid (dae)

* Update json scripts (dae)

* Remove old deprecation headers

* Parameterize JSON roots to keep

* Tweak deprecation message (dae)
2023-02-07 11:56:14 +10:00
RumovZ
c824dd0b90
Disable burying of previously gathered cards (#2361)
* Enforce hierarchical bury modes

Interday learning burying is only allowed if review burying is enabled
and review burying is only allowed if new burying is enabled.
Closes #2352.

* Switch front end to new bury modes

* Wording tweaks (dae)

* Hide interday option if using v2 scheduler (dae)
2023-02-06 12:02:27 +10:00
Damien Elmes
6a97efe7af Deck-specific limits should be ignored when the v2 scheduler is enabled
Closes #2365
2023-02-06 11:02:26 +10:00
RumovZ
f3ef242bc5
Support UTF-8-BOM when importing CSV (#2360)
The csv crate already supports it, but the meta line parsing didn't.
2023-02-05 11:53:21 +10:00
Damien Elmes
32ec6e06f6 Fix comparison being collapsed when extra characters in input 2023-02-02 19:13:12 +10:00
Damien Elmes
321402a6d0 Revert to blanking out missed chars in provided text
Quite a few users seem surprised to have missed characters appear in
their input text
2023-02-02 19:13:11 +10:00
Damien Elmes
2c952cf3af Wrap expected text in code block when no answer provided 2023-02-02 18:01:23 +10:00
Kaben Nanlohy
77bba533ea
Allow burying cards in browser (#2351)
* Allow burying cards in browser

This code is based on existing "toggle suspend" command in browser.

- Adds "toggle bury" command to browser cards menu.
- Adds "browsing-toggle-bury" to core translation. Only english-language.
- Adds "buried" coloring to rows for buried cards in browser table.

Not yet done:

- Keyboard shortcut for "toggle bury" action.
- Non-english translations.

* Add contributor as requested in CONTRIBUTORS.

* Fix formatting in browser_table.rs.

* Add keyboard shortcut to "toggle bury" command.

This adds keyboard shortcut "ctrl-shift-j" to "toggle bury" command in
browser cards menu.

* Simplify logic for color of buried-card rows.
2023-01-30 19:21:06 +10:00
Damien Elmes
d20a7d291f Validate and clamp deck config when loading
Fixes #2353
2023-01-28 21:51:47 +10:00
Damien Elmes
17480a2c80 Use HTTP/1.1 for syncing
HTTP2 + a request body size not being declared up front was creating extra
work for AnkiWeb.
2023-01-28 21:51:47 +10:00
Damien Elmes
4142de57e2 Fix clean build failure due to protoc change
da7d4dd2fc changed the name of the env
var in .cargo/config.toml, causing the check in setup_protoc() to think
a custom path had been provided, which skipped the download and extract
step.
2023-01-26 09:33:39 +10:00
Damien Elmes
17b33f8298
Use Rust nightly for formatting (#2348)
* Support specifying a working dir to a build command

* Use nightly for formatting

* Pass valid TERM in from environment

Rustfmt depends on a valid setting, and not just the var to be non-empty.

* Wrap comment
2023-01-25 23:35:53 +10:00
Mani
da7d4dd2fc
Use a ninja variable for Protoc binary (#2345)
* Use a ninja variable for Protoc binary

* fix whitespace
2023-01-23 20:44:47 +10:00
Damien Elmes
dc0185720a Fix outer whitespace not being trimmed in type answer 2023-01-23 17:20:35 +10:00