Commit Graph

1408 Commits

Author SHA1 Message Date
Damien Elmes
df93ed0b15 update TR references with args in *.ts; fix average answer time 2021-03-26 19:10:39 +10:00
Damien Elmes
3d366d5264 add types to some more Fluent variables 2021-03-26 16:52:54 +10:00
Damien Elmes
8cc6758eb1 declare variables with some common names as int instead of a union 2021-03-26 16:33:53 +10:00
Damien Elmes
3199fa80d5 delimit variables in docstrings to make them easier to read 2021-03-26 14:38:30 +10:00
Damien Elmes
8294b18c68 catch variables only used in plural selection 2021-03-26 14:20:44 +10:00
Damien Elmes
3c19708684
Merge pull request #1094 from shaunren/fix-tts-html
Fix extraneous whitespaces from strip_html_for_tts
2021-03-26 11:00:41 +10:00
Damien Elmes
c697eb1086 embed strings.json into write_json.rs
It appears that including the build script as a dependency is not
enough to make the file available at runtime, so the build breaks
if ts/ is built first.
2021-03-26 09:55:21 +10:00
Damien Elmes
9aece2a7b8 rework translation handling
Instead of generating a fluent.proto file with a giant enum, create
a .json file representing the translations that downstream consumers
can use for code generation.

This enables the generation of a separate method for each translation,
with a docstring that shows the actual text, and any required arguments
listed in the function signature.

The codebase is still using the old enum for now; updating it will need
to come in future commits, and the old enum will need to be kept
around, as add-ons are referencing it.

Other changes:

- move translation code into a separate crate
- store the translations on a per-file/module basis, which will allow
us to avoid sending 1000+ strings on each JS page load in the future
- drop the undocumented support for external .ftl files, that we weren't
using
- duplicate strings in translation files are now checked for at build
time
- fix i18n test failing when run outside Bazel
- drop slog dependency in i18n module
2021-03-26 09:41:32 +10:00
Shaun Ren
1f3751d191 Fix extraneous whitespaces from strip_html_for_tts 2021-03-25 11:44:42 -04:00
Damien Elmes
d382b33585 rework filtered deck screen & search errors
- Filtered deck creation now happens as an atomic operation, and is
undoable.
- The logic for initial search text, normalizing searches and so on
has been pushed into the backend.
- Use protobuf to pass the filtered deck to the updated dialog, so
we don't need to deal with untyped JSON.
- Change the "revise your search?" prompt to be a simple info box -
user has access to cancel and build buttons, and doesn't need a separate
prompt. Tweak the wording so the 'show excluded' button should be more
obvious.
- Filtered decks have a time appended to them instead of a number,
primarily because it's easier to implement. No objections going back to
the old behaviour if someone wants to contribute a clean patch.
The standard de-duplication will happen if two decks are created in the
same minute with the same name.
- Tweak the default sort order, and start with two searches. The UI
will still hide the second search by default, but by starting with two,
the frontend doesn't need logic for creating the starting text.
- Search errors now have their own error type, instead of using
InvalidInput, as that was intended mainly for bad API calls. The markdown
conversion is done when the error is converted from the backend, allowing
errors to printed as a string without any special handling by the calling
code.

TODO: when building a new filtered deck, update_active() is clobbering
the undo log when the overview is refreshed
2021-03-24 22:04:35 +10:00
Damien Elmes
12597e1094 support undo of filtered deck build/empty 2021-03-24 12:56:06 +10:00
Damien Elmes
2a168adb66 move filter code into scheduler/ 2021-03-23 23:55:28 +10:00
Damien Elmes
b5c58ff8e6 nest search term message/order enum 2021-03-23 23:28:50 +10:00
Damien Elmes
ff0d346927 move browser_row method into search service
For want of a better place to put it. Also split the node conversion
into a separate file.
2021-03-23 18:55:05 +10:00
Damien Elmes
95dea7f20a move activeCols into config/ 2021-03-23 18:40:50 +10:00
Damien Elmes
5fd79d9246
Merge pull request #1082 from RumovZ/backend-rows
Backend rows
2021-03-23 18:31:42 +10:00
Damien Elmes
01161c8ed2 use perform_op() for deck creation 2021-03-22 23:17:07 +10:00
RumovZ
03b9667789 Use raw sort field text in note_field_str() ...
... instead of the preprocessed note.sort_field. That means we always
have to load the note with fields.
2021-03-22 12:12:52 +01:00
RumovZ
9151bfb53e Return input if decode_entities() encounters error 2021-03-22 12:08:22 +01:00
Damien Elmes
0123a382ec deck rename with perform_op() 2021-03-22 20:38:51 +10:00
Damien Elmes
6a11c0398c use perform_op() for deck drag&drop 2021-03-22 18:23:56 +10:00
RumovZ
de73232f0d Fix date_string using FixedOffset instead of Local 2021-03-22 08:50:54 +01:00
Damien Elmes
7273996041 fix note importing detecting changes due to unicode differences
https://forums.ankiweb.net/t/python-checksum-rust-checksum/8195/16
2021-03-22 10:56:24 +10:00
RumovZ
255daad820 Fix card_due_str() 2021-03-21 21:18:56 +01:00
RumovZ
c91182b248 Strip question from answer string 2021-03-21 21:17:38 +01:00
RumovZ
af90bbf879 Check original_deck_id rather than original_deck()
in card_due_str() as we don't necessarily have to load that deck.
2021-03-20 18:12:00 +01:00
RumovZ
1ab0d4dff8 Refactor browser_rows.rs
* Make RowContext taking functions methods
* Make RowContext constructor a method
* Rename 'with_fields' to 'card_render'
2021-03-20 18:02:41 +01:00
RumovZ
04ae6f727b Rename browser_rows/RowColor to Color 2021-03-20 17:31:16 +01:00
RumovZ
b86d683f17 Rename render_card_inner() to render_card() 2021-03-20 17:26:30 +01:00
RumovZ
7425aa6b58 Refactor search/browser.rs to browser_rows.rs 2021-03-20 17:20:49 +01:00
RumovZ
c68a6131e0 Add backend routine for browser rows 2021-03-20 12:02:51 +01:00
RumovZ
436269b701 Add backend mod for browser rows 2021-03-20 12:02:18 +01:00
RumovZ
e931a429b3 Add html_to_text_line() on backend 2021-03-20 12:00:45 +01:00
RumovZ
1823c0dda4 Add get_note_without_fields() from storage 2021-03-20 11:59:45 +01:00
Damien Elmes
f7e4b6d822 fix spurious warning in db check for v1 scheduler+non-zero lapse ivl%
https://forums.ankiweb.net/t/invalid-property-on-card-not-resolving-via-recommended-check-database/8430
2021-03-19 22:57:43 +10:00
Damien Elmes
4c61c92806 speed up tag drag&drop and finish tag tidyup
approx 4x speedup when reparenting 10-15 tags and their children at once
2021-03-19 19:45:21 +10:00
Damien Elmes
9c2bff5b6d change bulk_update() into find_and_replace_tag()
Now behaves the same way as standard find&replace:
- Will match substrings
- Regexs can be used to match multiple items; we no longer split
input on spaces.
- The find&replace dialog has been updated to add tags to the field
list.
2021-03-19 19:45:21 +10:00
Damien Elmes
b287cd5238 speed up "add tags" and avoid usage of regex 2021-03-19 19:45:21 +10:00
Damien Elmes
08895c58d9 introduce separate routine to remove tags from specific notes
We were (ab)using the bulk update routine to do deletions, but that
code was really intended to be used for finding&replacing, where an
exact match is not a requirement.
2021-03-19 19:45:21 +10:00
Damien Elmes
33d467e688 split tags.rs up 2021-03-19 19:45:21 +10:00
Damien Elmes
09076da937 make tag deletion undoable, and speed it up
- ~4x faster than before on tag tree with 30k notes
- remove the separate clear_tag() backend method
2021-03-19 19:45:21 +10:00
Damien Elmes
157b74b671 make tag renaming undoable, and speed it up
~3x speedup when renaming a tag that's on 25k notes
2021-03-19 19:45:21 +10:00
Damien Elmes
0331d8b588 make reposition undoable 2021-03-19 19:45:21 +10:00
Damien Elmes
de668441b5 clear_unused_tags and browser redraw improvements
- clear_unused_tags() is now undoable, and returns the number of removed
notes
- add a new mw.query_op() helper for immutable queries
- decouple "freeze/unfreeze ui state" hooks from the "interface update
required" hook, so that the former is fired even on error, and can be
made re-entrant
- use a 'block_updates' flag in Python, instead of setUpdatesEnabled(),
as the latter has the side-effect of preventing child windows like
tooltips from appearing, and forces a full redrawn when updates are
enabled again. The new behaviour leads to the card list blanking out
when a long-running op is running, but in the future if we cache the
cell values we can just display them from the cache instead.
- we were indiscriminately saving the note with saveNow(), due to the
call to saveTags(). Changed so that it only saves when the tags field
is focused.
- drain the "on_done" queue on main before launching a new background
task, to lower the chances of something in on_done making a small query
to the DB and hanging until a long op finishes
- the duplicate check in the editor was executed after the webview loads,
leading to it hanging until the sidebar finishes loading. Run it at
set_note() time instead, so that the editor loads first.
- don't throw an error when a long-running op started with with_progress()
finishes after the window it was launched from has closed
- don't throw an error when the browser is closed before the sidebar
has finished loading
2021-03-19 19:45:21 +10:00
Damien Elmes
6b0fe4b381 undoable ops now return changes directly; add new *_ops.py files
- Introduced a new transact() method that wraps the return value
in a separate struct that describes the changes that were made.
- Changes are now gathered from the undo log, so we don't need to
guess at what was changed - eg if update_note() is called with identical
note contents, no changes are returned. Card changes will only be set
if cards were actually generated by the update_note() call, and tag
will only be set if a new tag was added.
- mw.perform_op() has been updated to expect the op to return the changes,
or a structure with the changes in it, and it will use them to fire the
change hook, instead of fetching the changes from undo_status(), so there
is no risk of race conditions.
- the various calls to mw.perform_op() have been split into separate
files like card_ops.py. Aside from making the code cleaner, this works
around a rather annoying issue with mypy. Because we run it with
no_strict_optional, mypy is happy to accept an operation that returns None,
despite the type signature saying it requires changes to be returned.
Turning no_strict_optional on for the whole codebase is not practical
at the moment, but we can enable it for individual files.

