Commit Graph

896 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
b435658acb convert no-arg TR references to method invocations in *.ts 2021-03-26 19:10:27 +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
e687552aeb update TR references that crossed multiple lines 2021-03-26 14:38:15 +10:00
Damien Elmes
b7587cb8d2 update TR references that contain arguments 2021-03-26 14:21:04 +10:00
Damien Elmes
0c338bfd53 update no-arg tr references in qt/ 2021-03-26 13:48:26 +10:00
Damien Elmes
ebe655975c update some more TR references in pylib; update tr_legacyglobal 2021-03-26 13:33:46 +10:00
Damien Elmes
efb1ce46d4 switch the Importers global to a callable for i18n
I18n is not set up at init time, so the strings can't be generated
at import.

@kelciour you have a few importing add-ons, so wanted to give you a
heads-up. The importing code is likely to change more in
future months, but for now this should be the only change
2021-03-26 13:28:21 +10:00
Damien Elmes
48354931da update some no-arg TR constants 2021-03-26 12:37:18 +10:00
Damien Elmes
07c6c4044c Merge branch 'int_type' into main 2021-03-26 11:38:34 +10:00
Damien Elmes
bc2c3a57ba fix incorrect constant naming 2021-03-26 11:29:07 +10:00
Damien Elmes
64bb526008 fix incorrect camelCase 2021-03-26 11:28:51 +10:00
Damien Elmes
7d5014fd5f fix typo and PEP8 naming in noteimp.py 2021-03-26 11:28:18 +10:00
Damien Elmes
8e0f00fbb9 fix .select() not handling string arguments 2021-03-26 11:27:49 +10:00
Arthur Milchior
be630adab9 NF: CardType type 2021-03-26 11:14:08 +10:00
Arthur Milchior
365de5f232 NF: CardQueue type 2021-03-26 11:14:08 +10:00
Arthur Milchior
7ea862931c NF: NoteTypeID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
b54410200e NF: DeckConfID 2021-03-26 11:14:08 +10:00
Arthur Milchior
6ac1e6477e NF: DeckID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
08e13013b2 NF: default_deck_conf_id as constant
So that the 1 is clearer
2021-03-26 11:14:08 +10:00
Arthur Milchior
b8f715ffea NF: default_deck_id as a constant
Otherwise it's not clear what this 1 represents
2021-03-26 11:14:08 +10:00
Arthur Milchior
3b6802530d NF: currentDeckID factorize odid or did 2021-03-26 11:14:08 +10:00
Arthur Milchior
986efeed19 NF: CardID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
6ac540927a NF: NoteID type 2021-03-26 11:14:08 +10:00
Arthur Milchior
23083c3eb4 NF: add types to noteimp.py 2021-03-26 11:14:08 +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
Damien Elmes
4b5944f181 move markdown dep into pylib 2021-03-24 22:19:14 +10: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
181cda1979 rename&simplify the deck/config type aliases
- QueueConfig is only used by the scheduler
- DeckConfig was being used in places that Config should have been used
- Add "Dict" to the name so that the bare name is free for use with a
stronger type.
2021-03-24 16:29:02 +10:00
Damien Elmes
12597e1094 support undo of filtered deck build/empty 2021-03-24 12:56:06 +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
84b0c8ba88 switch DeckID to a NewType
Not sure at this point whether this will buy us much in the Python
codebase over a simple int alias, but let's give it a go.
2021-03-22 23:43:54 +10:00
Damien Elmes
01161c8ed2 use perform_op() for deck creation 2021-03-22 23:17:07 +10: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
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
a5be72742c Add BrowserRow to ignored classes 2021-03-20 16:06:26 +01:00
RumovZ
922fccee58 Use backend rows in browser.py 2021-03-20 12:03:26 +01: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
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
1621f2ff26 remove temp variable 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
2d8e45b6da tidy up flag/mark code 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
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