Commit graph

1662 commits

Author SHA1 Message Date
Damien Elmes
89b043c319 roll rusqlite back due to Windows breakage 2021-11-18 21:39:23 +10:00
Damien Elmes
c5c41759b4 update Rust deps 2021-11-18 20:58:41 +10:00
Damien Elmes
1ac84d9454 update to edition 2021 2021-11-18 20:51:10 +10:00
RumovZ
119f8cb0b3 Smooth fuzz (#1493)
* Add separate `fuzz.rs`

* Switch to a smoother fuzz calculation
2021-11-17 07:23:19 +10:00
Damien Elmes
35c6d9585f avoid fuzzing until interval reaches 3 days
e5e47a31fe (r748827327)

+ switched assert_lower_middle_upper to a macro, so that when it fails,
the reported line number is the original call site, instead of one inside
the helper function
2021-11-15 15:48:58 +10:00
RumovZ
ec1e6b8819 Fix constrained_fuzz_bounds() (#1490)
... for cases where the entire fuzz range is above `maximum`.
Also improve hanling if the entire range is below `minimum` and
readability.
2021-11-15 15:41:43 +10:00
Damien Elmes
4855fa1182 fix a link anchor 2021-11-14 11:44:54 +10:00
Damien Elmes
c2d9f148fd unbury when refreshing queues
While we already unbury when refreshing the deck list, if the user
resumes study on a new day without refreshing the deck list, burying
could end up being delayed.

Possible fix for https://forums.ankiweb.net/t/buried-cards-in-ankimobile-beta-20081-3/14753/3
2021-11-14 10:06:47 +10:00
Damien Elmes
4dca9a724c fix underflow in fuzz code, leading to large intervals
https://forums.ankiweb.net/t/buried-cards-in-ankimobile-beta-20081-3/14753
2021-11-14 09:17:37 +10:00
RumovZ
5c64aadb7a Garbage collect unused Fluent strings (#1482)
* Canonify import of i18n module

Should always be imported as `tr`, or `tr2` if there is a name collision
(Svelte).

* Add helper for garbage collecting ftl strings

Also add a serializer for ftl asts.

* Add helper for filter-mapping `DirEntry`s

* Fix `i18n_helpers/BUILD.bazel`

* run cargo-raze

* Refactor `garbage_collection.rs`

- Improve helper for file iterating
- Remove unused terms as well
- Fix issue with checking for nested messages by switching to a regex-
based approach (which runs before deleting)
- Some more refactorings and lint fixes

* Fix lints in `serialize.rs`

* Write json pretty and sorted

* Update `serialize.rs` and fix header

* Fix doc and remove `dbg!`

* Add binaries for ftl garbage collection

Also relax type constraints and strip debug tests.

* add rust_binary targets for i18n helpers (dae)

* add scripts to update desktop usage/garbage collect (dae)

Since we've already diverged from 2.1.49, we won't gain anything
from generating a stable json just yet. But once 2.1.50 is released,
we should run 'ftl/update-desktop-usage.sh stable'.

* add keys from AnkiMobile (dae)

* Mention caveats in `remove-unused.sh`
2021-11-12 18:19:01 +10:00
Damien Elmes
594f957bbb add a builder for Collection 2021-11-06 14:43:41 +10:00
RumovZ
388849a3ef Rework v3 fuzzing (#1474)
* Remove flooring in v3 scheduler code

It is no longer supposed to be an exact port of the old Python code.

* Rework v3 fuzzing

https://github.com/ankitects/anki/issues/1416#issuecomment-958208149

* Ensure length of fuzz range is larger than 1

Only for new intervals larger than 1 and respecting max review interval.

* add the beginnings of a unit test

* Clarify `fuzz_factor` doc string

* Fix Python tests for 2021 scheduler

* Fix fuzz test

1.0 is not a valid fuzz factor.

* Add tests for fuzzing in Rust

* Use range notation in fuzz factor doc

* Strip redundant tests
2021-11-06 10:39:24 +10:00
Matthias Metelka
1592fd0295 Editor Field Descriptions (#1476)
* Add description input to fields dialog

QLineEdit seems like the best option, as it saves space and motivates users to keep their descriptions concise.

* Add setDescriptions to note initialization script

Went for the extra function instead of including it in setFields to prevent potential add-on breakages.

* Add tooltip next to field name if description is set

* Refactor code according to suggestions

Set default tooltip placement to right instead of bottom

Use .get() for fld["description"]

Fix tab order in fields dialog

Swap out abbreviation "desc" for full length name to keep consistency

* Update Protobuf and Rust for description

Add description to notetypes.proto and schema11

Co-authored-by: RumovZ <RumovZ@users.noreply.github.com>

* Fix tooltips not updating with description

Remove redundant variable tooltipOptions

Update previousTooltip within reactive function

* Move LabelDescription out of LabelName

Co-authored-by: Henrik Giesel <hgiesel@users.noreply.github.com>

* Decrease icon size and fix alignment

Co-Authored-By: Henrik Giesel <hengiesel@gmail.com>

* the new key needs to be cleared from fields, not the notetype itself

Co-authored-by: RumovZ <RumovZ@users.noreply.github.com>
Co-authored-by: Henrik Giesel <hengiesel@gmail.com>
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
2021-11-06 09:42:48 +10:00
Damien Elmes
455e0ce63b fix sort order toggling
We're getting an enum instead of an int in Qt6

normal/reversed have been renamed to ascending/descending; no add-ons
appear to be using the old versions.
2021-10-30 09:14:43 +10:00
RumovZ
d62d23c525 Use backend for getting deck children (#1465)
* Add backend routine for child deck names and ids

* Use backend for getting deck children

Instead of flawed case-sensitive Python logic.
2021-10-29 19:43:17 +10:00
Damien Elmes
a1a65fe4ff fix new cards not being correctly limited
https://forums.ankiweb.net/t/ios-beta-20080-2-more-new-cards-after-review-limit-is-met/13728/10
2021-10-29 12:12:34 +10:00
RumovZ
008fa9692b Fix quotation of "and" and "or" in search (#1463) 2021-10-28 19:23:56 +10:00
RumovZ
67ca3308a5 Stop trimming filename references before encoding (#1462)
Closes  #1430
2021-10-28 19:22:51 +10:00
Damien Elmes
dae1854106 update Rust deps with cargo-raze 0.13.0 2021-10-26 08:16:40 +10:00
RumovZ
51874bc612 Do not bury suspended cards (#1447)
* Skip burying for suspended cards

* Inform about number of buried cards
2021-10-23 11:04:26 +10:00
RumovZ
3454c9ba30 Card info cleanup (#1446)
* Cast proto interface to type ...

... instead of using non-null assertions in Revlog.svelte.

* Remove OptionalInt32 and OptionalUInt32
2021-10-23 11:00:43 +10:00
RumovZ
6219764e50 Fix underflow of learning count (#1444)
`counts.learning` includes interday learning cards, so it is not
suitable to determine how many cards from the (intraday!) learning queue
are already included in the learning count when updating it.
2021-10-22 20:58:06 +10:00
Damien Elmes
09a474a8df fix a clippy lint in 1.56 2021-10-22 12:03:54 +10:00
Damien Elmes
7405023b9b convert sql_format to ts_project; move into separate folder 2021-10-18 19:39:45 +10:00
Damien Elmes
a3deb649e8 unbury when rendering deck list
We were previously relying on the sched_timing_today() call in the
backend, but v3 doesn't call it, leading to cards remaining buried.
2021-10-16 21:11:09 +10:00
RumovZ
ea9fc3730e Switch CardInfoDialog to ts page (#1414)
* Only collect card stats on the backend ...

... instead of rendering an HTML string using askama.

* Add ts page Card Info

* Update test for new `col.card_stats()`

* Remove obsolete CardStats code

* Use new ts page in `CardInfoDialog`

* Align start and end instead of left and right

Curiously, `text-align: start` does not work for `th` tags if assigned
via classes.

* Adopt ts refactorings after rebase

#1405 and #1409

* Clean up `ts/card-info/BUILD.bazel`

* Port card info logic from Rust to TS

* Move repeated field to the top

https://github.com/ankitects/anki/pull/1414#discussion_r725402730

* Convert pseudo classes to interfaces

* CardInfoPage -> CardInfo

* Make revlog in card info optional

* Add legacy support for old card stats

* Check for undefined instead of falsy

* Make Revlog separate component

* drop askama dependency (dae)

* Fix nightmode for legacy card stats
2021-10-14 19:22:47 +10:00
Damien Elmes
0982956bdc handle AnkiDroid's two element new intervals
https://github.com/ankidroid/Anki-Android/issues/8889
2021-10-07 23:15:51 +10:00
Damien Elmes
79aa52c082 update Rust deps 2021-10-02 20:42:03 +10:00
Damien Elmes
4a0d242266 fix a clippy lint in latest Rust 2021-10-02 14:13:49 +10:00
Damien Elmes
9025985505 replace the old stripHTML() methods with the backend implementation
Python's regex engine performs pathologically on regexes like
'<!--.*?-->' when fed a large string of repeating '<!--' clauses.
Thanks to JaimeSlome / security@huntr.dev for the report; closes #1380.

Solved by switching to the Rust implementation, which does not suffer
from this issue.

entsToText(), minimizeHTML(), and the old regex constants have been
removed; they do not appear to be used by any add-ons.
2021-10-01 23:15:45 +10:00
Damien Elmes
181bfab3d9 Merge pull request #1397 from RumovZ/column-tooltips
Add tooltips for some browser columns
2021-10-01 19:12:59 +10:00
Damien Elmes
bc7c43ac67 avoid extra allocation in replacement 2021-10-01 14:43:38 +10:00
RumovZ
0d68e1d59c Add tooltips for some browser columns 2021-09-30 13:15:09 +02:00
abdo
4d3f2c0232 Strip isolation chars from filenames in Check Media screen 2021-09-27 22:15:37 +03:00
Damien Elmes
93202f372c Merge pull request #1264 from hgiesel/tageditor2
Svelte Tag Editor v2
2021-09-15 20:21:16 +10:00
Damien Elmes
d28f264c87 handle filtered case when repositioning 2021-09-13 14:57:41 +10:00
Damien Elmes
65f761b55c check for invalid collections in full_upload() 2021-09-13 11:50:13 +10:00
Damien Elmes
c3a1ebadef tentative fix for learning count underflow
The 'avoid showing learning card twice' logic is now only applied
when the next learning card was already due to be shown. This'll mean
there will be cases where a learning card does get shown twice near
the end, but it makes the behaviour easier to reason about, for both
us and end users.
2021-09-13 11:08:55 +10:00
Damien Elmes
b0350bafa7 bikeshedding: amount -> match_limit
+ convert from u32 in backend method
2021-09-12 11:57:49 +10:00
Henrik Giesel
9d0c3e0855 Cap tag suggestions at 500 2021-09-10 01:13:50 +02:00
Damien Elmes
c83843812e add basic tag completion to backend
Matches should arrive in alphabetical order. Currently results are not
capped (JS should be able to handle ~1k tags without too much hassle),
and no reordering based on match location is done. Matches are substring
based, and multiple can be provided, eg "foo::bar" will match
"foof::baz::abbar".

This is not hooked up properly on the frontend at the moment -
updateSuggestions() seems to be missing the most recently typed character,
and is not updating the list of completions half the time.
2021-09-09 15:38:08 +02:00
Damien Elmes
1aad956872 fix case of fields table 2021-09-07 10:22:22 +10:00
Damien Elmes
65c9853d38 don't panic when invalid note id provided to change notetype
https://forums.ankiweb.net/t/fatal-error-while-updating-deck/12743/2
2021-08-29 14:00:55 +10:00
Damien Elmes
c6762ee8ab expose uncapped counts and total in tree node
In the future this information could be revealed on hover, to make it
clearer how limits are being applied.
2021-08-22 15:32:46 +10:00
Damien Elmes
0aae073056 adding options to sort by ascending/descending ease 2021-08-22 15:32:46 +10:00
Damien Elmes
56e807c45d fix errors when undoing/redoing after a queue-invalidating operation
There were a few issues going on here:

- If some operation had invalidated the queues, they were subsequently
recreated with a call to .get_queues() in the undo handling code. This
could happen after the changes to the card had already been reverted,
leading to a queue state that didn't match our expectations.
- More generally, it's not safe to assume our mutations will apply
cleanly after the queue has been rebuilt. The next card will vary
depending on the number of remaining cards when interspersing cards of
different types, and a queue-invalidating operation will have changed
the learning cutoff.

So rather than rebuilding the queues on demand, we now check that they
already exist, and were created at the time we expect. If not, we
invalidate them and skip applying the mutations, and a subsequent
refresh of the UI should rebuild the queues correctly.

As part of this change, the cutoff snapshot has been moved into the
normal answer update object.

One possible downside here is that adding a note during review may cause
a newly due learning card to appear when undoing a different review.
If this proves to be a problem, we could potentially note down the
learning cutoff and apply it when queues are rebuilt later.
2021-08-22 15:32:46 +10:00
Damien Elmes
d8cbb8149a support limiting interday learning cards by review limit again
Context: https://forums.ankiweb.net/t/more-cards-today-question-about-v3/12400/10

Previously, interday learning cards and reviews were gathered at the
same time in v3, with the review limit being applied to both of them. The
order cards were gathered in would change the ratio of gathered learning
cards and reviews, but as they were displayed together in a single count,
a changing ratio was not apparent, and no special handling was required
by the deck tree code.

Showing interday learning cards in the learning count, while still
applying a review limit to them, makes things more complicated, as
a changing ratio will result in different counts. The deck tree code
is not able to know which order cards will appear in, so without changes,
we would have had a situation where the deck list may show different counts
to those seen when clicking on a deck.

One way to solve this would have been to introduce a separate limit for
interday learning cards. But this would have meant users needed to
juggle two different limits, instead of having a single one that controls
total number of (non-intraday) cards shown.

Instead, the scheduler now fetches interday cards prior to reviews -
the rationale for that order is that learning cards tend to be more
fragile/urgent than reviews. The option to show learning cards
before/after/mixed with reviews still exists, but it applies only after
cards have been capped to the daily limit.

To ensure the deck tree code matches the counts the scheduler gives,
it too applies limits to interday learning cards first, and reviews
afterwards.
2021-08-22 15:32:46 +10:00
Damien Elmes
e37a0844ae fix new clippy warning 2021-08-22 15:32:46 +10:00
Damien Elmes
104a24bc1d add options to v3 to preserve new card gather order
Allows cards to be presented in deck order when gather priority is set
to 'deck'.
2021-08-20 12:03:32 +10:00
Damien Elmes
827f3e073a handle ampersand entities in image filenames
In the old HTML editor, filenames were % escaped before feeding them to
beautifulsoup, causing bare ampersands to be left alone. The new HTML
editor reads content from the DOM, where a bare ampersand has been
transformed into an &amp;, and that gets saved back into the field,
so the media check now needs to deal with it for images as well.

https://forums.ankiweb.net/t/causing-problems-with-image-names/12171
2021-08-19 23:43:40 +10:00
Damien Elmes
6410e66857 filtered decks w/ scheduling disabled in v3 now log reviews 2021-08-19 20:25:29 +10:00
Damien Elmes
f44817e080 revert some interday learning changes in v3
Interday learning cards are now counted in the learning count again,
and are no longer subject to the daily review limit.

The thinking behind the original change was that interday learning cards
are scheduled more like reviews, and counting them in the review count
would allow the learning count to focus on intraday learning - the red
number reflecting the fact that they are the most fragile memories. And
counting them together made it practical to apply the review limit
to both at once.

Since the release, there have been a number of users expecting to see
interday learning cards included in the learning count (the latest being
https://forums.ankiweb.net/t/feedback-and-a-feature-adjustment-request-for-2-1-45/12308),
and a good argument can be made for that too - they are, after all, listed
in the learning steps, and do tend to be harder than reviews. Short of
introducing another count to keep track of interday and intraday learning
separately, moving back to the old behaviour seems like the best move.

This also means it is not really practical to apply the review limit to
interday learning cards anymore, as the limit would be split between two
different numbers, and how much each number is capped would depend on
the order cards are introduced. The scheduler could figure this out, but
the deck list code does not know card order, and would need significant
changes to be able to produce numbers that matched the scheduler. And
even if we ignore implementation complexities, I think it would be more
difficult for users to reason about - the influence of the review limit
on new cards is confusing enough as it is.
2021-08-19 16:40:12 +10:00
Damien Elmes
7c49cca8b0 ensure interday learning cards update deck limits
https://forums.ankiweb.net/t/more-cards-today-question-about-v3/12400
2021-08-19 12:50:11 +10:00
Damien Elmes
857bb0db7d allow adjusting tag case in rename
https://forums.ankiweb.net/t/2-1-46-renaming-tags-to-tags-not-working/12426
2021-08-19 11:46:01 +10:00
Damien Elmes
7127dca4bd allow repositioning of new cards while suspended
https://forums.ankiweb.net/t/no-longer-can-reposition-a-suspended-card/12241
2021-08-15 15:06:25 +10:00
Damien Elmes
a697d0b537 check both queues when popping answered card
If multiple answers are applied in succession, a newly-due learning card
may be in front of the next main entry.
2021-08-09 18:29:04 +10:00
abdo
f3ce557d5e Fix double quotes being escaped twice in dupe search
maybe_quote() already escapes double quotes.
2021-08-09 05:05:20 +03:00
Damien Elmes
2bf1dca15c fall back on default deck in v3 queue gather as well
Missed in the previous change.

https://forums.ankiweb.net/t/error-when-trying-to-choose-deck-in-new-anki/11829/11
2021-08-09 11:04:37 +10:00
Damien Elmes
13ffd705f2 fallback on default deck in congrats screen
https://forums.ankiweb.net/t/error-when-trying-to-choose-deck-in-new-anki/11829
2021-08-04 12:57:46 +10:00
Damien Elmes
cfb9a9ec9f fix undoing last learning card corner case 2021-08-04 10:29:01 +10:00
Damien Elmes
dd4bd58638 support updating multiple notes in one transaction/undo op 2021-08-02 17:07:26 +10:00
Damien Elmes
e278f3ad1d support updating multiple cards in one transaction/undo op 2021-08-02 16:59:02 +10:00
Damien Elmes
e165e1c40c revert to defaults when schema 11 deck config can not be read
Allows decks with missing/null values like ivlFct to be opened.

https://forums.ankiweb.net/t/i-cant-access-ankiweb/11814
2021-08-02 16:27:48 +10:00
Damien Elmes
86d5d7e020 don't hide learning count on congrats screen when learning is overdue
The v3 scheduler will delay the final card from being shown twice in
a row, but the overdue case was being treated the same as the no-learning
case, leading to the message being hidden.
2021-08-02 15:57:09 +10:00
Damien Elmes
ba2d9fe77e update learning cutoff when counts are zero 2021-08-02 15:03:14 +10:00
Damien Elmes
2e614255b8 fix learning cutoff not updating during review 2021-08-02 15:03:14 +10:00
Damien Elmes
9609cd36de fix v3 not honoring initial ease factor
Closes #1317
2021-07-31 14:57:04 +10:00
RumovZ
a5f9dfbc87 Use existing 'no such field' tr string 2021-07-29 08:30:49 +02:00
RumovZ
4fc3670e1a Allow duplicate templates if {{Card}} is used 2021-07-28 22:32:38 +02:00
RumovZ
db7916fa11 Skip new notetype checks when importing apkg 2021-07-28 21:46:51 +02:00
RumovZ
fcd8ef9763 Find template errors hidden by conditionals 2021-07-28 12:13:14 +02:00
RumovZ
4da4ca5c57 Check for invalid conditionals on templates 2021-07-28 11:53:31 +02:00
Damien Elmes
9a2d8cc5f0 fix reqwest build on Linux again 2021-07-24 10:18:09 +10:00
Damien Elmes
b90388bee2 use separate integration test for links
If we run into issues with unreliable network connections in the future,
we'll be able to mark the test as flaky so Bazel can retry it multiple
times.
2021-07-24 10:12:25 +10:00
Damien Elmes
cfdbdb4a49 Merge pull request #1308 from RumovZ/check-help
Build and check help links on the backend
2021-07-24 09:37:23 +10:00
RumovZ
c3d2bc2d9f Fix linkcheck result message 2021-07-23 19:40:51 +02:00
Damien Elmes
032b2b272b disable link check outside CI 2021-07-23 20:22:32 +10:00
Damien Elmes
d25785f7fb be explicit about .html suffix 2021-07-23 20:22:32 +10:00
Damien Elmes
c31f56e768 fix clippy lints 2021-07-23 20:22:32 +10:00
Damien Elmes
e9669c165a add linkcheck to Bazel 2021-07-23 20:22:32 +10:00
RumovZ
a24b54af21 Add check to ensure parsed URL equals link 2021-07-23 11:44:19 +02:00
RumovZ
03f11dcb32 Improve error message for unknown fragment 2021-07-23 10:32:29 +02:00
RumovZ
72a9507c18 Remove native HelpPage enum
Also remove oneof from pb enum and handle strs in Python.
2021-07-22 16:32:49 +02:00
RumovZ
d8fb6fa8c7 Add links.proto and backend module 2021-07-22 10:05:38 +02:00
RumovZ
059774cc9b Add links.rs for checking and building links 2021-07-22 10:03:03 +02:00
Damien Elmes
39b2f5d82f handle notes with missing cards in browser
https://forums.ankiweb.net/t/2-1-45-release-candidate/11362/30
2021-07-22 14:58:57 +10:00
Damien Elmes
ef4289b4be strip invalid Unicode chars in media check 2021-07-17 18:30:19 +10:00
Damien Elmes
83a88d0779 fix comment + copy/paste error 2021-07-17 09:02:14 +10:00
Aleksa Sarai
5d7847515c scheduler: use deck config's initial ease in set_due_date
Previously we would just use 250% ease for any new card that had no
pre-configured ease, but this will result in decks that have
non-standard ease values to have "set due date" cards in them that don't
match. In order to make this somewhat more efficient, we cache
deckid->ease lookups during this operation.

Ref: <https://forums.ankiweb.net/t/set-due-date-doesnt-obey-default-ease-factor/9184>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-07-16 12:33:15 +10:00
Damien Elmes
eb4e18a45f Merge pull request #1293 from RumovZ/find-and-replace
Find & Replace
2021-07-16 10:47:16 +10:00
Damien Elmes
1e2ebd1c29 move from Python's URI escaping to IRI escaping in Rust
Should make non-Latin text readable in the HTML editor, without the
breakages reverted in the previous change.
2021-07-16 10:38:00 +10:00
RumovZ
4b1218184d Rework Find & Replace dialog:
- Add option to affect whole collection
- Allow to open without selection
- Add parameter for presetting field
2021-07-13 16:33:45 +02:00
RumovZ
a68b07d9ee Fix find & replace for notes without 'field_name'
Distinguish between no 'field_name' passed and 'field_name' not on note.
2021-07-13 16:21:13 +02:00
Damien Elmes
1189e763df minor tidyup in protobuf build script 2021-07-12 16:15:38 +10:00
Damien Elmes
08ddd9cc90 drop the cloze-in-basic check for now
Unfortunately a popular note taking tool has been misusing cloze
markers in its deck exports. We may want to add this back in the
future, but we'll probably want to start by warning users, to give
people time to adjust.
2021-07-11 20:31:02 +10:00
Damien Elmes
0eab59e522 configs.proto plural workaround no longer necessary 2021-07-11 19:35:18 +10:00
Damien Elmes
2238cdaa43 rename Config in protobuf to avoid conflict with module name
+ use the enum directly, instead of wrapping it in an object

Python code retains the old "Config" name.
2021-07-11 19:27:08 +10:00
Damien Elmes
e3b53fc078 split out remaining tags, stats, media and rendering 2021-07-10 23:16:18 +10:00
Damien Elmes
673955de5b split out sync, search, scheduler & config 2021-07-10 21:33:12 +10:00
Damien Elmes
1fb86d499d split out decks, deckconfig, notes, notetypes 2021-07-10 20:44:22 +10:00
Damien Elmes
c43674762e split out cards and collection 2021-07-10 19:52:31 +10:00
Damien Elmes
5255409093 refactor protobuf handling for split/import
In order to split backend.proto into a more manageable size, the protobuf
handling needed to be updated. This took more time than I would have
liked, as each language handles protobuf differently:

- The Python Protobuf code ignores "package" directives, and relies
solely on how the files are laid out on disk. While it would have been
nice to keep the generated files in a private subpackage, Protobuf gets
confused if the files are located in a location that does not match
their original .proto layout, so the old approach of storing them in
_backend/ will not work. They now clutter up pylib/anki instead. I'm
rather annoyed by that, but alternatives seem to be having to add an extra
level to the Protobuf path, making the other languages suffer, or trying
to hack around the issue by munging sys.modules.
- Protobufjs fails to expose packages if they don't start with a capital
letter, despite the fact that lowercase packages are the norm in most
languages :-( This required a patch to fix.
- Rust was the easiest, as Prost is relatively straightforward compared
to Google's tools.

The Protobuf files are now stored in /proto/anki, with a separate package
for each file. I've split backend.proto into a few files as a test, but
the majority of that work is still to come.

The Python Protobuf building is a bit of a hack at the moment, hard-coding
"proto" as the top level folder, but it seems to get the job done for now.

Also changed the workspace name, as there seems to be a number of Bazel
repos moving away from the more awkward reverse DNS naming style.
2021-07-10 19:17:05 +10:00
Damien Elmes
14263c7a79 move protobuf into separate folder in preparation for multiple files 2021-07-09 21:02:40 +10:00
RumovZ
e763745e05 Add pylib/browser.py for literal config keys
Also, remove config bools for sort order.
2021-07-05 12:44:48 +02:00
Henrik Giesel
5031bafb61 Add NOTETYPE_FIELD sidebar items 2021-06-30 21:02:23 +02:00
Damien Elmes
8870a9c4d5 zero out graves before comparison, instead of at creation
Will allow us to turn the check back on in the future without a client
update
2021-06-30 10:08:52 +10:00
Damien Elmes
c0a1c04c3c ignore graves in sanity check 2021-06-30 09:31:02 +10:00
Damien Elmes
33a9afaa1b add back in missing check for upload size
Compression now happens up-front, so we can tell in advance if the
upload size has been exceeded.
2021-06-29 10:50:03 +10:00
Damien Elmes
5b14a2968a catch invalid card ordinals in DB check
https://forums.ankiweb.net/t/error-corrupted-note/10976
2021-06-29 10:50:03 +10:00
Damien Elmes
d6e3964151 PEP8 cards.py 2021-06-27 12:12:23 +10:00
Damien Elmes
14a2cc44ac update to latest rusqlite 2021-06-25 16:22:21 +10:00
Damien Elmes
795afb7068 update most rust deps; skip rusqlite 2021-06-25 15:35:25 +10:00
Damien Elmes
78a7620079 update undo skipping; exclude deck/tag expand/collapse
Instead of calling a method inside the transaction body, routines
can now pass Op::SkipUndo if they wish the changes to be discarded
at the end of the transaction. The advantage of doing it this way is
that the list of changes can still be returned, allowing the sync
indicator to update immediately.

Closes #1252
2021-06-25 09:16:15 +10:00
Damien Elmes
249e009f27 cope with collections where latexsvg is not a bool 2021-06-24 15:29:21 +10:00
Damien Elmes
2f25a969e4 report object type where json decode fails 2021-06-24 15:28:24 +10:00
Damien Elmes
b959feb6e5 expose scheduler js option in deck config 2021-06-24 14:38:10 +10:00
Damien Elmes
4ffca62afe allow customization of default search text
https://forums.ankiweb.net/t/whats-the-default-search-when-browsing-now-also-how-do-i-choose-to-browse-current-deck/8922
2021-06-24 11:24:30 +10:00
Damien Elmes
ff095ed57b fix clippy lints for latest Rust 2021-06-21 13:09:36 +10:00
Damien Elmes
d89c538c48 in/out -> request/response
The saved characters weren't worth the increased difficulty when
reading, and the fact that we were deviating from protobuf norms.
2021-06-20 15:49:20 +10:00
Damien Elmes
63f183958a add rustls-native-certs
closes #1241
2021-06-18 18:15:41 +10:00
Damien Elmes
532ac8b511 Merge pull request #1230 from RumovZ/fields-check
Check for misplaced or missing clozes when adding and in the editor
2021-06-17 21:26:16 +10:00
RumovZ
3004b460db Assign dupe error the lowest precedence 2021-06-16 11:42:40 +02:00
Henrik Giesel
76e885c65e Add escape_anki_wildcards_for_search_node 2021-06-16 09:25:27 +02:00
Henrik Giesel
3585bf0157 Revert "Remove special treatment of tag:none"
This reverts commit 95285ef66d.
2021-06-16 17:19:21 +10:00
Henrik Giesel
a6b313db5b Remove special treatment of tag:none 2021-06-16 17:19:21 +10:00
Henrik Giesel
8fd024c020 Make Browser root nodes use "_*" uniformly 2021-06-16 17:19:21 +10:00
Damien Elmes
596e37cabc update Rust deps 2021-06-16 16:10:57 +10:00
RumovZ
8160e05bd6 Fix missing hyphen escape when normalizing search (#1233)
* Fix missing hyphen escape when normalizing search

* Add some more tests for normalization

* Use char to satisfy clippy
2021-06-15 10:02:39 +10:00
Damien Elmes
6643780f17 handle <br/> when rendering a single line
+ case-insensitive matching

https://forums.ankiweb.net/t/html-editor-modifies-note-when-a-field-with-break-tags-is-opened/10772
2021-06-14 13:05:48 +10:00
RumovZ
4fb2299386 Add check for out-of-place/missing clozes 2021-06-12 10:02:21 +02:00
Damien Elmes
153e1e8d41 new change notetype implementation for the frontend
- changes can now be undone
- the same field can now be mapped to multiple target fields, allowing
fields to be cloned
- the old Qt dialog has been removed
- the old col.models.change() API calls the new code, to avoid
breaking existing consumers. It requires the field map to always
be passed in, but that appears to have been the common case.
- closes #1175
2021-06-10 22:19:24 +10:00
Damien Elmes
3b4bb5fafd fix spurious text in header injected by rust analyzer 2021-06-10 09:06:37 +10:00
Damien Elmes
7f984851b4 add notetype changing to backend 2021-06-09 20:56:52 +10:00
Damien Elmes
95151f5025 add LIFO sorting options for new cards 2021-06-08 14:01:46 +10:00
Damien Elmes
aaba9a777a fix note changes triggering a queue rebuild 2021-06-08 12:09:35 +10:00
Damien Elmes
c7381676a1 Merge pull request #1217 from RumovZ/flag-ftl
Mark search-invalid-flag as a new string
2021-06-03 10:50:11 +10:00
RumovZ
6e570a8ffc search-invalid-flag -> search-invalid-flag-2 2021-06-02 21:49:33 +02:00
Damien Elmes
f3e6ffd197 handle duplicate ids in values when upgrading deck config
Multiple configs with the same inner id would lead to errors like the
following when trying to open the collection:

DeckConfigInner.interval_multiplier: invalid wire type: StartGroup (expected ThirtyTwoBit)
2021-06-02 17:12:59 +10:00
Damien Elmes
d38f57cf3c Merge pull request #1213 from RumovZ/new-flags
Add pink, turquoise and purple flags
2021-06-02 11:22:26 +10:00
RumovZ
d6d712c4a7 Rename violet to pink 2021-06-01 18:14:43 +02:00
Damien Elmes
4daecb6771 push review randomizing into SQL
This makes the review backlog case more expensive, since we end up
shuffling items outside the daily limit, but for the common case it's
about the same speed, and it means we don't need two separate sorting
steps. New cards remain handled the same way, since a backlog
is common there.

Also ensures that interday learning cards honor the deck sorting, and
that the non-default sort orders shuffle at the end.
2021-06-01 14:50:35 +10:00
Damien Elmes
9a76565101 add options to sort reviews by deck
https://forums.ankiweb.net/t/is-studying-subdeck-by-subdeck-broken-in-2-1-44-mac/10458/2
2021-06-01 13:22:39 +10:00
Damien Elmes
afb9e92f36 fix subdeck order not being preserved by active_decks in v3 2021-06-01 11:40:25 +10:00
RumovZ
9e56a4421b Add violet, turquoise and purple flags 2021-05-31 12:03:30 +02:00
Damien Elmes
0b6beaa1da remove deck protobuf from frontend
Like the previous change, avoid exposing the protobuf as a public API
for now. It requires more thought, and is probably better done with
either extra helper accessors like decks.name(), or via a native class.
2021-05-31 16:31:06 +10:00
Damien Elmes
3d0a3a5707 fix exporting of non-default deck configs 2021-05-31 16:27:58 +10:00
Damien Elmes
8730e98778 Merge pull request #1200 from RumovZ/template-checks
Template checks
2021-05-29 10:28:06 +10:00
RumovZ
36c8ca32be Use HashSet for special fields 2021-05-28 15:42:09 +02:00
RumovZ
f2f5eb8b6f Add const for special fields and doc 2021-05-28 11:58:46 +02:00
RumovZ
b1dbebb1a6 Allow empty field name in templates 2021-05-28 11:37:05 +02:00
RumovZ
044e57075e Add checks for parsed templates
Combine existing check for unparsable templates with a check for unknown
field names and a check for front sides without any field replacement.
Updating the notetype's fields now mutates the parsed templates, so the
checks can run on the final templates.
2021-05-28 10:07:31 +02:00
Damien Elmes
c848a0a41b slightly simplify transact_inner() 2021-05-28 14:45:36 +10:00
Damien Elmes
f26982b9b1 don't depend on timer to increment between ops in unit test 2021-05-28 11:43:24 +10:00
Damien Elmes
ceb2813d5d avoid bumping mtime when nothing has changed
+ update sync indicator after every op
+ skip mtime bump on undo/redo
2021-05-28 11:09:16 +10:00
Damien Elmes
b0bde454ff add v3 scheduler to prefs screen 2021-05-27 23:09:49 +10:00
RumovZ
9ea349c38b Use HashMap in identical template check 2021-05-27 12:45:17 +02:00
RumovZ
1cdf1ed96d Check for clozes when saving notetype
Error if:
- Cloze notetype lacks a cloze field on either template side.
- Non-cloze notetype has a cloze field on any template.
2021-05-27 12:01:05 +02:00
Damien Elmes
52a98ce0ce change get_queued_cards() to no longer return congrats info 2021-05-26 12:59:45 +10:00
RumovZ
d4a163f893 Update tests to avoid duplicate front templates 2021-05-25 21:58:12 +02:00
RumovZ
87e5266f16 Check for identical templates before saving 2021-05-25 21:57:49 +02:00
RumovZ
1b1cb420ca Add details to TemplateSaveError 2021-05-25 21:01:03 +02:00
RumovZ
3c54f3a5c7 Escape HTML in template error message 2021-05-25 19:40:15 +02:00
Damien Elmes
22b05be570 expose the ability to get/set aux notetype/template keys
template keys are not currently adjusted when card templates are
repositioned.
2021-05-25 22:13:53 +10:00
Damien Elmes
691a5c5c44 pass css and latex svg flag back from rendering op
This could potentially help us avoid having to refetch the notetype
during study in the future, though updates to Note initialization and
the LaTeX handling would be required first.
2021-05-25 18:41:43 +10:00
Damien Elmes
12b4080dd3 support passing in a native notetype object to render_uncommitted_card() 2021-05-25 16:58:06 +10:00
Damien Elmes
01bfb5bf5d fix a panic when browser encounters a filtered card outside filtered deck
the -99999 due date overflows the i32, yielding to a stuck interface
when running in a debug build
2021-05-25 13:44:42 +10:00
Damien Elmes
1f7118a8e3 config updates by the frontend now skip undo by default 2021-05-24 14:50:46 +10:00
Damien Elmes
e687ac66f3 suppress some tests around the daily rollover 2021-05-24 14:18:07 +10:00
Damien Elmes
ced97c1f84 fix new ease not being applied to card on lapse
+ zero remaining steps when graduating (they shouldn't have been doing
any harm, but this is neater)
+ add some more tests that cover these cases
2021-05-24 10:04:56 +10:00
Damien Elmes
5427668303 expose undoable config changes to frontend; refresh sidebar
The browser header handling still needs updating
2021-05-21 17:50:41 +10:00
Damien Elmes
ba727735bd report changed cards when changing deck/flag
+ fix repeated flag shortcut not toggling
2021-05-21 16:03:05 +10:00
Damien Elmes
2b55f6111d Merge pull request #1180 from RumovZ/say-blank
Pronounce "[...]" as "blank" with TTS
2021-05-20 18:48:10 +10:00
RumovZ
4595dc5f28 Pronounce "[...]" as "blank" with TTS 2021-05-20 09:42:38 +02:00
Damien Elmes
0a3c727436 add a separate DeckId search for decks with children
- The "unbury deck" option was broken, as it was ignoring child
decks. It would be nice if we could use active_decks instead, but
plugging that into the old scheduler without breaking undo seems a bit
tricky.
- Remove the implicit From impl for decks, so we need to be forced to
think about whether we want child decks or not.
2021-05-20 11:44:37 +10:00
Damien Elmes
60ef1c35eb show note about old options screen if any add-ons are installed 2021-05-19 16:20:25 +10:00
Damien Elmes
79fb17c17f fix accidental schema bump in undo that was forcing full sync 2021-05-19 14:17:49 +10:00
RumovZ
4725fc436f Adjust search syntax for filtered deck presets 2021-05-17 12:14:02 +02:00
Damien Elmes
95a7ceff41 shift learning fuzz into answering stage in test scheduler
When shown on the answer buttons, it's too distracting
2021-05-17 13:05:42 +10:00
RumovZ
e4df61f9aa Preserve formatting of regex error 2021-05-16 21:07:35 +02:00
RumovZ
6024a8748f Remove SearchErrorKind::Regex as it's never used 2021-05-16 21:07:03 +02:00
Damien Elmes
fe5dee2a67 rework various aspects of the test scheduler
- Daily limits are no longer inherited - each deck limits its own
cards, and the selected deck enforces a maximum limit.
- Fetching of review cards now uses a single query, and sorts in advance.
In collections with a large number of overdue cards and decks, this is
faster than iterating over each deck in turn.
- Include interday learning count in review count & review limit, and
allow them to be buried.
- Warn when parent review limit is lower than child deck in deck options.
- Cap the new card limit to the review limit.
- Add option to control whether new card fetching short-circuits.
2021-05-16 20:23:07 +10:00
Damien Elmes
060ef67b26 remove some duplicate code & add deck.or() helper 2021-05-14 22:35:52 +10:00
Damien Elmes
a42648a418 fix test scheduler undo + implement look-ahead
Instead of using a separate undo queue, the code now defers checking for
newly-due learning cards until the answering stage, and logs the updated
cutoff time as an undoable change, so that any newly-due learning cards
won't appear instead of a new/review card that was just undone.

Queue redo now uses a similar approach to undo, instead of rebuilding the
queues.
2021-05-14 22:16:53 +10:00
Damien Elmes
127b7e28fc drop binary heap in test scheduler
The original rationale was avoiding a possible O(n) insertion if
the learning card was due outside the cutoff, but the increased code
complexity doesn't seem worth it, given that learning cards will
rarely grow above 1000.

Also added a currently-disabled test that demonstrates the current undo
handling behaviour is yielding incorrect counts; that will be reworked
in the next commit, and this change will make that easier.
2021-05-14 16:19:46 +10:00
Damien Elmes
5f7590c4b4 expose new sorting options in test scheduler options; move things around 2021-05-13 15:23:16 +10:00
Damien Elmes
9ff8727e68 pass sort options into test scheduler
- split new card fetch order and subsequent sort order; use latter
when building queues
- default to spacing siblings when burying is off, with options to
show each sibling in turn, and shuffle the fetched cards
2021-05-13 15:21:20 +10:00
Damien Elmes
2142cdbd24 fix burying in test scheduler
The bury new/review flags are now pulled from each card's home deck,
instead of using a global setting that had not been hooked up. This
unfortunately means we need to fetch the map of all decks up front, as
we need to be able to look up a deck configuration for cards that are
in filtered decks.

Fixes a "card was modified" error caused by cards being buried during
review, when they weren't removed up-front.
2021-05-12 12:00:15 +10:00
Damien Elmes
5a10f007e7 is_stale() doesn't need to be passed deck
Deck changes will trigger a queue rebuild via requires_study_queue_rebuild()
2021-05-12 09:44:10 +10:00
Damien Elmes
7e324a6ec0 use new API for test scheduler
Avoids duplicate work, and is a step towards allowing the next
states to be modified by third-party code.

Also:

- fixed incorrect underlined count, due to reviews being labeled as
learning cards
- fixed reviewer not refreshing when undoing a test review, by splitting
up backend queue rebuilding from frontend reviewer refresh
- moved answering into a CollectionOp
2021-05-11 13:06:03 +10:00
Damien Elmes
75589e3eba better leech tag handling for test scheduler 2021-05-10 14:58:04 +10:00
Damien Elmes
5e44a34f20 expose step counter and undone op changes in hook 2021-05-08 17:51:36 +10:00
Damien Elmes
57fada3be0 move action names out of undo.ftl into actions.ftl 2021-05-08 17:11:54 +10:00
Damien Elmes
f9d5eda3f8 update Rust deps 2021-05-07 18:22:27 +10:00
Damien Elmes
2a6cd2ff72 default to the v2 scheduler in new collections
ported from 9e91785d98
2021-05-06 19:09:28 +10:00
Damien Elmes
7f7dd7b6c9 add support for custom undo steps, and merging multiple actions
Allows add-on authors to define their own label for a group of undoable
operations. For example:

def mark_and_bury(
    *,
    parent: QWidget,
    card_id: CardId,
) -> CollectionOp[OpChanges]:
    def op(col: Collection) -> OpChanges:
        target = col.add_custom_undo_entry("Mark and Bury")
        col.sched.bury_cards([card_id])
        card = col.get_card(card_id)
        col.tags.bulk_add(note_ids=[card.nid], tags="marked")
        return col.merge_undo_entries(target)

    return CollectionOp(parent, op)

The .add_custom_undo_entry() is for adding your own custom actions.
When extending a standard Anki action, instead store `target = 
col.undo_status().last_step` after executing the standard operation.

This started out as a bigger refactor that required a separate
.commit_undoable() call to be run after each operation, instead of
having each operation return changes directly. But that proved to be
somewhat cumbersome in unit tests, and ran the risk of unexpected
behaviour if the caller invoked an operation without remembering to
finalize it.
2021-05-06 16:39:06 +10:00
Damien Elmes
126d27585f add a valid, empty file so the check action works in Rust Analyzer 2021-05-05 15:53:27 +10:00
Damien Elmes
1802066afe support undo for (renamed) unbury_deck() action 2021-04-30 20:03:20 +10:00
Damien Elmes
994d26937f remove some unneeded transactions from tests 2021-04-30 19:18:02 +10:00
Damien Elmes
65e2bfb16d fix invalid outer transaction in clear_unused_tags() 2021-04-30 19:09:02 +10:00
Damien Elmes
09f3e1db07 empty/restore media trash shouldn't clear undo 2021-04-30 19:07:30 +10:00
Damien Elmes
e161b9049a undoing of notetype fields
- fix stale cache issue
- update add cards screen in response to op changes
2021-04-30 17:15:59 +10:00
Damien Elmes
8a9796ee5a update GUI to allow notetype addition undo
- backend now updates current notetype as part of addition
- frontend no longer implicitly adds, so we can assign a new name and
add in a single operation
2021-04-30 15:58:08 +10:00
Damien Elmes
df068c2a17 update backend to support undoing of notetype changes 2021-04-30 12:54:59 +10:00
Damien Elmes
03ca227fd4 make it more ergonomic to search directly via nodes in Rust 2021-04-30 11:37:55 +10:00
Damien Elmes
acac1ae1f2 move note/card removal for notetype out of storage layer 2021-04-29 19:44:09 +10:00
Damien Elmes
df42d466b9 make config prefix removal undoable 2021-04-29 19:16:02 +10:00
Damien Elmes
b3d3768baa use aux var when retrieving last deck for notetype
The adding case was already covered by defaults_for_adding(), but we
the code was using the old variable when adding new cards to an existing
note.
2021-04-29 19:15:27 +10:00
Damien Elmes
9c3cf8b25b move pub functions to top of notetype/mod.rs 2021-04-29 15:32:59 +10:00
Damien Elmes
adec449ad4 move pub functions to top of notes/mod.rs 2021-04-29 14:08:15 +10:00
Damien Elmes
4f128aa330 confirm deletion is requiring a full sync 2021-04-28 22:21:16 +10:00
Damien Elmes
4216dd6d7e add some unit tests to deck config updating 2021-04-28 22:00:39 +10:00
Damien Elmes
77038ae554 DeckConfId -> DeckConfigId 2021-04-28 21:09:26 +10:00
Damien Elmes
985d256e7a sort deck on config update; fix id not being updated after deletion 2021-04-28 21:08:09 +10:00
Damien Elmes
deabb30dea report pinned package issues upstream 2021-04-27 23:11:22 +10:00
Damien Elmes
d76ef9cde5 update Rust deps
- tokio 1.0
- updated reqwest, thanks to Rumo
- other minor dep updates

the reqwest build file has been split into two, as it was awkward
to manually update the combined file, and the platform gate is now
on the target in rslib/
2021-04-27 22:18:12 +10:00
Damien Elmes
ddf7c5bb89 update translations 2021-04-25 22:06:05 +10:00
Damien Elmes
a7ef410615 hook new deck config screen up behind an env var 2021-04-22 10:59:16 +10:00
Damien Elmes
592e13e967 deckconf -> deckconfig 2021-04-20 21:54:24 +10:00
Damien Elmes
2fd7e8539d change detection needs to ignore collection mtime bump 2021-04-20 19:52:47 +10:00
Damien Elmes
293cbfb024 check if deck changed before saving 2021-04-20 19:50:31 +10:00
Damien Elmes
05f75c6194 implement deck config updating 2021-04-20 14:57:44 +10:00
Damien Elmes
4eaddde127 remove some imports duplicated by prelude 2021-04-19 18:22:43 +10:00
Damien Elmes
e287ebe988 Merge pull request #1138 from RumovZ/introduced
Add search keyword for "first review in x days"
2021-04-19 18:22:15 +10:00
RumovZ
d4d48676ad Use arg name instead of repeating it in format!() 2021-04-19 08:58:33 +02:00
RumovZ
af1111a91e Use timestamp adding for writing cutoff 2021-04-19 08:44:13 +02:00
RumovZ
e1e25d2b6a Add sql condition for speedup in write_introduced 2021-04-19 08:43:32 +02:00
RumovZ
eb9fbb9c0f Add sidebar filter "first review today" 2021-04-18 13:27:10 +02:00
RumovZ
f514697a90 Add sqlwriter test for introduced 2021-04-18 12:32:02 +02:00
RumovZ
6cfccf63bd Add cutoff_in_secs_from_days() helper method 2021-04-18 12:25:44 +02:00
RumovZ
27b658fc02 Add search keyword introduced
Filters for cards that had their first review within the last x days.
2021-04-18 12:14:18 +02:00
Damien Elmes
363a843d07 tidy up Rust imports
rustfmt can do this automatically, but only when run with a nightly
toolchain, so it needs to be manually done for now - see rslib/rusfmt.toml
2021-04-18 18:38:54 +10:00
Damien Elmes
06dea7aa0a start on making deck config and schema/mod changes undoable
+ move timestamps into a struct in a separate file for convenience
2021-04-18 17:33:12 +10:00
Damien Elmes
1f0ff0f22d add schema change prompt to removal, tweak return struct 2021-04-18 17:33:12 +10:00
RumovZ
6b5a73d3e7 Maybe normalize name when preparing deck update 2021-04-18 09:16:43 +02:00
RumovZ
6864cdb62e Remove redundant imports 2021-04-18 08:43:46 +02:00
Damien Elmes
6eb28909da as_str() -> as_native_str() 2021-04-18 09:33:39 +10:00
Damien Elmes
eece6125d8 hide NativeName inner value, and require explicit accessors 2021-04-18 09:29:35 +10:00
Damien Elmes
e0cf897104 create_missing_parents() can take a native name directly 2021-04-18 09:20:23 +10:00
RumovZ
32edd2b554 Give deck.name the newtype NativeDeckName
The deck name must be constructed by calling associated functions of
NativeDeckName, unless the name is guaranteed to be valid machine
name (like "Default").
NativeDeckName exposes methods to mutate the deck name and return
the human name.
The storage routines take &strs, but those should be slices of
NativeDeckNames to ensure machine form and normalization.
2021-04-17 22:47:04 +02:00
Damien Elmes
cd1c4d0941 Merge pull request #1132 from RumovZ/refactor-decks
Refactor decks/mod.rs
2021-04-17 18:21:56 +10:00
Damien Elmes
0645cb29b7 fix parent limit handling
We can't calculate it on the backend, as adjusting a config may alter
the parent limit.

Also fix hidden deck name and missing separator.
2021-04-17 12:53:59 +10:00
RumovZ
bca111e6b5 Split Col impls in decks in pub and private blocks 2021-04-16 08:30:16 +02:00
RumovZ
6a974a49bb Remove some imports in decks which are in prelude 2021-04-15 20:07:16 +02:00
RumovZ
7a159137cd Create decks/stats.rs 2021-04-15 20:06:16 +02:00
RumovZ
982ac0f342 Move some methods into decks/counts.rs 2021-04-15 19:53:11 +02:00
RumovZ
3f80addab7 Tidy up blocks and imports in decks/mod.rs 2021-04-15 19:43:35 +02:00
RumovZ
c2a0a0cb08 Create decks/remove.rs 2021-04-15 19:35:54 +02:00
RumovZ
dcb398558e Create decks/add.rs 2021-04-15 19:29:52 +02:00
RumovZ
6aeea5a829 Create decks/reparent.rs 2021-04-15 19:17:43 +02:00
RumovZ
e4bbb9eaa3 Create decks/name.rs 2021-04-15 18:46:01 +02:00