Still todo:
- The cursor keeps moving back to the start of a field when typing -
we need to ignore the refresh hook when we are the initiator.
- The busy cursor icon should probably be delayed a few hundreds ms.
- Still need to think about a nicer way of handling saveNow()
- op_made_changes(), op_affects_study_queue() might be better embedded
as properties in the object instead
2021-03-19 19:45:21 +10:00
Damien Elmes
30c7cf1fdd fade out webview when pending updates; do some reviewer updates immediately
Issues that need fixing:
- when the editor saves the note with perform_op(), if it isn't modified,
no new undo entry is created, and perform_op then returns the changes
made by the previous operation instead
- the approach of fetching the last action in a subsequent backend
method is unsound, as another queued operation may sneak in first before
we have a chance to query the result - it would be better if it were
returned in a single atomic action
- redrawing the current card while editing is likely to make sound
autoplay annoyingly, and it has an unpleasant redraw. We may be better off
fading it out instead

Side note: the editor cursor moves to the start of the field when the
note is updated in another window - it might be nicer to have it move
the cursor to the end instead.
2021-03-19 19:45:21 +10:00
Damien Elmes
1e849316be more reset refactoring
'card modified' covers the common case where we need to rebuild the
study queue, but is also set when changing the card flags. We want to
avoid a queue rebuild in that case, as it causes UI flicker, and may
result in a different card being shown. Note marking doesn't trigger
a queue build, but still causes flicker, and may return the user back
to the front side when they were looking at the answer.

I still think entity-based change tracking is the simplest in the
common case, but to solve the above, I've introduced an enum describing
the last operation that was taken. This currently is not trying to list
out all possible operations, and just describes the ones we want to
special-case.

Other changes:

- Fire the old 'state_did_reset' hook after an operation is performed,
so legacy code can refresh itself after an operation is performed.
- Fire the new `operation_did_execute` hook when mw.reset() is called,
so that as the UI is updated to the use the new hook, it will still
be able to refresh after legacy code calls mw.reset()
- Update the deck browser, overview and review screens to listen to
the new hook, instead of relying on the main window to call moveToState()
- Add a 'set flag' backend action, so we can distinguish it from a
normal card update.
- Drop the separate added/modified entries in the change list in
favour of a single entry per entity.
- Add typing to mw.state
- Tweak perform_op()
- Convert a few more actions to use perform_op()
2021-03-19 19:45:21 +10:00
Damien Elmes
112cbe8b59 experiment with finer-scoped reset in perform_op()
Basic proof of concept, where the 'delete note' operation in the
reviewer has been updated to use mw.perform_op(). Instead of manually
calling .reset() afterwards, a summary of the changes is returned as
part of the undo status query, and various parts of the GUI can listen
to gui_hooks.operation_did_execute and decide whether they want to
redraw based on the scope of the changes. This should allow the sidebar
to selectively redraw just the tags area in the future for example.

Currently we're just listing out all possible areas that might be changed;
in the future we could theoretically inspect the specific changes in the
undo log to provide a more accurate report (avoiding refreshing the tags
list when no tags were added for example).

You can test it out by opening the browse screen while studying, and
then deleting the current card - the browser should update to show (deleted)
on the cards due the earlier change.

If going ahead with this, aside from updating all the screens that currently
listen for resets, some thought will be required on how we can integrate
it with legacy code that expects to called when resets are made, and expects
to call .reset() when it makes changes.

Thoughts?
2021-03-19 19:45:21 +10:00
Damien Elmes
7fab319dad derive reset scope from last undoable operation 2021-03-19 19:45:21 +10:00
Damien Elmes
90526c61cd move ops.rs out of undo/ 2021-03-19 19:45:21 +10:00
Damien Elmes
8fc43956c2 move collection mtime bump into backend
Fixes the following issue:
- some code directly modifies the database, causing modified_in_python
to be set to true
- an undoable operation is run, which calls autosave() at the end
- autosave() notices there's an undoable operation, and commits immediately
- because modified_in_python was true, col.mtime was bumped in Python
- that invalidated the undo queue, preventing the operation from being
undone
2021-03-19 19:45:21 +10:00
Arthur Milchior
9661684ca3 If a template name contains only quote, show relevant error message
This is for the sake of the consistency with the last commit
2021-03-14 02:10:48 +01:00
Arthur Milchior
dd48b2dff0 Return meaningful message if a field is empty after normalizing
This correct the probably rare bug as follow:

I got a note type with a field whose name is "\".

When I made any change to this note type, even unrelated, I get a message stating that there is an empty field. This is
strange because I can see it to be false. Investigating show that "\" is normalized to empty field. This ensure that
it's shown
2021-03-14 02:10:32 +01:00
Damien Elmes
bd959731d7
Merge pull request #1067 from RumovZ/regex-err
Fix regex error formatting and search error escaping
2021-03-13 10:16:10 +10:00
RumovZ
e033f21767 Fix markdown escaping in search errors 2021-03-12 20:32:38 +01:00
RumovZ
2078a094f4 Fix formatting of invalid regex error
Preserve whitespace, special characters and use monospace font.
2021-03-12 20:31:23 +01:00
Damien Elmes
28994458e9 add indexes to graves table to speed up undo 2021-03-12 18:59:24 +10:00
Damien Elmes
2ffc055487 'change deck' now undoable 2021-03-12 16:27:57 +10:00
Damien Elmes
7b7d7e8330 consume original card when updating 2021-03-12 16:20:58 +10:00
Damien Elmes
24762261d9 make 'forget card' undoable; remove checkpoint() in set_due_date 2021-03-12 16:13:50 +10:00
Damien Elmes
3b067c7a66 limit initial sort selection to new cards
https://github.com/ankidroid/Anki-Android/issues/8172
2021-03-12 14:58:19 +10:00
Damien Elmes
c1316bb65f 'set due date' now undoable 2021-03-12 14:50:31 +10:00
Damien Elmes
0ab87b7339 enable deck removal undo again 2021-03-11 22:24:12 +10:00
RumovZ
f4c2fe6485 Merge branch 'master' into sidebar-tools 2021-03-11 12:08:32 +01:00
Damien Elmes
e20c5ed9c5 deck drag&drop undo 2021-03-11 20:02:16 +10:00
Damien Elmes
984e2c2666 add a separate 'rename deck' method 2021-03-11 19:24:54 +10:00
RumovZ
f1dd010489 Remove deck remove prompt but show card count 2021-03-11 09:52:11 +01:00
RumovZ
186a0202ea Show tooltip instead of prompt for removing tags 2021-03-11 09:14:50 +01:00
Damien Elmes
4bd120cc4b split out remaining rpc methods
@david-allison-1 note this also changes the method index to start at
0 instead of 1
2021-03-11 17:04:32 +10:00
Damien Elmes
378b116977 split out stats, media and search 2021-03-11 16:16:40 +10:00
Damien Elmes
cd14987812 split out tags, deck config and card rendering 2021-03-11 16:05:06 +10:00
Damien Elmes
1b8d6c6e85 split out sync, notetypes and config code 2021-03-11 15:47:31 +10:00
Damien Elmes
5df684fa6b rework backend codegen to support multiple services; split out sched
Rust requires all methods of impl Trait to be in a single file, which
means we had a giant backend/mod.rs covering all exposed methods. By
using separate service definitions for the separate areas, and updating
the code generation, we can split it into more manageable chunks -
this commit starts with the scheduling code.

In the long run, we'll probably want to split up the protobuf file into
multiple files as well.

Also dropped want_release_gil() from rsbridge, and the associated method
enum. While it allows us to skip the thread save/restore and mutex unlock/
lock, it looks to only be buying about 2.5% extra performance in the
best case (tested with timeit+format_timespan), and the majority of
the backend methods deal with I/O, and thus were already releasing the
GIL.
2021-03-11 14:51:29 +10:00
RumovZ
e1db8e1da1 Borrow dids in remove_decks_and_child_decks 2021-03-10 15:56:54 +01:00
Damien Elmes
c3b0589bb4 make sure we invalidate cache when undoing deck add 2021-03-10 23:59:40 +10:00
Damien Elmes
e122f8ae0d undo support for deck adding/removing
Work in progress - still to do:
- renames appear as 'Update Deck' - easiest way to solve it would
be to have a separate backend method for renames
- drag&drop of decks not yet undoable
- since the undo status is updated after the backend method ends,
the older checkpoint() calls need to be replaced with an
update_undo_status() at the end of the call - if we just remove the
checkpoint, then the menu doesn't get updated
2021-03-10 23:50:11 +10:00
RumovZ
0c2ac4ba04 Merge branch 'master' into sidebar-tools 2021-03-10 10:34:36 +01:00
Damien Elmes
6b1dd9ee19 expand backend Preferences and make undoable
- moved 'default to current deck when adding' into prefs
- move some profile options into the collection config, so they're
undoable and will sync. There is (currently) no automatic migration
from the old profile settings, meaning users will need to set the
options again if they've customized them.
- tidy up preferences.py
- drop the deleteMedia option that was not exposed in the UI
2021-03-10 18:51:03 +10:00
Damien Elmes
24ad7c1f35 inline scheduling settings into preferences 2021-03-10 14:11:59 +10:00
Damien Elmes
4bcd2b68ab roll back slog-term due to Windows break (2/2)
The cargo.toml update was missing from the previous commit, and term
was included directly when it didn't need to be.
2021-03-10 13:28:32 +10:00
Damien Elmes
77accb458f roll back slog-term due to Windows breakage 2021-03-10 12:22:11 +10:00
Damien Elmes
d2f48e1663 move sync/err backend code into separate files 2021-03-10 11:53:27 +10:00
Damien Elmes
30865eae51 move progress and search backend code into separate files 2021-03-10 11:53:27 +10:00
Damien Elmes
96940f0527 undo support for config entries 2021-03-10 11:53:27 +10:00
Damien Elmes
ce243c2cae Simplify note adding and the deck/notetype choosers
The existing code was really difficult to reason about:

- The default notetype depended on the selected deck, and vice versa,
and this logic was buried in the deck and notetype choosing screens,
and models.py.
- Changes to the notetype were not passed back directly, but were fired
via a hook, which changed any screen in the app that had a notetype
selector.

It also wasn't great for performance, as the most recent deck and tags
were embedded in the notetype, which can be expensive to save and sync
for large notetypes.

To address these points:

- The current deck for a notetype, and notetype for a deck, are now
stored in separate config variables, instead of directly in the deck
or notetype. These are cheap to read and write, and we'll be able to
sync them individually in the future once config syncing is updated in
the future. I seem to recall some users not wanting the tag saving
behaviour, so I've dropped that for now, but if people end up missing
it, it would be simple to add as an extra auxiliary config variable.
- The logic for getting the starting deck and notetype has been moved
into the backend. It should be the same as the older Python code, with
one exception: when "change deck depending on notetype" is enabled in
the preferences, it will start with the current notetype ("curModel"),
instead of first trying to get a deck-specific notetype.
- ModelChooser has been duplicated into notetypechooser.py, and it
has been updated to solely be concerned with keeping track of a selected
notetype - it no longer alters global state.
2021-03-10 11:53:27 +10:00
Damien Elmes
c0e939ceb6 split config.rs up 2021-03-10 11:53:27 +10:00
Damien Elmes
545cb76018 native stringkey 2021-03-10 11:53:27 +10:00
Damien Elmes
1dea8babee use native boolkey instead of separate getters/setters
Makes it easier to add new config settings in the future, especially
if we don't need to export them via protobuf.
2021-03-10 11:53:27 +10:00
Damien Elmes
b67947cfbc use strum for config keys 2021-03-10 11:53:27 +10:00
Damien Elmes
265e91c13f add strum crate 2021-03-10 11:53:27 +10:00
Damien Elmes
0207f6c0ab update Rust deps 2021-03-10 11:53:27 +10:00
Damien Elmes
455d609109 when only sort field changed, we don't need to update ordinals 2021-03-10 11:53:27 +10:00
Damien Elmes
3d0ddc8539 make flag changes in the reviewer undoable
This splits update_card() into separate undoable/non-undoable ops
like the change to notes in b4396b94abdeba3347d30025c5c0240d991006c9

It means that actions get a blanket 'Update Card' description - in the
future we'll probably want to either add specific actions to the backend,
or allow an enum or string to be passed in to describe the op.

Other changes:
- card.flush() can no longer be used to add new cards. Card creation
is only supposed to be done in response to changes in a note's fields,
and this functionality was only exposed because the card generation
hadn't been migrated to the backend at that point. As far as I'm aware,
only Arthur's "copy notes" add-on used this functionality, and that should
be an easy fix - when the new note is added, the associated cards will
be generated, and they can then be retrieved with note.cards()
- tidy ups/PEP8
2021-03-10 11:53:27 +10:00
Damien Elmes
d4765a301f coalesce note updates; avoid unnecessary saving due to mtime changes 2021-03-10 11:53:27 +10:00
Damien Elmes
ecea2161e3 dispatch undo operations via enum instead of trait
To coalesce successive note edits into a single undo op we'll need to
be able to get the original Undoable type, which is awkward to do with
a trait object.
2021-03-10 11:53:27 +10:00
Damien Elmes
d70e35e0a2 move remaining undo ops into separate files 2021-03-10 11:53:27 +10:00
Damien Elmes
ad74e26c84 move note undo into separate file 2021-03-10 11:53:27 +10:00
Damien Elmes
d2ebfc5482 move card undo into separate file 2021-03-10 11:53:27 +10:00
Damien Elmes
7900cc6868 fix some clippy lints 2021-03-10 11:53:27 +10:00
Damien Elmes
f1a1b0891e make mark toggling undoable
- note.flush() behaves like before, as otherwise actions or add-ons
that perform bulk flushing would end up creating an undo entry for
each note
- added col.update_note() to opt in to the new behaviour
- tidy up the names of some related routines
2021-03-10 11:53:27 +10:00
Damien Elmes
bec77fd420 undo support for bulk tag add/remove 2021-03-10 11:47:53 +10:00
Damien Elmes
49a1970399 note deletion undo; refactoring
- transact() now automatically clears card queues unless an op
opts-out (and currently only AnswerCard does). This means there's no
risk of forgetting to clear the queues in an operation, or when undoing/
redoing
- CollectionOp->UndoableOp
- clear queues when redoing "answer card", instead of clearing redo
when clearing queues
2021-03-10 11:47:53 +10:00
Damien Elmes
f4d931131b undo support for note removing 2021-03-10 11:47:53 +10:00
Damien Elmes
40aff4447a undo support for note adding 2021-03-10 11:47:53 +10:00
Damien Elmes
105ce94dd4 undo unbury/unsuspend 2021-03-10 11:47:53 +10:00
Damien Elmes
77e4526718 fix notes being saved indiscriminately
caused by a commit a few days ago:

f61827657630ec0e6bbc5ca58c1a5ca131aede56
2021-03-10 11:47:53 +10:00
Damien Elmes
41779c1aad implement bury/suspend undo 2021-03-10 11:47:53 +10:00
Damien Elmes
b466f0ce90 rework undo
- use dataclasses for the review/checkpoint undo cases, instead of the
nasty ad-hoc list structure
- expose backend review undo to Python, and hook it into GUI
- redo is not currently exposed on the GUI, and the backend can only
cope with reviews done by the new scheduler at the moment
- the initial undo prototype code was bumping mtime/usn on undo, but
that was not ideal, as it was breaking the queue handling which expected
the mtime to match. The original rationale for bumping mtime/usn was
to avoid problems with syncing, but various operations like removing
a revlog can't be synced anyway - so we just need to ensure we clear the
undo queue prior to syncing
2021-03-10 11:47:53 +10:00
Damien Elmes
67c490a8dc support undoing deck mutations
This required refactoring the deck code a bit to split up the 'update'
and 'add' cases better.
2021-03-10 11:47:53 +10:00
Damien Elmes
c9eeb91e0a initial work on undoing reviews+burying siblings
- fetch sfld and csum when fetching notes, to make it cheaper
to write them back out unmodified
- make `fields` private, and access it via accessors, so we can
still catch when fields have been mutated without calling
prepare_for_update()
- fix python importing code passing a string in as the checksum
2021-03-10 11:47:53 +10:00
Damien Elmes
359d0bc331 use native struct for QueuedCard 2021-03-10 11:47:53 +10:00
Damien Elmes
7ce75479b2 fix sync download failing when temp dir on different mount
https://forums.ankiweb.net/t/problems-with-2-1-41-on-arch-linux/8103
2021-03-09 11:44:49 +10:00
Damien Elmes
b81e2c0265 Ensure we purge caches when rolling back
Fixes #1056
2021-03-08 10:39:18 +10:00
Damien Elmes
59ec485852 handle duplicate keys in schema 11 deckconf 2021-03-04 11:52:15 +10:00
Damien Elmes
07989afa38 fix infinite loop on card answer when parent is missing deck 2021-03-04 11:03:09 +10:00
RumovZ
25d57574c9 Enable removal of multiple tags from the sidebar 2021-03-02 11:05:16 +01:00
Damien Elmes
de7baa80bd switch to 4 buttons when previewing in test scheduler
- Currently we just use 1.5x and 2x the normal preview delay; we could
change this in the future.
- Don't try to capture the current state; just use a flag to denote
exit status.
- Show (end) when exiting
2021-03-01 23:47:00 +10:00
Damien Elmes
c74a71a6d7 interval sorting 2021-03-01 21:48:14 +10:00
Damien Elmes
f764753920 show the empty card message on the back of the card as well
Otherwise when viewing the back side, user can end up with an empty
screen.
2021-03-01 15:32:31 +10:00
Damien Elmes
88e2aba93c fix inconsistent test handling on Windows
Bazel sets TZ to UTC when running tests, so the tests are reproducible.
But it seems like the Rust time crate was not honoring it, and using
the configured timezone instead. "Fix" by forcing UTC when testing, as
we already special-case a test run.
2021-03-01 13:36:36 +10:00
Damien Elmes
2c6b6734b5 experimental queue building
Still a work in progress, and hidden behind a feature flag.
2021-03-01 12:18:21 +10:00
Damien Elmes
3bddf99ba1 remove local tz test
This was breaking some of the unit tests when they happened to
complete in a particular order
2021-03-01 10:59:01 +10:00
Damien Elmes
32af54cd4d catch attempts to nest under a filtered deck; don't show traceback 2021-03-01 09:58:12 +10:00
Damien Elmes
5564fd9e13
Merge pull request #1040 from RumovZ/deck-name-err
Catch deck rename errors and localise warnings
2021-03-01 09:40:55 +10:00
RumovZ
f7c20e40b5 Make backend deck deletion take vec of ids 2021-02-26 19:52:02 +01:00
RumovZ
ef925a88d6 Add filtered deck error localisation on backend 2021-02-26 11:32:26 +01:00
Damien Elmes
c0b9285923 move cards out of the new queue on filtered deck upgrade 2021-02-26 19:16:18 +10:00
Damien Elmes
37429f1580 add test to the previewing code 2021-02-23 17:35:20 +10:00
Damien Elmes
02e23e1063 split rescheduling_filter, and more tidyups 2021-02-23 17:35:20 +10:00
Damien Elmes
b887057448 split review/learn/new/relearn 2021-02-23 17:35:20 +10:00
Damien Elmes
e74210717a split state fetching, revlog and preview code out 2021-02-23 17:35:20 +10:00
Damien Elmes
6a44269280 sched->scheduler 2021-02-23 17:35:20 +10:00
Damien Elmes
e33f632169 answering.rs tidyups 2021-02-23 17:35:20 +10:00
Damien Elmes
f165576992 implement leech handling
Also change the default for new users to "tag only"
2021-02-23 17:35:20 +10:00
Damien Elmes
97300a16bf implement fuzzing
Notes:

- The fuzz seed is now derived from the card id and # of reps, so
if a card is undone and done again, the same fuzz will be used.
- The intervals shown on the answer buttons now include the fuzz, instead
of hiding it from the user. This will prevent questions about due dates
being different to what was shown on the buttons, but will create
questions about due dates being different for cards with the same
interval, and some people may find it distracting for learning cards.
The new approach is easier to reason about, but time will tell
whether it's a net gain or not.
- The env var we were using to shift the clock away from rollover for
unit tests has been repurposed to also disable fuzzing, which simplifies
the tests.
- Cards in filtered decks without scheduling now have the preview delay
fuzzed.
- Sub-day learning cards are mostly fuzzed like before, but will apply
the up-to-5-minutes of fuzz regardless of the time of day.
- The answer buttons now round minute values, as the fuzz on short
intervals is distracting.
2021-02-22 21:31:53 +10:00
Damien Elmes
e1e552ff93 if learning step crossed day boundary, reflect that on the answer button 2021-02-22 21:31:53 +10:00
Damien Elmes
3af5221895 plug new answering code in
This is not the way the code is intended to be used, but making it
conform to the existing API allows us to exercise the existing unit
tests and provides partial backwards compatibility.

- Leech handling is currently broken
- Fix answered_at in wrong units, and not being used
2021-02-22 21:31:53 +10:00
Damien Elmes
f50cd43e75 fix incorrect nested review counts in v2 scheduler
https://forums.ankiweb.net/t/problem-with-anki-subdecks/7689
2021-02-21 22:48:14 +10:00
Damien Elmes
53d9433d94 Revert "use v2 scheduler+new timezone handling by default for new users"
This reverts commit 8372931b9b.

I fear this will be too disruptive - let's give AnkiDroid a bit more
time to catch up. Reverting this will mean new users are presented with
an upgrade notice on first startup, which looks a bit silly, but it's
probably the lesser of two evils.
2021-02-21 19:03:46 +10:00
Damien Elmes
8372931b9b use v2 scheduler+new timezone handling by default for new users
- In corner cases, enabling the new timezone handling later can cause
reviews to shift forward or back a day, so it's best to have it on
by default.
- https://github.com/ankidroid/Anki-Android/issues/5805 has not landed
in a stable release yet, but will hopefully not be too far off by the
time 2.1.41 is released.
- Existing users will be unaffected, as the upgrade prompt in the previous
commit asks them if they use AnkiDroid.
- Users starting on AnkiDroid will be unaffected, as their collections
will still be on V1.
- The error message AnkiWeb gives when syncing an older AnkiDroid
with the new timezone enabled has been updated to direct users to the
preferences screen.
2021-02-21 17:18:08 +10:00
Damien Elmes
5ae66af5d2 rework v2 scheduler upgrade; drop downgrade
- Rework V2 upgrade so that it no longer resets cards in learning,
or empties filtered decks.
- V1 users will receive a message at the top of the deck list
encouraging them to upgrade, and they can upgrade directly from that
screen.
- The setting in the preferences screen has been removed, so users
will need to use an older Anki version if they wish to switch back to
V1.
- Prevent V2 exports with scheduling from being importable into a V1
collection - the code was previously allowing this when it shouldn't
have been.
- New collections still default to v1 at the moment.

Also add helper to get map of decks and deck configs, as there were
a few places in the codebase where that was required.
2021-02-21 15:50:41 +10:00
Damien Elmes
ab790c1d14 initial work on moving v2 card answering into backend
Not plugged into the Python code yet. Still a work in progress.

Other changes:

- move a bunch of From implementations out of the giant backend/mod.rs
file into separate submodules.
- reorder backend methods to match proto order
- fix some clippy lints
2021-02-20 14:48:07 +10:00
abdo
fae0437e49 Fix tag replacement matching substrings
https://github.com/ankitects/anki/issues/1027
2021-02-17 03:57:07 +03:00
Damien Elmes
b3b40933c2 switch 'set due date' to leaving the interval alone for now
The previous approach worked when the user pushes their due date back,
or moves it forward a little bit, but breaks down if they reschedule
shortly after the previous answer - a card that was only just answered
will have had an effective delay of 0, causing the interval to be
reset, which is not great.

I thought about limiting interval reductions, but that means the
behaviour is inconsistent when sending a card forward and moving it
back again.

We could apply a cap to the amount of interval we'll reduce, but that
will either doing something like dividing by 2 (which breaks down when
the action is performed repeatedly), or or looking up the review log
to try and determine the previous interval we should not go below.

One other option we might want to consider in the future is using
the revlog to calculate the actual elapsed time at answer time instead
of reschedule time, falling back to existing behaviour when the revlog
doesn't match or is missing.
2021-02-12 11:19:58 +10:00
Damien Elmes
586ea07869 avoid wrapping outermost search in parens 2021-02-12 09:30:21 +10:00
Damien Elmes
35840221bb tweak search wording and tidy up API
- SearchTerm -> SearchNode
- Operator -> Joiner; share between messages
- build_search_string() supports specifying AND/OR as a convenience
- group_searches() makes it easier to negate
2021-02-11 19:57:19 +10:00
Damien Elmes
59ccfe5918 more search bikeshedding
While implementing the overdue search, I realised it would be nice to
be able to construct a search string with OR and NOT searches without
having to construct each part individually with build_search_string().

Changes:

- Extends SearchTerm to support a text search, which will be parsed
by the backend. This allows us to do things like wrap text in a group
or NOT node.
- Because SearchTerm->Node conversion can now fail with a parsing error,
it's switched over to TryFrom
- Switch concatenate_searches and replace_search_term to use SearchTerms,
so that they too don't require separate string building steps.
- Remove the unused normalize_search()
- Remove negate_search, as this is now an operation on a Node, and
users can wrap their search in SearchTerm(negated=...)
- Remove the match_any and negate args from build_search_string

Having done all this work, I've just realised that perhaps the original
JSON idea was more feasible than I first thought - if we wrote it out
to a string and re-parsed it, we would be able to leverage the existing
checks that occur at parsing stage.
2021-02-11 17:11:17 +10:00
Damien Elmes
242b4ea505 switch search parser to using owned values
I was a bit too enthusiastic with using borrowed values in structs
earlier on in the Rust porting. In this case any performance gains are
dwarfed by the cost of querying the DB, and using owned values here
simplifies the code, and will make it easier to parse a fragment in
the From<SearchTerm> impl.
2021-02-11 12:19:36 +10:00
Damien Elmes
8852359fa9 expose the ability to create search groups 2021-02-11 11:21:33 +10:00
Damien Elmes
b75851d823 add "due on day" search 2021-02-11 10:46:40 +10:00
Damien Elmes
843ec29228 make it easier to negate a search term 2021-02-11 10:45:47 +10:00
Damien Elmes
9ce4b21935 add markdown flag for deck description
Needed so we can display consistently, and gradually transition over
2021-02-09 18:47:19 +10:00
Damien Elmes
180efbc578 recent -> today
'Current deck' has moved, and by removing 'due tomorrow', we can drop
the 'today' suffix on the rest of the items.

The keys of the existing translations have not been changed, so
existing translations will not break, but will need to be manually
updated to make them shorter.
2021-02-09 09:50:59 +10:00
Damien Elmes
05074f2cc1 make decks root search collection; move current deck
Also use explicit 'deck:*' search, to make it more obvious what is
happening
2021-02-08 22:48:45 +10:00
Damien Elmes
a8ddb65e1c add ability to force interval reset
- use trailing ! to force a reset
- use - instead of ..
- tweak i18n messages and error handling
2021-02-08 22:33:27 +10:00
Damien Elmes
b9635ce936 nest NoteWithEmptyCards 2021-02-08 19:11:16 +10:00
Damien Elmes
c23b01978d nest progress messages and remove Python wrapper class
The progress messages are only really intended to be consumed by Anki.
If consumption by add-ons was expected, we'd be better off keeping the
wrapper, as the API for oneofs in Python is quite awkward to use.
2021-02-08 16:40:27 +10:00
Damien Elmes
f434cff36f remember last input for 'set due'; add string config; nest config types 2021-02-08 14:10:05 +10:00
Damien Elmes
704b5e581a Rework reschedule tool
The old rescheduling dialog's two options have been split into two
separate menu items, "Forget", and "Set Due Date"

For cards that are not review cards, "Set Due Date" behaves like the
old reschedule option, changing the cards into a review card, and
and setting both the interval and due date to the provided number of
days.

When "Set Due Date" is applied to a review card, it no longer resets
the card's interval. Instead, it looks at how much the provided number
of days will change the original interval, and adjusts the interval by
that amount, so that cards that are answered earlier receive a smaller
next interval, and cards that are answered after a longer delay receive
a bonus.

For example, imagine a card was answered on day 5, and given an interval
of 10 days, so it has a due date of day 15.

- if on day 10 the due date is changed to day 12 (today+2), the card
is being scheduled 3 days earlier than it was supposed to be, so the
interval will be adjusted to 7 days.
- and if on day 10 the due date is changed to day 20, the interval will
be changed from 10 days to 15 days.

There is no separate option to reset the interval of a review card, but
it can be accomplished by forgetting the card(s), and then setting the
desired due date.

Other notes:

- Added the action to the review screen as well.
- Set the shortcut to Ctrl+Shift+D, and changed the existing Delete
Tags shortcut to Ctrl+Alt+Shift+A.
2021-02-07 21:57:51 +10:00
Damien Elmes
ded626f0b9 render deck description with markdown; strip images
To support images on that screen, we'll first need to adjust the base url
for each platform, or rewrite the local image URLs, as otherwise they
are resolved to _anki/pages/...
2021-02-06 15:02:40 +10:00
Damien Elmes
6ba321f818 sanitize deck description in decks screen on backend
Looks like ammonia only adds about 800k to the release binary
2021-02-06 13:42:38 +10:00
Damien Elmes
3839ed2e28 show deck description on congrats screen 2021-02-06 13:20:06 +10:00
Damien Elmes
b8d67cdad5 move remaining Filter button items into sidebar
- Closes #976
- Added helper to apply arbitrary colour to an icon.
- Fix #979 - low res icons in night mode.
- The icons and colours are not perfect - please feel free to send
through a PR if you can improve them.
- Convert colors dictionary into module consts, so we can
use code completion.
- Added "Edited Today" and "Due Tomorrow"
- Rename camelCase attribute to snake_case and tweak the wording
of some enum constants. We've already broken compatibility with the
major sidebar add-ons, so we may as well make these changes while we
can.
- Removed Filter button. Currently there is no exposed way to toggle
the Sidebar off - wonder if we still need it?
2021-02-05 18:58:22 +10:00
Damien Elmes
da407a5000 pin proc_macro_nested due to Windows breakage 2021-02-03 21:17:11 +10:00
Damien Elmes
790562cd08 update Rust deps 2021-02-03 20:29:48 +10:00
Damien Elmes
a50601ed46 add tag drag & drop support 2021-02-02 20:14:04 +10:00
Damien Elmes
467064f873 collapsed->expanded in other tag uses for consistency 2021-02-02 18:52:57 +10:00
Damien Elmes
8e0f69b71c return tags as a string list directly; we don't need usn or collapse state 2021-02-02 18:52:57 +10:00
Damien Elmes
52b256663f collapsed->expanded in TagTreeNode 2021-02-02 18:52:57 +10:00
Damien Elmes
7d8448a321 decks start collapsed 2021-02-02 17:14:11 +10:00
Damien Elmes
4b7d30f515 tags start collapsed 2021-02-02 16:47:05 +10:00
Damien Elmes
4a4aef3972
Merge pull request #959 from Arthur-Milchior/AGPL
NF: add AGPL licence missing in some file
2021-02-01 12:46:59 +10:00
Damien Elmes
d219337023
Update card_stats.html
Don't want the header accidentally getting copied about when users copy+paste their stats.
2021-02-01 12:46:29 +10:00
Arthur Milchior
8b5ae7d7c5 NF: add AGPL licence missing in some file
I noticed it when I looked at some files now used in AnkiDroid, wanting to be sure we clearly indicate that we have
AGPLv3 code linked in the app
2021-01-31 21:50:21 +01:00
RumovZ
13c6921da1 Remove protobuf filters whole_col and current_deck 2021-01-31 11:12:49 +01:00
Damien Elmes
260a270eb0 embed BuiltinSortKind 2021-01-31 18:56:16 +10:00
Damien Elmes
5974163343 embed kind enum in StockNoteType and remove prefix 2021-01-31 18:56:16 +10:00
Damien Elmes
cb805cf355 Merge branch 'more-backend-search' into main 2021-01-31 14:21:51 +10:00
Damien Elmes
8410330f94 move drag/drop deck logic to backend 2021-01-31 13:46:31 +10:00
RumovZ
692aa16f6b Rename EaseKind to RatingKind 2021-01-30 19:03:50 +01:00
RumovZ
b0890b0e47 Manually namespace enum variants in SearchTerm
In protobuf "...enum values use C++ scoping rules, meaning that
enum values are siblings of their type, not children of it.
Therefore, [an enum variant] must be unique within [a message],
not just within [the enum.]"
So we must prefix enum variants with their enum's name, but can
also call them directly from the message namespace.
The protobuf crate is smart, though, and strips the prefixes.

(Simultaneously change some SearchTerm variant names.)
2021-01-30 17:56:29 +01:00
RumovZ
4745b55d27 Revert addition of pb.NoteIDs 2021-01-30 12:59:18 +01:00
Damien Elmes
705012164b move Rating up a level
More ergonomic, and will allow reuse if we expose prop:rated in
the future.
2021-01-30 11:54:39 +10:00
Damien Elmes
cb6b88da0f simplify nid/nids searches, and ditch helper function
- IdList could be re-used for a cids: search in the future if required.
- Embedding the message means it's easy to access from Python as
an attribute of SearchTerm.
2021-01-30 11:37:00 +10:00
Damien Elmes
1adc9952f4 simplify Dupe message and ditch helper function
Calling code doesn't need to know about the existence of such helpers;
it can just rely on code completion to discover the required arguments.
2021-01-30 11:10:26 +10:00
Damien Elmes
73b897c754 rename FilterToSearchIn in backend to match frontend 2021-01-30 10:54:21 +10:00
Damien Elmes
52bac7a7a1 use a separate enum for the is:* searches 2021-01-30 10:49:00 +10:00
Damien Elmes
22b80c2dd5 combine forgot_in_days and studied_today into a more general 'rated' 2021-01-30 10:26:23 +10:00
RumovZ
c299e271e8 Refactor search_string() and FilterToSearchIn
See #955.
2021-01-29 18:27:33 +01:00
Damien Elmes
6ba5ff5a01 place each sidebar section under its own collapsible parent node
- Allows for group operations like "clear unused tags"
- Allows users to hide groups they're not interested in
2021-01-29 22:11:05 +10:00
Damien Elmes
5ff7944a26 add getter/setter for boolean config values 2021-01-29 21:03:19 +10:00
RumovZ
1fb6024454 Rename filters added_in etc. to added_in_days 2021-01-29 09:38:13 +01:00
Damien Elmes
a9be60c8b4 sort config keys 2021-01-29 16:31:29 +10:00
Damien Elmes
7693879e3c remove unused set_all_config; expose .all_config(). 2021-01-29 16:30:42 +10:00
RumovZ
d33442f901 Add backend filter for field name 2021-01-28 19:48:01 +01:00
RumovZ
da6f3b7e76 Fix nid search test 2021-01-28 16:29:34 +01:00
RumovZ
bc52a54dfc Add nid filter on backend 2021-01-28 16:19:55 +01:00
RumovZ
b15bb4289e Add forgot, due and added filters on backend 2021-01-28 11:11:32 +01:00
Damien Elmes
e4d44efecc unbury on sync start
https://forums.ankiweb.net/t/unburying-works-differently-on-anki-desktop-ankiweb-and-ios-app/6909
2021-01-28 11:54:48 +10:00
Damien Elmes
163a9df886 avoid bumping mtime when correcting card eases on upgrade
The USN is still set, which should cause the cards to sync in the
non-conflict case, but if changes have been made on other devices
the ease fix will not take priority, as we could be overwriting the
reviews of someone who has not synced in a while.
2021-01-28 08:11:35 +10:00
Damien Elmes
2319312d94
Merge pull request #953 from hgiesel/backlogcb
Add FutureDueShowBacklog as preferences
2021-01-27 19:44:01 +10:00
Damien Elmes
9299dc60f4 suggest DB check if HTTP status 400 is returned 2021-01-27 14:23:28 +10:00
Henrik Giesel
677f4d340c Add FutureDueShowBacklog as preferences 2021-01-27 01:15:19 +01:00
Damien Elmes
644cc46dea
Merge pull request #897 from hgiesel/statssearch
Triggering searches from the stats screen.
2021-01-26 11:31:36 +10:00
Henrik Giesel
759ed17963 Move dispatch logic from Histogram to individual graphs 2021-01-25 16:34:44 +01:00
Henrik Giesel
60ed9c1e22 Add back bridge_commands_support via backend.proto 2021-01-25 13:47:20 +01:00
Kerrick Staley
1eac36c5d7 Add comment explaining why sfld column has type integer
The `notes.sfld` column in the `collection.anki2` database has type `integer`, even though it contains text. This is [something SQLite allows](https://dba.stackexchange.com/questions/106364/text-string-stored-in-sqlite-integer-column) and was done to allow integer values to sort numerically. Add a comment explaining this.
2021-01-25 18:39:59 +08:00
Damien Elmes
d70132cc8b handle missing deck ID in templates
https://github.com/ankidroid/Anki-Android/issues/7512
2021-01-25 16:47:23 +10:00
Damien Elmes
ef9f6b022b coerce some more invalid decimal values to ints during sync 2021-01-25 09:43:50 +10:00
Damien Elmes
370fc00afd handle older clients not setting 'done' key when false 2021-01-24 09:05:17 +10:00
Damien Elmes
2a875ffc55
Merge pull request #934 from hgiesel/graphprefs
Add GraphsPreferences API to graphs for setting persistent preferences
2021-01-23 21:24:41 +10:00
Damien Elmes
37ca8afaf6 minor wording tweak: GraphsPreferences -> GraphPreferences 2021-01-23 20:47:45 +10:00
Damien Elmes
bdc5c619f7 handle decks/notetypes with a duplicate name being sent in a sync
Typically caused by older clients, but could happen if the user added
the same name on different devices without syncing.

Also add an inactive test that was used to try track down this issue
and might be useful in the future.
2021-01-23 12:59:24 +10:00
Henrik Giesel
de71123ab4 Rename GraphsPreferencesOut to simply GraphsPreferences 2021-01-22 19:39:03 +01:00
Henrik Giesel
ebd3ca8a8f Set calendar labels to emptyColour 2021-01-22 18:15:16 +01:00
Henrik Giesel
834f2de99b Make cardCountsSeparateInactive settable 2021-01-22 18:03:58 +01:00
Henrik Giesel
aebaa04652 Uniformly rename firstWeekday to firstDayOfWeek 2021-01-22 16:53:33 +01:00
Henrik Giesel
054c30a695 Add non-functioning logic for settings graphs preferences 2021-01-22 13:14:35 +01:00
Henrik Giesel
665a13e378 Add GraphsPreferences endpoint to backend 2021-01-22 13:13:48 +01:00
Damien Elmes
99d732799c (de)serialize Weekday directly
Re: discussion in https://github.com/ankitects/anki/pull/934
2021-01-22 12:12:57 +10:00
Damien Elmes
a77aa6b65a handle non-chunked graves from AnkiDroid 2021-01-22 10:00:25 +10:00
Damien Elmes
ce50b1cddf add missing file header 2021-01-21 10:31:34 +10:00
Damien Elmes
44cde24679 fix context in rated: search error message 2021-01-19 18:33:10 +10:00
Damien Elmes
d273ebb756 more parsing error tweaks
The majority of the error checking can now be delegated to routines
like parse_f32(), parse_negative_i32() and so on, instead of creating
specific error messages for each type.
2021-01-19 15:50:26 +10:00
Damien Elmes
0b83efb63e simplify write_props() and associated translations
This is a work in progress; see associated PR discussion to follow.
2021-01-19 12:40:16 +10:00
Damien Elmes
a4ec467284 have register_tag mutate the tag if it changes it, instead of copying 2021-01-19 12:37:51 +10:00
Damien Elmes
9edb002679 fix deck and tag normalization
The issue existed in the deck code as well; I've added a test for it.
2021-01-19 12:36:01 +10:00
Damien Elmes
09bea954a2
Merge pull request #929 from abdnh/tag-case
Make tags match their parents case
2021-01-19 11:56:03 +10:00
Damien Elmes
71f1d3b982 tweaks to the parent matching behaviour
- move logic out of the storage layer - its job is only to read
and write data from the DB
- avoid the Result within a Result
- return the preferred case as an option, so we can avoid a copy
in the unchanged case
- return a Cow when normalizing, so we can avoid copying in the
unchanged case
- add tags directly in clear_unused_tags(), so we avoid doing
lookups for every tag in the tag list
2021-01-19 11:52:24 +10:00
abdo
3159cf4ab6 Make tags match their parents case
https://github.com/ankitects/anki/pull/900/#issuecomment-762018745
2021-01-19 02:29:09 +03:00
Henrik Giesel
a5947e5c65 Satisfy formatter 2021-01-19 00:17:30 +01:00
Henrik Giesel
04e606bf4b Add firstWeekday to GraphsOut 2021-01-18 23:10:53 +01:00
Damien Elmes
318cc01c73
Merge pull request #900 from abdnh/tagtree
Hierarchical tags
2021-01-18 16:36:22 +10:00
abdo
0ac97cf358 clear_tag() should be case-insensitive 2021-01-18 03:52:28 +03:00
Henrik Giesel
84c997fa4d Adjust unit tests for new InvalidRatedEase 2021-01-18 00:05:20 +01:00
Henrik Giesel
bdc6494c79 Generalize InvalidRatedEase error for rated and prop:rated 2021-01-17 23:55:05 +01:00
Henrik Giesel
2b45ef22a5 Use explicit unreachable in rust pattern matching 2021-01-17 22:18:12 +01:00
Henrik Giesel
bc81165be4 Add resched to tags 2021-01-17 21:44:56 +01:00
Henrik Giesel
947260e4aa Reintroduce false removed limits 2021-01-16 17:38:02 +01:00
Henrik Giesel
e7660113ce Change argument order of write_rated to be more in line with the logic 2021-01-16 15:24:22 +01:00
Henrik Giesel
112e7f577e Lift the 365 limit from rated/resched searches 2021-01-16 15:08:15 +01:00
Henrik Giesel
47542f97e5 Fix issues after rebasing 2021-01-16 13:07:35 +01:00
Henrik Giesel
908e0a375c Being overly correct with the review ids 2021-01-16 12:45:02 +01:00
Henrik Giesel
8f3c63bf0b Fix formatting 2021-01-16 12:45:02 +01:00
Henrik Giesel
88c75d73b6 Pass in the the negative offset day to write_rated 2021-01-16 12:44:59 +01:00
Henrik Giesel
3788cb8890 Port prop:rated to EaseKind 2021-01-16 12:44:03 +01:00
Henrik Giesel
b57d0da12a Implement functioning prop:rated 2021-01-16 12:42:08 +01:00
Henrik Giesel
ce55dc4a75 Add nonfunctional "prop:rated" as possible search query 2021-01-16 12:42:06 +01:00
Damien Elmes
34245e6f72 use of 'self' in function name was confusing 2021-01-16 21:14:55 +10:00
Damien Elmes
9f964916ab simplify unused tags and DB check
- backend routines should contain minimal logic, and should call
into a routine on the collection
- instead of copying the giant-string approach the Python code was taking,
we use a HashSet to keep track of seen tags as we loop through the
notes, which should be more efficient
2021-01-16 20:38:16 +10:00
Damien Elmes
d80a5c56e3 no need for separate all_tags_sorted()
tag is the primary key, so sqlite will give it back to us in
sorted order already.
2021-01-16 19:46:58 +10:00
Damien Elmes
d54acba81f custom ord/partialeq is not required; fix clippy lint 2021-01-16 19:44:37 +10:00
Damien Elmes
a390a77815 handle missing parent names with varying case
Also convert to \x1f before sorting, so that numbers (with have a lower
ascii order than '::') don't mess up the sort.
2021-01-16 19:42:25 +10:00
Damien Elmes
6f7c68b661 add a (currently failing) test for duplicate parent names 2021-01-16 19:04:25 +10:00
Damien Elmes
9686cd99ec search error tweaks
- use markdown instead of HTML, to make editing and translating easier
- use a shared prefix
- a few very minor wording tweaks
- we don't need to translate undocumented command errors
- share a string for positive number of days
- share a string for invalid property and state arguments, and avoid
listing them out

Related discussion: https://github.com/ankitects/anki/pull/922
2021-01-16 15:59:19 +10:00
RumovZ
5b03d1e2c8 Add resched error tests 2021-01-15 10:57:55 +01:00
RumovZ
cb4a103bb1 Merge branch 'master' into search-errors
Add error support for new resched node, update rated error.
2021-01-15 10:50:02 +01:00
RumovZ
c8f0961c6c Include context in search error test 2021-01-15 09:09:54 +01:00
abdo
e018ea94b6 Merge branch 'master' of https://github.com/ankitects/anki into tagtree 2021-01-15 01:12:01 +03:00
RumovZ
182abfe66d Encode HTML entities in search errors 2021-01-14 23:02:39 +01:00
RumovZ
2a2ac38a1b Add search context for certain error kinds 2021-01-14 22:40:07 +01:00
RumovZ
5f05ca2548 Rename ParseErrorKind to SearchErrorKind 2021-01-14 22:00:52 +01:00
RumovZ
6af1852611 Add errorkind test 2021-01-14 19:10:12 +01:00
RumovZ
8f754e1525 Add FailKinds for unopened/unclosed groups 2021-01-14 19:09:31 +01:00
RumovZ
0b73110f82 Make AnkiError::SearchError work with ParseError
Use mock ftl strings for now.
2021-01-14 11:14:55 +01:00
RumovZ
4afb476f04 Fix text node parsers, add FailKind alias 2021-01-14 11:10:33 +01:00
abdo
831942c2e2 Fix unicode tag sorting 2021-01-14 07:04:55 +03:00
abdo
ee3c019804 Remove Default impl of Tag 2021-01-14 07:04:55 +03:00
abdo
9c1d7c522a Refactor code for clearing unused tags and saving collapse state 2021-01-14 07:04:14 +03:00
RumovZ
6d9cfb85ab Add pb message for dupe filter 2021-01-14 10:42:37 +10:00
RumovZ
d9bb20ac24 Expect backslashes to be escaped in dupe: text 2021-01-14 10:42:37 +10:00
RumovZ
f4cfccfc0a Fix writing dupe nodes
Rename comments and dupe functions on the backend accordingly to avoid
further confusion.
2021-01-14 10:42:37 +10:00
Damien Elmes
7d81d39be7
Merge pull request #918 from hgiesel/ratedflags
Introduce `resched:n` instead of `rated:n:0`
2021-01-14 10:19:10 +10:00
RumovZ
3aa15a7139 Optimise term parsers 2021-01-13 14:15:57 +01:00
RumovZ
447ff6931c Move parse errors, add helper func for parse fail 2021-01-13 13:23:25 +01:00
Henrik Giesel
9f7170ac0f Change "between 1 and 4" to "> 0" 2021-01-13 11:44:54 +01:00
Henrik Giesel
c0ec21b139 Rename EaseKind values 2021-01-13 11:41:48 +01:00
Damien Elmes
633034b24d add local sync server frontend 2021-01-13 11:42:00 +10:00
abdo
72e8f9d640 Merge branch 'master' of https://github.com/ankitects/anki into tagtree 2021-01-12 23:31:58 +03:00
abdo
9a68d84483 Keep tags in human form and update the tags table structure
See https://github.com/ankitects/anki/pull/900#issuecomment-758284016

- Leave tag names alone and add the collapsed and config columns to the tags table.
- Update The DB check code to preserve the collapse state of used tags.
- Add a simple test for clearing tags and their children
2021-01-12 23:12:35 +03:00
RumovZ
b89381ac95 Fix top-level search errorkinds 2021-01-12 17:32:26 +01:00
Damien Elmes
fbd91b22f5 tidy up UTC offset handling/timing calculations
- use the TimestampSecs newtype instead of raw i64s
- use FixedOffset instead of a minutes_west offset
- check localOffset each time the timing is calculated, and set it
if it's stale - even for v1.
- check for and fix missing rollover when calculating timing
- stop explicitly passing localOffset in the sync/start call
2021-01-12 21:32:56 +10:00
RumovZ
d00c54aacf Switch parser to custom erros and results 2021-01-12 10:43:12 +01:00
Damien Elmes
553908a856 add .clang-format so VS Code preserves formatting style on .proto save 2021-01-12 18:47:08 +10:00
Damien Elmes
31f941267c move sync JSON into separate file; add enum wrapper 2021-01-12 18:47:08 +10:00
Damien Elmes
09dfa9ced6 allow normal sync tests to run offline 2021-01-12 18:47:08 +10:00
Damien Elmes
f6c1a91674 use '<=' when merging UnchunkableChanges
Prevents current tests from failing when testing locally, due the current
second not changing between syncs.
2021-01-12 18:47:08 +10:00
Henrik Giesel
81d851610e Coerce resched:days as well 2021-01-11 17:25:42 +01:00
Henrik Giesel
5eb2c7b271 Satisfy rslib unit tests 2021-01-11 17:18:40 +01:00
Henrik Giesel
7a7152fe27 Remove EaseKind impl in favor of transforming to sql in function 2021-01-11 17:10:17 +01:00
Henrik Giesel
cbfe14ef4f Introduce "resched:n" instead of 0 and a flag for "rated" 2021-01-11 16:40:30 +01:00
Henrik Giesel
7e58660aab Modify default behavior of rated searches to exclude manual 2021-01-11 16:40:30 +01:00
Damien Elmes
9225c804db update Rust deps; add async_trait 2021-01-11 19:19:45 +10:00
Damien Elmes
401d5dd9cc
Merge pull request #917 from hgiesel/querynozero3
Coerce added/edited:0 to 1, Constrain rated:n to 1-365
2021-01-11 16:24:12 +10:00
Henrik Giesel
0b955c3699 Fix formatting 2021-01-10 16:38:20 +01:00
Henrik Giesel
adf969d37f Add a few rslib unit tests 2021-01-10 16:29:10 +01:00
Henrik Giesel
8f01887fe7 Remove coercion in write_rated 2021-01-10 16:23:53 +01:00
Henrik Giesel
87bc1e69b0 Coerce added/edited:0 to 1, constrain rated:n to 1 <= 365 2021-01-10 16:16:17 +01:00
Damien Elmes
5f70d718b8 favour readability over brevity in filter conversion 2021-01-10 09:19:33 +10:00
Damien Elmes
4ba4e8ca78
Merge pull request #913 from RumovZ/fix-write-template
Fix ordinal case in write_template
2021-01-10 08:58:00 +10:00
Damien Elmes
3f9604457d
Merge pull request #911 from RumovZ/backend-filters
Backend filters
2021-01-10 08:56:57 +10:00
Damien Elmes
4d471612ec fix protobuf formatting adding carriage returns on Windows 2021-01-10 08:48:20 +10:00
RumovZ
0629f80aeb Format backend.proto 2021-01-09 20:09:47 +01:00
RumovZ
f83553c82a Merge branch 'master' into backend-filters
Adapt new formatting.
2021-01-09 19:03:43 +01:00
RumovZ
ca62f3ef80 Fix ordinal case in write_template
Internal card ordinals start at 0, so add 1 again when writing a
template search string from a parsed ordinal.
2021-01-09 17:30:12 +01:00
abdo
0b5bb711a1 Remove unused backend methods & formatting 2021-01-09 17:48:34 +03:00
abdo
5919d9273f Fix tag collapse state not getting updated 2021-01-09 17:46:52 +03:00
abdo
97b4c2124c sql formatting 2021-01-09 17:38:16 +03:00
abdo
f7f509c70d Move tag collapse method to the backend 2021-01-09 17:10:16 +03:00
abdo
1be789f25f Move sql code for upgrading to schema 17 to a separate file 2021-01-09 17:10:16 +03:00
abdo
c6e3d55400 fill_missing_tags's input should be sorted
I assumed that fill_missing_tags will work correctly with un unsorted
tag list previously so I replaced the all_tags_sorted call, but take the following the list for example:

["foo::bar", "foo"]

This will cause "foo" to be counted like a missing tag, since it's
encountered the first time when looking at "foo::bar"", and its config
and other associated data will be lost.
2021-01-09 17:10:16 +03:00
abdo
b33267f754 Do not check for missing tag parents at registration time 2021-01-09 17:10:16 +03:00
abdo
b276ce3dd5 Hierarchical tags 2021-01-09 17:10:13 +03:00
RumovZ
9ef691c06f Provide filter searches through backend 2021-01-09 10:50:08 +01:00
Damien Elmes
fc948d3e83 add clang-format for backend.proto formatting 2021-01-09 17:08:50 +10:00
Damien Elmes
e0c3949ef9 format backend.proto with standard Google style 2021-01-09 15:50:24 +10:00
Damien Elmes
c3b1266f47 fix some comments in wrong position after format 2021-01-09 14:26:51 +10:00
Damien Elmes
3dad3c90d0 add .sql file formatter
Uses the logic from the sqltools VSCode add-on, with a workaround
for the use of 'type' in some table columns.

By detecting the presence of 'BUILD_WORKSPACE_DIRECTORY' we can tell
if the rule is running in test mode or was run directly, avoiding the
need for separate check and fix rules. It might be nice to extend this
to other formatting rules in the future as well.
2021-01-09 14:22:49 +10:00
Damien Elmes
56e4e2d518 reformat .sql files 2021-01-09 14:08:55 +10:00
Henrik Giesel
82a4e0abe8 Don't import now unused INITIAL_EASE_FACTOR_THOUSANDS 2021-01-08 19:32:36 +01:00
Henrik Giesel
caa536a753 Reset ease to 0 for after rescheduling cards as new 2021-01-08 18:15:24 +01:00
Damien Elmes
fe4da25e15 fix reposition not honoring provided order, and add unit test 2021-01-08 20:38:49 +10:00
Damien Elmes
97e3bfe1c0
Merge pull request #904 from hgiesel/propdue
Streamlining `is:due`, `prop:due`, and the FutureDue graph
2021-01-08 16:34:53 +10:00
Damien Elmes
10630ab723 handle SortOrderProto conversion separately, and use enum getter
In most cases we can just fall back on the default enum value instead
of caring if it's missing/invalid.
2021-01-08 15:56:20 +10:00
Damien Elmes
cbeb714062 convert sort_kind_from_pb into from impl 2021-01-08 09:42:54 +10:00
Damien Elmes
1a5b5f09cc convert from protobuf enum, rather than the underlying i32 2021-01-08 09:24:03 +10:00
Henrik Giesel
4c570785bb Add comment about integer division 2021-01-07 20:10:25 +01:00
Henrik Giesel
04a56209c6 Restate rslib unit test 2021-01-07 19:56:36 +01:00
Henrik Giesel
155a59b80b Search for Learn and PreviewRepeat cards when using prop:due 2021-01-07 19:01:10 +01:00
Henrik Giesel
795dcab370 Include PreviewRepeat cards in is:due 2021-01-07 17:24:10 +01:00
RumovZ
76c16180ae Add native enum for concatenate_search's separator 2021-01-07 12:50:57 +01:00
RumovZ
ebe535e42f Add Position in PropertyKind match of writer.rs 2021-01-06 23:29:09 +01:00
RumovZ
6ee9e4f58c Merge branch 'master' of https://github.com/ankitects/anki into norm-search 2021-01-06 20:57:24 +01:00
RumovZ
d9f7d2e70d Add tests for writer.rs
Also minor adjustments to concatenate_searches.
2021-01-06 19:39:34 +01:00
RumovZ
07499dd890 Implement search replacing via Ctrl+Shift combo
Also switch to using the new backend functions for concatenating and
negating searches.
2021-01-06 18:32:29 +01:00
RumovZ
84061a6e6d Implement replace_search_term 2021-01-06 14:03:43 +01:00
RumovZ
79d0b5496b Implement concatenate_searches
Fix minor stuff in writer.rs.
2021-01-06 14:00:47 +01:00
RumovZ
713db05f27 Implement negate_search 2021-01-06 13:57:35 +01:00
Damien Elmes
e28c67d4f6
Merge pull request #895 from hgiesel/newlearn
Change meaning of "is:learn" to filter on type, not queue
2021-01-06 19:13:59 +10:00
Henrik Giesel
59cb901a3b Change meaning of "is:learn" to filter on type, not queue 2021-01-05 17:36:55 +01:00
Damien Elmes
dad4c76089 no need to log card resets when exporting 2021-01-05 11:11:37 +10:00
abdo
dc51dc6795 Rename prop:order to prop:pos 2021-01-02 13:35:10 +03:00
abdo
0ad4619833 Support prop:order to search for new cards by order 2021-01-01 04:36:51 +03:00
Damien Elmes
6199548ba9
Merge pull request #879 from Arthur-Milchior/Tex_keep_alt
Add Alt text to latex image
2020-12-31 12:02:40 +10:00
Damien Elmes
a0b4948760 fix clippy error in unit test 2020-12-31 09:48:05 +10:00
Arthur Milchior
d933d7774f Add Alt text to latex image
I'm trying to go over accessibilities issues in AnkiDroid. Since we'll use rust backend, I thought I might as well go
over it in rust directly. The only side effect in anki is that, if you copy a text with the image, you'll get the LaTeX
copied instead of nothing. Alas, it seems qt does not show alt text.
2020-12-30 18:00:06 +01:00
Damien Elmes
3f3f4b5c36 add aarch64 Linux to cargo; update deps 2020-12-30 13:33:16 +10:00
RumovZ
95b4e4cc84 Make function names more explicit and add docs 2020-12-29 11:18:49 +01:00
RumovZ
62753290d8 Make normalized search syntax more explicit
Also fix a bug with NoCombining and WordBoundary searches.
2020-12-29 11:06:53 +01:00
Arthur Milchior
008a87a794 NF: test # / and ^ can remains at end of string 2020-12-28 07:58:15 +01:00