mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
split out decks, deckconfig, notes, notetypes
This commit is contained in:
parent
18851ace47
commit
9e0a295ab9
20 changed files with 733 additions and 683 deletions
|
@ -7,34 +7,10 @@ package anki.backend;
|
|||
|
||||
import "anki/generic.proto";
|
||||
import "anki/cards.proto";
|
||||
import "anki/decks.proto";
|
||||
import "anki/collection.proto";
|
||||
|
||||
// IDs used in RPC calls
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
message NotetypeId {
|
||||
int64 ntid = 1;
|
||||
}
|
||||
|
||||
message NoteId {
|
||||
int64 nid = 1;
|
||||
}
|
||||
|
||||
message NoteIds {
|
||||
repeated int64 note_ids = 1;
|
||||
}
|
||||
|
||||
message DeckId {
|
||||
int64 did = 1;
|
||||
}
|
||||
|
||||
message DeckIds {
|
||||
repeated int64 dids = 1;
|
||||
}
|
||||
|
||||
message DeckConfigId {
|
||||
int64 dcid = 1;
|
||||
}
|
||||
import "anki/notes.proto";
|
||||
import "anki/notetypes.proto";
|
||||
|
||||
// Backend methods
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -66,15 +42,15 @@ service SchedulingService {
|
|||
rpc StudiedTodayMessage(StudiedTodayMessageRequest) returns (generic.String);
|
||||
rpc UpdateStats(UpdateStatsRequest) returns (generic.Empty);
|
||||
rpc ExtendLimits(ExtendLimitsRequest) returns (generic.Empty);
|
||||
rpc CountsForDeckToday(DeckId) returns (CountsForDeckTodayResponse);
|
||||
rpc CountsForDeckToday(decks.DeckId) returns (CountsForDeckTodayResponse);
|
||||
rpc CongratsInfo(generic.Empty) returns (CongratsInfoResponse);
|
||||
rpc RestoreBuriedAndSuspendedCards(cards.CardIds)
|
||||
returns (collection.OpChanges);
|
||||
rpc UnburyDeck(UnburyDeckRequest) returns (collection.OpChanges);
|
||||
rpc BuryOrSuspendCards(BuryOrSuspendCardsRequest)
|
||||
returns (collection.OpChangesWithCount);
|
||||
rpc EmptyFilteredDeck(DeckId) returns (collection.OpChanges);
|
||||
rpc RebuildFilteredDeck(DeckId) returns (collection.OpChangesWithCount);
|
||||
rpc EmptyFilteredDeck(decks.DeckId) returns (collection.OpChanges);
|
||||
rpc RebuildFilteredDeck(decks.DeckId) returns (collection.OpChangesWithCount);
|
||||
rpc ScheduleCardsAsNew(ScheduleCardsAsNewRequest)
|
||||
returns (collection.OpChanges);
|
||||
rpc SetDueDate(SetDueDateRequest) returns (collection.OpChanges);
|
||||
|
@ -88,49 +64,6 @@ service SchedulingService {
|
|||
rpc GetQueuedCards(GetQueuedCardsRequest) returns (QueuedCards);
|
||||
}
|
||||
|
||||
service DecksService {
|
||||
rpc AddDeckLegacy(generic.Json) returns (collection.OpChangesWithId);
|
||||
rpc AddOrUpdateDeckLegacy(AddOrUpdateDeckLegacyRequest) returns (DeckId);
|
||||
rpc DeckTree(DeckTreeRequest) returns (DeckTreeNode);
|
||||
rpc DeckTreeLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetAllDecksLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetDeckIdByName(generic.String) returns (DeckId);
|
||||
rpc GetDeck(DeckId) returns (Deck);
|
||||
rpc UpdateDeck(Deck) returns (collection.OpChanges);
|
||||
rpc UpdateDeckLegacy(generic.Json) returns (collection.OpChanges);
|
||||
rpc SetDeckCollapsed(SetDeckCollapsedRequest) returns (collection.OpChanges);
|
||||
rpc GetDeckLegacy(DeckId) returns (generic.Json);
|
||||
rpc GetDeckNames(GetDeckNamesRequest) returns (DeckNames);
|
||||
rpc NewDeckLegacy(generic.Bool) returns (generic.Json);
|
||||
rpc RemoveDecks(DeckIds) returns (collection.OpChangesWithCount);
|
||||
rpc ReparentDecks(ReparentDecksRequest)
|
||||
returns (collection.OpChangesWithCount);
|
||||
rpc RenameDeck(RenameDeckRequest) returns (collection.OpChanges);
|
||||
rpc GetOrCreateFilteredDeck(DeckId) returns (FilteredDeckForUpdate);
|
||||
rpc AddOrUpdateFilteredDeck(FilteredDeckForUpdate)
|
||||
returns (collection.OpChangesWithId);
|
||||
rpc FilteredDeckOrderLabels(generic.Empty) returns (generic.StringList);
|
||||
rpc SetCurrentDeck(DeckId) returns (collection.OpChanges);
|
||||
rpc GetCurrentDeck(generic.Empty) returns (Deck);
|
||||
}
|
||||
|
||||
service NotesService {
|
||||
rpc NewNote(NotetypeId) returns (Note);
|
||||
rpc AddNote(AddNoteRequest) returns (AddNoteResponse);
|
||||
rpc DefaultsForAdding(DefaultsForAddingRequest) returns (DeckAndNotetype);
|
||||
rpc DefaultDeckForNotetype(NotetypeId) returns (DeckId);
|
||||
rpc UpdateNote(UpdateNoteRequest) returns (collection.OpChanges);
|
||||
rpc GetNote(NoteId) returns (Note);
|
||||
rpc RemoveNotes(RemoveNotesRequest) returns (collection.OpChangesWithCount);
|
||||
rpc ClozeNumbersInNote(Note) returns (ClozeNumbersInNoteResponse);
|
||||
rpc AfterNoteUpdates(AfterNoteUpdatesRequest)
|
||||
returns (collection.OpChangesWithCount);
|
||||
rpc FieldNamesForNotes(FieldNamesForNotesRequest)
|
||||
returns (FieldNamesForNotesResponse);
|
||||
rpc NoteFieldsCheck(Note) returns (NoteFieldsCheckResponse);
|
||||
rpc CardsOfNote(NoteId) returns (cards.CardIds);
|
||||
}
|
||||
|
||||
service SyncService {
|
||||
rpc SyncMedia(SyncAuth) returns (generic.Empty);
|
||||
rpc AbortSync(generic.Empty) returns (generic.Empty);
|
||||
|
@ -158,28 +91,6 @@ service ConfigService {
|
|||
rpc SetPreferences(Preferences) returns (collection.OpChanges);
|
||||
}
|
||||
|
||||
service NotetypesService {
|
||||
rpc AddNotetype(Notetype) returns (collection.OpChangesWithId);
|
||||
rpc UpdateNotetype(Notetype) returns (collection.OpChanges);
|
||||
rpc AddNotetypeLegacy(generic.Json) returns (collection.OpChangesWithId);
|
||||
rpc UpdateNotetypeLegacy(generic.Json) returns (collection.OpChanges);
|
||||
rpc AddOrUpdateNotetype(AddOrUpdateNotetypeRequest) returns (NotetypeId);
|
||||
rpc GetStockNotetypeLegacy(StockNotetype) returns (generic.Json);
|
||||
rpc GetNotetype(NotetypeId) returns (Notetype);
|
||||
rpc GetNotetypeLegacy(NotetypeId) returns (generic.Json);
|
||||
rpc GetNotetypeNames(generic.Empty) returns (NotetypeNames);
|
||||
rpc GetNotetypeNamesAndCounts(generic.Empty) returns (NotetypeUseCounts);
|
||||
rpc GetNotetypeIdByName(generic.String) returns (NotetypeId);
|
||||
rpc RemoveNotetype(NotetypeId) returns (collection.OpChanges);
|
||||
rpc GetAuxNotetypeConfigKey(GetAuxConfigKeyRequest) returns (generic.String);
|
||||
rpc GetAuxTemplateConfigKey(GetAuxTemplateConfigKeyRequest)
|
||||
returns (generic.String);
|
||||
rpc GetSingleNotetypeOfNotes(NoteIds) returns (NotetypeId);
|
||||
rpc GetChangeNotetypeInfo(GetChangeNotetypeInfoRequest)
|
||||
returns (ChangeNotetypeInfo);
|
||||
rpc ChangeNotetype(ChangeNotetypeRequest) returns (collection.OpChanges);
|
||||
}
|
||||
|
||||
service CardRenderingService {
|
||||
rpc ExtractAVTags(ExtractAVTagsRequest) returns (ExtractAVTagsResponse);
|
||||
rpc ExtractLatex(ExtractLatexRequest) returns (ExtractLatexResponse);
|
||||
|
@ -194,18 +105,6 @@ service CardRenderingService {
|
|||
rpc RenderMarkdown(RenderMarkdownRequest) returns (generic.String);
|
||||
}
|
||||
|
||||
service DeckConfigService {
|
||||
rpc AddOrUpdateDeckConfigLegacy(generic.Json) returns (DeckConfigId);
|
||||
rpc GetDeckConfig(DeckConfigId) returns (DeckConfig);
|
||||
rpc AllDeckConfigLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetDeckConfigLegacy(DeckConfigId) returns (generic.Json);
|
||||
rpc NewDeckConfigLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc RemoveDeckConfig(DeckConfigId) returns (generic.Empty);
|
||||
rpc GetDeckConfigsForUpdate(DeckId) returns (DeckConfigsForUpdate);
|
||||
rpc UpdateDeckConfigs(UpdateDeckConfigsRequest)
|
||||
returns (collection.OpChanges);
|
||||
}
|
||||
|
||||
service TagsService {
|
||||
rpc ClearUnusedTags(generic.Empty) returns (collection.OpChangesWithCount);
|
||||
rpc AllTags(generic.Empty) returns (generic.StringList);
|
||||
|
@ -250,257 +149,6 @@ service MediaService {
|
|||
rpc RestoreTrash(generic.Empty) returns (generic.Empty);
|
||||
}
|
||||
|
||||
// Protobuf stored in .anki2 files
|
||||
// These should be moved to a separate file in the future
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
message DeckConfig {
|
||||
message Config {
|
||||
enum NewCardInsertOrder {
|
||||
NEW_CARD_INSERT_ORDER_DUE = 0;
|
||||
NEW_CARD_INSERT_ORDER_RANDOM = 1;
|
||||
}
|
||||
enum NewCardGatherPriority {
|
||||
NEW_CARD_GATHER_PRIORITY_DECK = 0;
|
||||
NEW_CARD_GATHER_PRIORITY_LOWEST_POSITION = 1;
|
||||
NEW_CARD_GATHER_PRIORITY_HIGHEST_POSITION = 2;
|
||||
}
|
||||
enum NewCardSortOrder {
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_LOWEST_POSITION = 0;
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_HIGHEST_POSITION = 1;
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_RANDOM = 2;
|
||||
NEW_CARD_SORT_ORDER_LOWEST_POSITION = 3;
|
||||
NEW_CARD_SORT_ORDER_HIGHEST_POSITION = 4;
|
||||
NEW_CARD_SORT_ORDER_RANDOM = 5;
|
||||
}
|
||||
enum ReviewCardOrder {
|
||||
REVIEW_CARD_ORDER_DAY = 0;
|
||||
REVIEW_CARD_ORDER_DAY_THEN_DECK = 1;
|
||||
REVIEW_CARD_ORDER_DECK_THEN_DAY = 2;
|
||||
REVIEW_CARD_ORDER_INTERVALS_ASCENDING = 3;
|
||||
REVIEW_CARD_ORDER_INTERVALS_DESCENDING = 4;
|
||||
// REVIEW_CARD_ORDER_RELATIVE_OVERDUE = 3;
|
||||
}
|
||||
enum ReviewMix {
|
||||
REVIEW_MIX_MIX_WITH_REVIEWS = 0;
|
||||
REVIEW_MIX_AFTER_REVIEWS = 1;
|
||||
REVIEW_MIX_BEFORE_REVIEWS = 2;
|
||||
}
|
||||
enum LeechAction {
|
||||
LEECH_ACTION_SUSPEND = 0;
|
||||
LEECH_ACTION_TAG_ONLY = 1;
|
||||
}
|
||||
|
||||
repeated float learn_steps = 1;
|
||||
repeated float relearn_steps = 2;
|
||||
|
||||
reserved 3 to 8;
|
||||
|
||||
uint32 new_per_day = 9;
|
||||
uint32 reviews_per_day = 10;
|
||||
uint32 new_per_day_minimum = 29;
|
||||
|
||||
float initial_ease = 11;
|
||||
float easy_multiplier = 12;
|
||||
float hard_multiplier = 13;
|
||||
float lapse_multiplier = 14;
|
||||
float interval_multiplier = 15;
|
||||
|
||||
uint32 maximum_review_interval = 16;
|
||||
uint32 minimum_lapse_interval = 17;
|
||||
|
||||
uint32 graduating_interval_good = 18;
|
||||
uint32 graduating_interval_easy = 19;
|
||||
|
||||
NewCardInsertOrder new_card_insert_order = 20;
|
||||
NewCardGatherPriority new_card_gather_priority = 34;
|
||||
NewCardSortOrder new_card_sort_order = 32;
|
||||
ReviewMix new_mix = 30;
|
||||
|
||||
ReviewCardOrder review_order = 33;
|
||||
|
||||
ReviewMix interday_learning_mix = 31;
|
||||
|
||||
LeechAction leech_action = 21;
|
||||
uint32 leech_threshold = 22;
|
||||
|
||||
bool disable_autoplay = 23;
|
||||
uint32 cap_answer_time_to_secs = 24;
|
||||
bool show_timer = 25;
|
||||
bool skip_question_when_replaying_answer = 26;
|
||||
|
||||
bool bury_new = 27;
|
||||
bool bury_reviews = 28;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
int32 usn = 4;
|
||||
Config config = 5;
|
||||
}
|
||||
|
||||
message Deck {
|
||||
message Common {
|
||||
bool study_collapsed = 1;
|
||||
bool browser_collapsed = 2;
|
||||
|
||||
uint32 last_day_studied = 3;
|
||||
int32 new_studied = 4;
|
||||
int32 review_studied = 5;
|
||||
int32 milliseconds_studied = 7;
|
||||
|
||||
// previously set in the v1 scheduler,
|
||||
// but not currently used for anything
|
||||
int32 learning_studied = 6;
|
||||
|
||||
reserved 8 to 13;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
message Normal {
|
||||
int64 config_id = 1;
|
||||
uint32 extend_new = 2;
|
||||
uint32 extend_review = 3;
|
||||
string description = 4;
|
||||
bool markdown_description = 5;
|
||||
|
||||
reserved 6 to 11;
|
||||
}
|
||||
message Filtered {
|
||||
message SearchTerm {
|
||||
enum Order {
|
||||
OLDEST_REVIEWED_FIRST = 0;
|
||||
RANDOM = 1;
|
||||
INTERVALS_ASCENDING = 2;
|
||||
INTERVALS_DESCENDING = 3;
|
||||
LAPSES = 4;
|
||||
ADDED = 5;
|
||||
DUE = 6;
|
||||
REVERSE_ADDED = 7;
|
||||
DUE_PRIORITY = 8;
|
||||
}
|
||||
|
||||
string search = 1;
|
||||
uint32 limit = 2;
|
||||
Order order = 3;
|
||||
}
|
||||
|
||||
bool reschedule = 1;
|
||||
repeated SearchTerm search_terms = 2;
|
||||
// v1 scheduler only
|
||||
repeated float delays = 3;
|
||||
// v2 scheduler only
|
||||
uint32 preview_delay = 4;
|
||||
}
|
||||
// a container to store the deck specifics in the DB
|
||||
// as a tagged enum
|
||||
message KindContainer {
|
||||
oneof kind {
|
||||
Normal normal = 1;
|
||||
Filtered filtered = 2;
|
||||
}
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
int32 usn = 4;
|
||||
Common common = 5;
|
||||
// the specifics are inlined here when sending data to clients,
|
||||
// as otherwise an extra level of indirection would be required
|
||||
oneof kind {
|
||||
Normal normal = 6;
|
||||
Filtered filtered = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message Notetype {
|
||||
message Config {
|
||||
enum Kind {
|
||||
KIND_NORMAL = 0;
|
||||
KIND_CLOZE = 1;
|
||||
}
|
||||
message CardRequirement {
|
||||
enum Kind {
|
||||
KIND_NONE = 0;
|
||||
KIND_ANY = 1;
|
||||
KIND_ALL = 2;
|
||||
}
|
||||
uint32 card_ord = 1;
|
||||
Kind kind = 2;
|
||||
repeated uint32 field_ords = 3;
|
||||
}
|
||||
|
||||
Kind kind = 1;
|
||||
uint32 sort_field_idx = 2;
|
||||
string css = 3;
|
||||
/// This is now stored separately; retrieve with DefaultsForAdding()
|
||||
int64 target_deck_id_unused = 4;
|
||||
string latex_pre = 5;
|
||||
string latex_post = 6;
|
||||
bool latex_svg = 7;
|
||||
repeated CardRequirement reqs = 8;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
message Field {
|
||||
message Config {
|
||||
bool sticky = 1;
|
||||
bool rtl = 2;
|
||||
string font_name = 3;
|
||||
uint32 font_size = 4;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
generic.OptionalUInt32 ord = 1;
|
||||
string name = 2;
|
||||
Config config = 5;
|
||||
}
|
||||
message Template {
|
||||
message Config {
|
||||
string q_format = 1;
|
||||
string a_format = 2;
|
||||
string q_format_browser = 3;
|
||||
string a_format_browser = 4;
|
||||
int64 target_deck_id = 5;
|
||||
string browser_font_name = 6;
|
||||
uint32 browser_font_size = 7;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
|
||||
generic.OptionalUInt32 ord = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
sint32 usn = 4;
|
||||
Config config = 5;
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
sint32 usn = 4;
|
||||
Config config = 7;
|
||||
repeated Field fields = 8;
|
||||
repeated Template templates = 9;
|
||||
}
|
||||
|
||||
// Database objects
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
message Note {
|
||||
int64 id = 1;
|
||||
string guid = 2;
|
||||
int64 notetype_id = 3;
|
||||
uint32 mtime_secs = 4;
|
||||
int32 usn = 5;
|
||||
repeated string tags = 6;
|
||||
repeated string fields = 7;
|
||||
}
|
||||
|
||||
// Backend
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -551,43 +199,20 @@ message SchedTimingTodayResponse {
|
|||
int64 next_day_at = 2;
|
||||
}
|
||||
|
||||
message DeckTreeRequest {
|
||||
// if non-zero, counts for the provided timestamp will be included
|
||||
int64 now = 1;
|
||||
int64 top_deck_id = 2;
|
||||
}
|
||||
|
||||
message DeckTreeNode {
|
||||
int64 deck_id = 1;
|
||||
string name = 2;
|
||||
uint32 level = 4;
|
||||
bool collapsed = 5;
|
||||
|
||||
uint32 review_count = 6;
|
||||
uint32 learn_count = 7;
|
||||
uint32 new_count = 8;
|
||||
|
||||
bool filtered = 16;
|
||||
|
||||
// low index so key can be packed into a byte, but at bottom
|
||||
// to make debug output easier to read
|
||||
repeated DeckTreeNode children = 3;
|
||||
}
|
||||
|
||||
message RenderExistingCardRequest {
|
||||
int64 card_id = 1;
|
||||
bool browser = 2;
|
||||
}
|
||||
|
||||
message RenderUncommittedCardRequest {
|
||||
Note note = 1;
|
||||
notes.Note note = 1;
|
||||
uint32 card_ord = 2;
|
||||
Notetype.Template template = 3;
|
||||
notetypes.Notetype.Template template = 3;
|
||||
bool fill_empty = 4;
|
||||
}
|
||||
|
||||
message RenderUncommittedCardLegacyRequest {
|
||||
Note note = 1;
|
||||
notes.Note note = 1;
|
||||
uint32 card_ord = 2;
|
||||
bytes template = 3;
|
||||
bool fill_empty = 4;
|
||||
|
@ -782,53 +407,11 @@ message ReplaceSearchNodeRequest {
|
|||
SearchNode replacement_node = 2;
|
||||
}
|
||||
|
||||
message DeckConfigsForUpdate {
|
||||
message ConfigWithExtra {
|
||||
DeckConfig config = 1;
|
||||
uint32 use_count = 2;
|
||||
}
|
||||
message CurrentDeck {
|
||||
string name = 1;
|
||||
int64 config_id = 2;
|
||||
repeated int64 parent_config_ids = 3;
|
||||
}
|
||||
|
||||
repeated ConfigWithExtra all_config = 1;
|
||||
CurrentDeck current_deck = 2;
|
||||
DeckConfig defaults = 3;
|
||||
bool schema_modified = 4;
|
||||
bool v3_scheduler = 5;
|
||||
bool have_addons = 6;
|
||||
// only applies to v3 scheduler
|
||||
string card_state_customizer = 7;
|
||||
}
|
||||
|
||||
message UpdateDeckConfigsRequest {
|
||||
int64 target_deck_id = 1;
|
||||
/// Unchanged, non-selected configs can be omitted. Deck will
|
||||
/// be set to whichever entry comes last.
|
||||
repeated DeckConfig configs = 2;
|
||||
repeated int64 removed_config_ids = 3;
|
||||
bool apply_to_children = 4;
|
||||
string card_state_customizer = 5;
|
||||
}
|
||||
|
||||
message SetTagCollapsedRequest {
|
||||
string name = 1;
|
||||
bool collapsed = 2;
|
||||
}
|
||||
|
||||
message SetDeckCollapsedRequest {
|
||||
enum Scope {
|
||||
REVIEWER = 0;
|
||||
BROWSER = 1;
|
||||
}
|
||||
|
||||
int64 deck_id = 1;
|
||||
bool collapsed = 2;
|
||||
Scope scope = 3;
|
||||
}
|
||||
|
||||
message GetChangedTagsResponse {
|
||||
repeated string tags = 1;
|
||||
}
|
||||
|
@ -856,57 +439,6 @@ message SetConfigJsonRequest {
|
|||
bool undoable = 3;
|
||||
}
|
||||
|
||||
message StockNotetype {
|
||||
enum Kind {
|
||||
BASIC = 0;
|
||||
BASIC_AND_REVERSED = 1;
|
||||
BASIC_OPTIONAL_REVERSED = 2;
|
||||
BASIC_TYPING = 3;
|
||||
CLOZE = 4;
|
||||
}
|
||||
|
||||
Kind kind = 1;
|
||||
}
|
||||
|
||||
message NotetypeNames {
|
||||
repeated NotetypeNameId entries = 1;
|
||||
}
|
||||
|
||||
message NotetypeUseCounts {
|
||||
repeated NotetypeNameIdUseCount entries = 1;
|
||||
}
|
||||
|
||||
message NotetypeNameId {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message NotetypeNameIdUseCount {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
uint32 use_count = 3;
|
||||
}
|
||||
|
||||
message AddOrUpdateNotetypeRequest {
|
||||
bytes json = 1;
|
||||
bool preserve_usn_and_mtime = 2;
|
||||
}
|
||||
|
||||
message AddNoteRequest {
|
||||
Note note = 1;
|
||||
int64 deck_id = 2;
|
||||
}
|
||||
|
||||
message AddNoteResponse {
|
||||
int64 note_id = 1;
|
||||
collection.OpChanges changes = 2;
|
||||
}
|
||||
|
||||
message UpdateNoteRequest {
|
||||
Note note = 1;
|
||||
bool skip_undo_entry = 2;
|
||||
}
|
||||
|
||||
message EmptyCardsReport {
|
||||
message NoteWithEmptyCards {
|
||||
int64 note_id = 1;
|
||||
|
@ -917,28 +449,6 @@ message EmptyCardsReport {
|
|||
repeated NoteWithEmptyCards notes = 2;
|
||||
}
|
||||
|
||||
message DeckNames {
|
||||
repeated DeckNameId entries = 1;
|
||||
}
|
||||
|
||||
message DeckNameId {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message AddOrUpdateDeckLegacyRequest {
|
||||
bytes deck = 1;
|
||||
bool preserve_usn_and_mtime = 2;
|
||||
}
|
||||
|
||||
message FieldNamesForNotesRequest {
|
||||
repeated int64 nids = 1;
|
||||
}
|
||||
|
||||
message FieldNamesForNotesResponse {
|
||||
repeated string fields = 1;
|
||||
}
|
||||
|
||||
message FindAndReplaceRequest {
|
||||
repeated int64 nids = 1;
|
||||
string search = 2;
|
||||
|
@ -992,12 +502,6 @@ message BrowserRow {
|
|||
uint32 font_size = 4;
|
||||
}
|
||||
|
||||
message AfterNoteUpdatesRequest {
|
||||
repeated int64 nids = 1;
|
||||
bool mark_notes_modified = 2;
|
||||
bool generate_cards = 3;
|
||||
}
|
||||
|
||||
message NoteIdsAndTagsRequest {
|
||||
repeated int64 note_ids = 1;
|
||||
string tags = 2;
|
||||
|
@ -1049,33 +553,6 @@ message Preferences {
|
|||
Editing editing = 3;
|
||||
}
|
||||
|
||||
message ClozeNumbersInNoteResponse {
|
||||
repeated uint32 numbers = 1;
|
||||
}
|
||||
|
||||
message GetDeckNamesRequest {
|
||||
bool skip_empty_default = 1;
|
||||
// if unset, implies skip_empty_default
|
||||
bool include_filtered = 2;
|
||||
}
|
||||
|
||||
message ReparentDecksRequest {
|
||||
repeated int64 deck_ids = 1;
|
||||
int64 new_parent = 2;
|
||||
}
|
||||
|
||||
message NoteFieldsCheckResponse {
|
||||
enum State {
|
||||
NORMAL = 0;
|
||||
EMPTY = 1;
|
||||
DUPLICATE = 2;
|
||||
MISSING_CLOZE = 3;
|
||||
NOTETYPE_NOT_CLOZE = 4;
|
||||
FIELD_NOT_CLOZE = 5;
|
||||
}
|
||||
State state = 1;
|
||||
}
|
||||
|
||||
message SyncLoginRequest {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
|
@ -1131,11 +608,6 @@ message SyncServerMethodRequest {
|
|||
bytes data = 2;
|
||||
}
|
||||
|
||||
message RemoveNotesRequest {
|
||||
repeated int64 note_ids = 1;
|
||||
repeated int64 card_ids = 2;
|
||||
}
|
||||
|
||||
message UpdateStatsRequest {
|
||||
int64 deck_id = 1;
|
||||
int32 new_delta = 2;
|
||||
|
@ -1403,58 +875,3 @@ message QueuedCards {
|
|||
uint32 learning_count = 3;
|
||||
uint32 review_count = 4;
|
||||
}
|
||||
|
||||
message DefaultsForAddingRequest {
|
||||
int64 home_deck_of_current_review_card = 1;
|
||||
}
|
||||
|
||||
message DeckAndNotetype {
|
||||
int64 deck_id = 1;
|
||||
int64 notetype_id = 2;
|
||||
}
|
||||
|
||||
message RenameDeckRequest {
|
||||
int64 deck_id = 1;
|
||||
string new_name = 2;
|
||||
}
|
||||
|
||||
message FilteredDeckForUpdate {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
Deck.Filtered config = 3;
|
||||
}
|
||||
|
||||
message GetAuxConfigKeyRequest {
|
||||
int64 id = 1;
|
||||
string key = 2;
|
||||
}
|
||||
|
||||
message GetAuxTemplateConfigKeyRequest {
|
||||
int64 notetype_id = 1;
|
||||
uint32 card_ordinal = 2;
|
||||
string key = 3;
|
||||
}
|
||||
|
||||
message GetChangeNotetypeInfoRequest {
|
||||
int64 old_notetype_id = 1;
|
||||
int64 new_notetype_id = 2;
|
||||
}
|
||||
|
||||
message ChangeNotetypeRequest {
|
||||
repeated int64 note_ids = 1;
|
||||
// -1 is used to represent null, as nullable repeated fields
|
||||
// are unwieldy in protobuf
|
||||
repeated int32 new_fields = 2;
|
||||
repeated int32 new_templates = 3;
|
||||
int64 old_notetype_id = 4;
|
||||
int64 new_notetype_id = 5;
|
||||
int64 current_schema = 6;
|
||||
}
|
||||
|
||||
message ChangeNotetypeInfo {
|
||||
repeated string old_field_names = 1;
|
||||
repeated string old_template_names = 2;
|
||||
repeated string new_field_names = 3;
|
||||
repeated string new_template_names = 4;
|
||||
ChangeNotetypeRequest input = 5;
|
||||
}
|
||||
|
|
145
proto/anki/deckconfig.proto
Normal file
145
proto/anki/deckconfig.proto
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package anki.deckconfig;
|
||||
|
||||
import "anki/generic.proto";
|
||||
import "anki/collection.proto";
|
||||
import "anki/decks.proto";
|
||||
|
||||
service DeckConfigService {
|
||||
rpc AddOrUpdateDeckConfigLegacy(generic.Json) returns (DeckConfigId);
|
||||
rpc GetDeckConfig(DeckConfigId) returns (DeckConfig);
|
||||
rpc AllDeckConfigLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetDeckConfigLegacy(DeckConfigId) returns (generic.Json);
|
||||
rpc NewDeckConfigLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc RemoveDeckConfig(DeckConfigId) returns (generic.Empty);
|
||||
rpc GetDeckConfigsForUpdate(decks.DeckId) returns (DeckConfigsForUpdate);
|
||||
rpc UpdateDeckConfigs(UpdateDeckConfigsRequest)
|
||||
returns (collection.OpChanges);
|
||||
}
|
||||
|
||||
message DeckConfigId {
|
||||
int64 dcid = 1;
|
||||
}
|
||||
|
||||
message DeckConfig {
|
||||
message Config {
|
||||
enum NewCardInsertOrder {
|
||||
NEW_CARD_INSERT_ORDER_DUE = 0;
|
||||
NEW_CARD_INSERT_ORDER_RANDOM = 1;
|
||||
}
|
||||
enum NewCardGatherPriority {
|
||||
NEW_CARD_GATHER_PRIORITY_DECK = 0;
|
||||
NEW_CARD_GATHER_PRIORITY_LOWEST_POSITION = 1;
|
||||
NEW_CARD_GATHER_PRIORITY_HIGHEST_POSITION = 2;
|
||||
}
|
||||
enum NewCardSortOrder {
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_LOWEST_POSITION = 0;
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_HIGHEST_POSITION = 1;
|
||||
NEW_CARD_SORT_ORDER_TEMPLATE_THEN_RANDOM = 2;
|
||||
NEW_CARD_SORT_ORDER_LOWEST_POSITION = 3;
|
||||
NEW_CARD_SORT_ORDER_HIGHEST_POSITION = 4;
|
||||
NEW_CARD_SORT_ORDER_RANDOM = 5;
|
||||
}
|
||||
enum ReviewCardOrder {
|
||||
REVIEW_CARD_ORDER_DAY = 0;
|
||||
REVIEW_CARD_ORDER_DAY_THEN_DECK = 1;
|
||||
REVIEW_CARD_ORDER_DECK_THEN_DAY = 2;
|
||||
REVIEW_CARD_ORDER_INTERVALS_ASCENDING = 3;
|
||||
REVIEW_CARD_ORDER_INTERVALS_DESCENDING = 4;
|
||||
// REVIEW_CARD_ORDER_RELATIVE_OVERDUE = 3;
|
||||
}
|
||||
enum ReviewMix {
|
||||
REVIEW_MIX_MIX_WITH_REVIEWS = 0;
|
||||
REVIEW_MIX_AFTER_REVIEWS = 1;
|
||||
REVIEW_MIX_BEFORE_REVIEWS = 2;
|
||||
}
|
||||
enum LeechAction {
|
||||
LEECH_ACTION_SUSPEND = 0;
|
||||
LEECH_ACTION_TAG_ONLY = 1;
|
||||
}
|
||||
|
||||
repeated float learn_steps = 1;
|
||||
repeated float relearn_steps = 2;
|
||||
|
||||
reserved 3 to 8;
|
||||
|
||||
uint32 new_per_day = 9;
|
||||
uint32 reviews_per_day = 10;
|
||||
uint32 new_per_day_minimum = 29;
|
||||
|
||||
float initial_ease = 11;
|
||||
float easy_multiplier = 12;
|
||||
float hard_multiplier = 13;
|
||||
float lapse_multiplier = 14;
|
||||
float interval_multiplier = 15;
|
||||
|
||||
uint32 maximum_review_interval = 16;
|
||||
uint32 minimum_lapse_interval = 17;
|
||||
|
||||
uint32 graduating_interval_good = 18;
|
||||
uint32 graduating_interval_easy = 19;
|
||||
|
||||
NewCardInsertOrder new_card_insert_order = 20;
|
||||
NewCardGatherPriority new_card_gather_priority = 34;
|
||||
NewCardSortOrder new_card_sort_order = 32;
|
||||
ReviewMix new_mix = 30;
|
||||
|
||||
ReviewCardOrder review_order = 33;
|
||||
|
||||
ReviewMix interday_learning_mix = 31;
|
||||
|
||||
LeechAction leech_action = 21;
|
||||
uint32 leech_threshold = 22;
|
||||
|
||||
bool disable_autoplay = 23;
|
||||
uint32 cap_answer_time_to_secs = 24;
|
||||
bool show_timer = 25;
|
||||
bool skip_question_when_replaying_answer = 26;
|
||||
|
||||
bool bury_new = 27;
|
||||
bool bury_reviews = 28;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
int32 usn = 4;
|
||||
Config config = 5;
|
||||
}
|
||||
|
||||
message DeckConfigsForUpdate {
|
||||
message ConfigWithExtra {
|
||||
DeckConfig config = 1;
|
||||
uint32 use_count = 2;
|
||||
}
|
||||
message CurrentDeck {
|
||||
string name = 1;
|
||||
int64 config_id = 2;
|
||||
repeated int64 parent_config_ids = 3;
|
||||
}
|
||||
|
||||
repeated ConfigWithExtra all_config = 1;
|
||||
CurrentDeck current_deck = 2;
|
||||
DeckConfig defaults = 3;
|
||||
bool schema_modified = 4;
|
||||
bool v3_scheduler = 5;
|
||||
bool have_addons = 6;
|
||||
// only applies to v3 scheduler
|
||||
string card_state_customizer = 7;
|
||||
}
|
||||
|
||||
message UpdateDeckConfigsRequest {
|
||||
int64 target_deck_id = 1;
|
||||
/// Unchanged, non-selected configs can be omitted. Deck will
|
||||
/// be set to whichever entry comes last.
|
||||
repeated DeckConfig configs = 2;
|
||||
repeated int64 removed_config_ids = 3;
|
||||
bool apply_to_children = 4;
|
||||
string card_state_customizer = 5;
|
||||
}
|
188
proto/anki/decks.proto
Normal file
188
proto/anki/decks.proto
Normal file
|
@ -0,0 +1,188 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package anki.decks;
|
||||
|
||||
import "anki/generic.proto";
|
||||
import "anki/collection.proto";
|
||||
|
||||
service DecksService {
|
||||
rpc AddDeckLegacy(generic.Json) returns (collection.OpChangesWithId);
|
||||
rpc AddOrUpdateDeckLegacy(AddOrUpdateDeckLegacyRequest) returns (DeckId);
|
||||
rpc DeckTree(DeckTreeRequest) returns (DeckTreeNode);
|
||||
rpc DeckTreeLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetAllDecksLegacy(generic.Empty) returns (generic.Json);
|
||||
rpc GetDeckIdByName(generic.String) returns (DeckId);
|
||||
rpc GetDeck(DeckId) returns (Deck);
|
||||
rpc UpdateDeck(Deck) returns (collection.OpChanges);
|
||||
rpc UpdateDeckLegacy(generic.Json) returns (collection.OpChanges);
|
||||
rpc SetDeckCollapsed(SetDeckCollapsedRequest) returns (collection.OpChanges);
|
||||
rpc GetDeckLegacy(DeckId) returns (generic.Json);
|
||||
rpc GetDeckNames(GetDeckNamesRequest) returns (DeckNames);
|
||||
rpc NewDeckLegacy(generic.Bool) returns (generic.Json);
|
||||
rpc RemoveDecks(DeckIds) returns (collection.OpChangesWithCount);
|
||||
rpc ReparentDecks(ReparentDecksRequest)
|
||||
returns (collection.OpChangesWithCount);
|
||||
rpc RenameDeck(RenameDeckRequest) returns (collection.OpChanges);
|
||||
rpc GetOrCreateFilteredDeck(DeckId) returns (FilteredDeckForUpdate);
|
||||
rpc AddOrUpdateFilteredDeck(FilteredDeckForUpdate)
|
||||
returns (collection.OpChangesWithId);
|
||||
rpc FilteredDeckOrderLabels(generic.Empty) returns (generic.StringList);
|
||||
rpc SetCurrentDeck(DeckId) returns (collection.OpChanges);
|
||||
rpc GetCurrentDeck(generic.Empty) returns (Deck);
|
||||
}
|
||||
|
||||
message DeckId {
|
||||
int64 did = 1;
|
||||
}
|
||||
|
||||
message DeckIds {
|
||||
repeated int64 dids = 1;
|
||||
}
|
||||
|
||||
message Deck {
|
||||
message Common {
|
||||
bool study_collapsed = 1;
|
||||
bool browser_collapsed = 2;
|
||||
|
||||
uint32 last_day_studied = 3;
|
||||
int32 new_studied = 4;
|
||||
int32 review_studied = 5;
|
||||
int32 milliseconds_studied = 7;
|
||||
|
||||
// previously set in the v1 scheduler,
|
||||
// but not currently used for anything
|
||||
int32 learning_studied = 6;
|
||||
|
||||
reserved 8 to 13;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
message Normal {
|
||||
int64 config_id = 1;
|
||||
uint32 extend_new = 2;
|
||||
uint32 extend_review = 3;
|
||||
string description = 4;
|
||||
bool markdown_description = 5;
|
||||
|
||||
reserved 6 to 11;
|
||||
}
|
||||
message Filtered {
|
||||
message SearchTerm {
|
||||
enum Order {
|
||||
OLDEST_REVIEWED_FIRST = 0;
|
||||
RANDOM = 1;
|
||||
INTERVALS_ASCENDING = 2;
|
||||
INTERVALS_DESCENDING = 3;
|
||||
LAPSES = 4;
|
||||
ADDED = 5;
|
||||
DUE = 6;
|
||||
REVERSE_ADDED = 7;
|
||||
DUE_PRIORITY = 8;
|
||||
}
|
||||
|
||||
string search = 1;
|
||||
uint32 limit = 2;
|
||||
Order order = 3;
|
||||
}
|
||||
|
||||
bool reschedule = 1;
|
||||
repeated SearchTerm search_terms = 2;
|
||||
// v1 scheduler only
|
||||
repeated float delays = 3;
|
||||
// v2 scheduler only
|
||||
uint32 preview_delay = 4;
|
||||
}
|
||||
// a container to store the deck specifics in the DB
|
||||
// as a tagged enum
|
||||
message KindContainer {
|
||||
oneof kind {
|
||||
Normal normal = 1;
|
||||
Filtered filtered = 2;
|
||||
}
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
int32 usn = 4;
|
||||
Common common = 5;
|
||||
// the specifics are inlined here when sending data to clients,
|
||||
// as otherwise an extra level of indirection would be required
|
||||
oneof kind {
|
||||
Normal normal = 6;
|
||||
Filtered filtered = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message AddOrUpdateDeckLegacyRequest {
|
||||
bytes deck = 1;
|
||||
bool preserve_usn_and_mtime = 2;
|
||||
}
|
||||
|
||||
message DeckTreeRequest {
|
||||
// if non-zero, counts for the provided timestamp will be included
|
||||
int64 now = 1;
|
||||
int64 top_deck_id = 2;
|
||||
}
|
||||
|
||||
message DeckTreeNode {
|
||||
int64 deck_id = 1;
|
||||
string name = 2;
|
||||
uint32 level = 4;
|
||||
bool collapsed = 5;
|
||||
|
||||
uint32 review_count = 6;
|
||||
uint32 learn_count = 7;
|
||||
uint32 new_count = 8;
|
||||
|
||||
bool filtered = 16;
|
||||
|
||||
// low index so key can be packed into a byte, but at bottom
|
||||
// to make debug output easier to read
|
||||
repeated DeckTreeNode children = 3;
|
||||
}
|
||||
|
||||
message SetDeckCollapsedRequest {
|
||||
enum Scope {
|
||||
REVIEWER = 0;
|
||||
BROWSER = 1;
|
||||
}
|
||||
|
||||
int64 deck_id = 1;
|
||||
bool collapsed = 2;
|
||||
Scope scope = 3;
|
||||
}
|
||||
|
||||
message GetDeckNamesRequest {
|
||||
bool skip_empty_default = 1;
|
||||
// if unset, implies skip_empty_default
|
||||
bool include_filtered = 2;
|
||||
}
|
||||
|
||||
message DeckNames {
|
||||
repeated DeckNameId entries = 1;
|
||||
}
|
||||
|
||||
message DeckNameId {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message ReparentDecksRequest {
|
||||
repeated int64 deck_ids = 1;
|
||||
int64 new_parent = 2;
|
||||
}
|
||||
|
||||
message RenameDeckRequest {
|
||||
int64 deck_id = 1;
|
||||
string new_name = 2;
|
||||
}
|
||||
|
||||
message FilteredDeckForUpdate {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
Deck.Filtered config = 3;
|
||||
}
|
106
proto/anki/notes.proto
Normal file
106
proto/anki/notes.proto
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package anki.notes;
|
||||
|
||||
import "anki/notetypes.proto";
|
||||
import "anki/collection.proto";
|
||||
import "anki/decks.proto";
|
||||
import "anki/cards.proto";
|
||||
|
||||
service NotesService {
|
||||
rpc NewNote(notetypes.NotetypeId) returns (Note);
|
||||
rpc AddNote(AddNoteRequest) returns (AddNoteResponse);
|
||||
rpc DefaultsForAdding(DefaultsForAddingRequest) returns (DeckAndNotetype);
|
||||
rpc DefaultDeckForNotetype(notetypes.NotetypeId) returns (decks.DeckId);
|
||||
rpc UpdateNote(UpdateNoteRequest) returns (collection.OpChanges);
|
||||
rpc GetNote(NoteId) returns (Note);
|
||||
rpc RemoveNotes(RemoveNotesRequest) returns (collection.OpChangesWithCount);
|
||||
rpc ClozeNumbersInNote(Note) returns (ClozeNumbersInNoteResponse);
|
||||
rpc AfterNoteUpdates(AfterNoteUpdatesRequest)
|
||||
returns (collection.OpChangesWithCount);
|
||||
rpc FieldNamesForNotes(FieldNamesForNotesRequest)
|
||||
returns (FieldNamesForNotesResponse);
|
||||
rpc NoteFieldsCheck(Note) returns (NoteFieldsCheckResponse);
|
||||
rpc CardsOfNote(NoteId) returns (cards.CardIds);
|
||||
rpc GetSingleNotetypeOfNotes(notes.NoteIds) returns (notetypes.NotetypeId);
|
||||
}
|
||||
|
||||
message NoteId {
|
||||
int64 nid = 1;
|
||||
}
|
||||
|
||||
message NoteIds {
|
||||
repeated int64 note_ids = 1;
|
||||
}
|
||||
|
||||
message Note {
|
||||
int64 id = 1;
|
||||
string guid = 2;
|
||||
int64 notetype_id = 3;
|
||||
uint32 mtime_secs = 4;
|
||||
int32 usn = 5;
|
||||
repeated string tags = 6;
|
||||
repeated string fields = 7;
|
||||
}
|
||||
|
||||
message AddNoteRequest {
|
||||
Note note = 1;
|
||||
int64 deck_id = 2;
|
||||
}
|
||||
|
||||
message AddNoteResponse {
|
||||
int64 note_id = 1;
|
||||
collection.OpChanges changes = 2;
|
||||
}
|
||||
|
||||
message UpdateNoteRequest {
|
||||
Note note = 1;
|
||||
bool skip_undo_entry = 2;
|
||||
}
|
||||
|
||||
message DefaultsForAddingRequest {
|
||||
int64 home_deck_of_current_review_card = 1;
|
||||
}
|
||||
|
||||
message DeckAndNotetype {
|
||||
int64 deck_id = 1;
|
||||
int64 notetype_id = 2;
|
||||
}
|
||||
|
||||
message RemoveNotesRequest {
|
||||
repeated int64 note_ids = 1;
|
||||
repeated int64 card_ids = 2;
|
||||
}
|
||||
|
||||
message ClozeNumbersInNoteResponse {
|
||||
repeated uint32 numbers = 1;
|
||||
}
|
||||
|
||||
message AfterNoteUpdatesRequest {
|
||||
repeated int64 nids = 1;
|
||||
bool mark_notes_modified = 2;
|
||||
bool generate_cards = 3;
|
||||
}
|
||||
|
||||
message FieldNamesForNotesRequest {
|
||||
repeated int64 nids = 1;
|
||||
}
|
||||
|
||||
message FieldNamesForNotesResponse {
|
||||
repeated string fields = 1;
|
||||
}
|
||||
|
||||
message NoteFieldsCheckResponse {
|
||||
enum State {
|
||||
NORMAL = 0;
|
||||
EMPTY = 1;
|
||||
DUPLICATE = 2;
|
||||
MISSING_CLOZE = 3;
|
||||
NOTETYPE_NOT_CLOZE = 4;
|
||||
FIELD_NOT_CLOZE = 5;
|
||||
}
|
||||
State state = 1;
|
||||
}
|
176
proto/anki/notetypes.proto
Normal file
176
proto/anki/notetypes.proto
Normal file
|
@ -0,0 +1,176 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package anki.notetypes;
|
||||
|
||||
import "anki/generic.proto";
|
||||
import "anki/collection.proto";
|
||||
|
||||
service NotetypesService {
|
||||
rpc AddNotetype(Notetype) returns (collection.OpChangesWithId);
|
||||
rpc UpdateNotetype(Notetype) returns (collection.OpChanges);
|
||||
rpc AddNotetypeLegacy(generic.Json) returns (collection.OpChangesWithId);
|
||||
rpc UpdateNotetypeLegacy(generic.Json) returns (collection.OpChanges);
|
||||
rpc AddOrUpdateNotetype(AddOrUpdateNotetypeRequest) returns (NotetypeId);
|
||||
rpc GetStockNotetypeLegacy(StockNotetype) returns (generic.Json);
|
||||
rpc GetNotetype(NotetypeId) returns (Notetype);
|
||||
rpc GetNotetypeLegacy(NotetypeId) returns (generic.Json);
|
||||
rpc GetNotetypeNames(generic.Empty) returns (NotetypeNames);
|
||||
rpc GetNotetypeNamesAndCounts(generic.Empty) returns (NotetypeUseCounts);
|
||||
rpc GetNotetypeIdByName(generic.String) returns (NotetypeId);
|
||||
rpc RemoveNotetype(NotetypeId) returns (collection.OpChanges);
|
||||
rpc GetAuxNotetypeConfigKey(GetAuxConfigKeyRequest) returns (generic.String);
|
||||
rpc GetAuxTemplateConfigKey(GetAuxTemplateConfigKeyRequest)
|
||||
returns (generic.String);
|
||||
rpc GetChangeNotetypeInfo(GetChangeNotetypeInfoRequest)
|
||||
returns (ChangeNotetypeInfo);
|
||||
rpc ChangeNotetype(ChangeNotetypeRequest) returns (collection.OpChanges);
|
||||
}
|
||||
|
||||
message NotetypeId {
|
||||
int64 ntid = 1;
|
||||
}
|
||||
|
||||
message Notetype {
|
||||
message Config {
|
||||
enum Kind {
|
||||
KIND_NORMAL = 0;
|
||||
KIND_CLOZE = 1;
|
||||
}
|
||||
message CardRequirement {
|
||||
enum Kind {
|
||||
KIND_NONE = 0;
|
||||
KIND_ANY = 1;
|
||||
KIND_ALL = 2;
|
||||
}
|
||||
uint32 card_ord = 1;
|
||||
Kind kind = 2;
|
||||
repeated uint32 field_ords = 3;
|
||||
}
|
||||
|
||||
Kind kind = 1;
|
||||
uint32 sort_field_idx = 2;
|
||||
string css = 3;
|
||||
/// This is now stored separately; retrieve with DefaultsForAdding()
|
||||
int64 target_deck_id_unused = 4;
|
||||
string latex_pre = 5;
|
||||
string latex_post = 6;
|
||||
bool latex_svg = 7;
|
||||
repeated CardRequirement reqs = 8;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
message Field {
|
||||
message Config {
|
||||
bool sticky = 1;
|
||||
bool rtl = 2;
|
||||
string font_name = 3;
|
||||
uint32 font_size = 4;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
generic.OptionalUInt32 ord = 1;
|
||||
string name = 2;
|
||||
Config config = 5;
|
||||
}
|
||||
message Template {
|
||||
message Config {
|
||||
string q_format = 1;
|
||||
string a_format = 2;
|
||||
string q_format_browser = 3;
|
||||
string a_format_browser = 4;
|
||||
int64 target_deck_id = 5;
|
||||
string browser_font_name = 6;
|
||||
uint32 browser_font_size = 7;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
|
||||
generic.OptionalUInt32 ord = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
sint32 usn = 4;
|
||||
Config config = 5;
|
||||
}
|
||||
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
sint32 usn = 4;
|
||||
Config config = 7;
|
||||
repeated Field fields = 8;
|
||||
repeated Template templates = 9;
|
||||
}
|
||||
|
||||
message AddOrUpdateNotetypeRequest {
|
||||
bytes json = 1;
|
||||
bool preserve_usn_and_mtime = 2;
|
||||
}
|
||||
|
||||
message StockNotetype {
|
||||
enum Kind {
|
||||
BASIC = 0;
|
||||
BASIC_AND_REVERSED = 1;
|
||||
BASIC_OPTIONAL_REVERSED = 2;
|
||||
BASIC_TYPING = 3;
|
||||
CLOZE = 4;
|
||||
}
|
||||
|
||||
Kind kind = 1;
|
||||
}
|
||||
|
||||
message NotetypeNames {
|
||||
repeated NotetypeNameId entries = 1;
|
||||
}
|
||||
|
||||
message NotetypeUseCounts {
|
||||
repeated NotetypeNameIdUseCount entries = 1;
|
||||
}
|
||||
|
||||
message NotetypeNameId {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message NotetypeNameIdUseCount {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
uint32 use_count = 3;
|
||||
}
|
||||
|
||||
message GetAuxConfigKeyRequest {
|
||||
int64 id = 1;
|
||||
string key = 2;
|
||||
}
|
||||
|
||||
message GetAuxTemplateConfigKeyRequest {
|
||||
int64 notetype_id = 1;
|
||||
uint32 card_ordinal = 2;
|
||||
string key = 3;
|
||||
}
|
||||
|
||||
message GetChangeNotetypeInfoRequest {
|
||||
int64 old_notetype_id = 1;
|
||||
int64 new_notetype_id = 2;
|
||||
}
|
||||
|
||||
message ChangeNotetypeRequest {
|
||||
repeated int64 note_ids = 1;
|
||||
// -1 is used to represent null, as nullable repeated fields
|
||||
// are unwieldy in protobuf
|
||||
repeated int32 new_fields = 2;
|
||||
repeated int32 new_templates = 3;
|
||||
int64 old_notetype_id = 4;
|
||||
int64 new_notetype_id = 5;
|
||||
int64 current_schema = 6;
|
||||
}
|
||||
|
||||
message ChangeNotetypeInfo {
|
||||
repeated string old_field_names = 1;
|
||||
repeated string old_template_names = 2;
|
||||
repeated string new_field_names = 3;
|
||||
repeated string new_template_names = 4;
|
||||
ChangeNotetypeRequest input = 5;
|
||||
}
|
|
@ -12,6 +12,10 @@ import anki.backend_pb2
|
|||
import anki.i18n_pb2
|
||||
import anki.cards_pb2
|
||||
import anki.collection_pb2
|
||||
import anki.decks_pb2
|
||||
import anki.deckconfig_pb2
|
||||
import anki.notes_pb2
|
||||
import anki.notetypes_pb2
|
||||
|
||||
import stringcase
|
||||
|
||||
|
@ -171,6 +175,10 @@ service_modules = dict(
|
|||
I18N=anki.i18n_pb2,
|
||||
COLLECTION=anki.collection_pb2,
|
||||
CARDS=anki.cards_pb2,
|
||||
NOTES=anki.notes_pb2,
|
||||
DECKS=anki.decks_pb2,
|
||||
DECK_CONFIG=anki.deckconfig_pb2,
|
||||
NOTETYPES=anki.notetypes_pb2,
|
||||
)
|
||||
|
||||
for service in anki.backend_pb2.ServiceIndex.DESCRIPTOR.values:
|
||||
|
|
|
@ -22,7 +22,6 @@ OpChanges = collection_pb2.OpChanges
|
|||
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
||||
OpChangesWithId = collection_pb2.OpChangesWithId
|
||||
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
||||
DefaultsForAdding = _pb.DeckAndNotetype
|
||||
BrowserRow = _pb.BrowserRow
|
||||
BrowserColumns = _pb.BrowserColumns
|
||||
|
||||
|
@ -370,7 +369,7 @@ class Collection(DeprecatedNamesMixin):
|
|||
|
||||
def defaults_for_adding(
|
||||
self, *, current_review_card: Optional[Card]
|
||||
) -> DefaultsForAdding:
|
||||
) -> anki.notes.DefaultsForAdding:
|
||||
"""Get starting deck and notetype for add screen.
|
||||
An option in the preferences controls whether this will be based on the current deck
|
||||
or current notetype.
|
||||
|
|
|
@ -23,7 +23,7 @@ from typing import (
|
|||
if TYPE_CHECKING:
|
||||
import anki
|
||||
|
||||
import anki.backend_pb2 as _pb
|
||||
from anki import deckconfig_pb2, decks_pb2
|
||||
from anki._legacy import DeprecatedNamesMixin, deprecated, print_deprecation_warning
|
||||
from anki.cards import CardId
|
||||
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
|
||||
|
@ -32,12 +32,12 @@ from anki.errors import NotFoundError
|
|||
from anki.utils import from_json_bytes, ids2str, intTime, to_json_bytes
|
||||
|
||||
# public exports
|
||||
DeckTreeNode = _pb.DeckTreeNode
|
||||
DeckNameId = _pb.DeckNameId
|
||||
FilteredDeckConfig = _pb.Deck.Filtered
|
||||
DeckCollapseScope = _pb.SetDeckCollapsedRequest.Scope
|
||||
DeckConfigsForUpdate = _pb.DeckConfigsForUpdate
|
||||
UpdateDeckConfigs = _pb.UpdateDeckConfigsRequest
|
||||
DeckTreeNode = decks_pb2.DeckTreeNode
|
||||
DeckNameId = decks_pb2.DeckNameId
|
||||
FilteredDeckConfig = decks_pb2.Deck.Filtered
|
||||
DeckCollapseScope = decks_pb2.SetDeckCollapsedRequest.Scope
|
||||
DeckConfigsForUpdate = deckconfig_pb2.DeckConfigsForUpdate
|
||||
UpdateDeckConfigs = deckconfig_pb2.UpdateDeckConfigsRequest
|
||||
|
||||
# type aliases until we can move away from dicts
|
||||
DeckDict = Dict[str, Any]
|
||||
|
|
|
@ -12,7 +12,7 @@ import time
|
|||
from typing import Any, Dict, List, NewType, Optional, Sequence, Tuple, Union
|
||||
|
||||
import anki # pylint: disable=unused-import
|
||||
import anki.backend_pb2 as _pb
|
||||
from anki import notetypes_pb2
|
||||
from anki._legacy import DeprecatedNamesMixin, deprecated, print_deprecation_warning
|
||||
from anki.collection import OpChanges, OpChangesWithId
|
||||
from anki.consts import *
|
||||
|
@ -22,11 +22,11 @@ from anki.stdmodels import StockNotetypeKind
|
|||
from anki.utils import checksum, from_json_bytes, to_json_bytes
|
||||
|
||||
# public exports
|
||||
NotetypeNameId = _pb.NotetypeNameId
|
||||
NotetypeNameIdUseCount = _pb.NotetypeNameIdUseCount
|
||||
NotetypeNames = _pb.NotetypeNames
|
||||
ChangeNotetypeInfo = _pb.ChangeNotetypeInfo
|
||||
ChangeNotetypeRequest = _pb.ChangeNotetypeRequest
|
||||
NotetypeNameId = notetypes_pb2.NotetypeNameId
|
||||
NotetypeNameIdUseCount = notetypes_pb2.NotetypeNameIdUseCount
|
||||
NotetypeNames = notetypes_pb2.NotetypeNames
|
||||
ChangeNotetypeInfo = notetypes_pb2.ChangeNotetypeInfo
|
||||
ChangeNotetypeRequest = notetypes_pb2.ChangeNotetypeRequest
|
||||
|
||||
# legacy types
|
||||
NotetypeDict = Dict[str, Any]
|
||||
|
@ -459,7 +459,9 @@ and notes.mid = ? and cards.ord = ?""",
|
|||
def _availClozeOrds(
|
||||
self, notetype: NotetypeDict, flds: str, allow_empty: bool = True
|
||||
) -> List[int]:
|
||||
note = _pb.Note(fields=[flds])
|
||||
import anki.notes_pb2
|
||||
|
||||
note = anki.notes_pb2.Note(fields=[flds])
|
||||
return list(self.col._backend.cloze_numbers_in_note(note))
|
||||
|
||||
# @deprecated(replaced_by=add_template)
|
||||
|
|
|
@ -9,15 +9,15 @@ import copy
|
|||
from typing import Any, List, NewType, Optional, Sequence, Tuple, Union
|
||||
|
||||
import anki # pylint: disable=unused-import
|
||||
import anki.backend_pb2 as _pb
|
||||
from anki import hooks
|
||||
from anki import hooks, notes_pb2
|
||||
from anki._legacy import DeprecatedNamesMixin
|
||||
from anki.consts import MODEL_STD
|
||||
from anki.models import NotetypeDict, NotetypeId, TemplateDict
|
||||
from anki.utils import joinFields
|
||||
|
||||
DuplicateOrEmptyResult = _pb.NoteFieldsCheckResponse.State
|
||||
NoteFieldsCheckResult = _pb.NoteFieldsCheckResponse.State
|
||||
DuplicateOrEmptyResult = notes_pb2.NoteFieldsCheckResponse.State
|
||||
NoteFieldsCheckResult = notes_pb2.NoteFieldsCheckResponse.State
|
||||
DefaultsForAdding = notes_pb2.DeckAndNotetype
|
||||
|
||||
# types
|
||||
NoteId = NewType("NoteId", int)
|
||||
|
@ -53,7 +53,7 @@ class Note(DeprecatedNamesMixin):
|
|||
assert note
|
||||
self._load_from_backend_note(note)
|
||||
|
||||
def _load_from_backend_note(self, note: _pb.Note) -> None:
|
||||
def _load_from_backend_note(self, note: notes_pb2.Note) -> None:
|
||||
self.id = NoteId(note.id)
|
||||
self.guid = note.guid
|
||||
self.mid = NotetypeId(note.notetype_id)
|
||||
|
@ -63,9 +63,9 @@ class Note(DeprecatedNamesMixin):
|
|||
self.fields = list(note.fields)
|
||||
self._fmap = self.col.models.field_map(self.note_type())
|
||||
|
||||
def _to_backend_note(self) -> _pb.Note:
|
||||
def _to_backend_note(self) -> notes_pb2.Note:
|
||||
hooks.note_will_flush(self)
|
||||
return _pb.Note(
|
||||
return notes_pb2.Note(
|
||||
id=self.id,
|
||||
guid=self.guid,
|
||||
notetype_id=self.mid,
|
||||
|
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
import anki
|
||||
import anki.backend_pb2 as _pb
|
||||
from anki import decks_pb2
|
||||
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
|
||||
from anki.config import Config
|
||||
|
||||
|
@ -22,7 +23,7 @@ from anki.utils import ids2str, intTime
|
|||
CongratsInfo = _pb.CongratsInfoResponse
|
||||
UnburyDeck = _pb.UnburyDeckRequest
|
||||
BuryOrSuspend = _pb.BuryOrSuspendCardsRequest
|
||||
FilteredDeckForUpdate = _pb.FilteredDeckForUpdate
|
||||
FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate
|
||||
|
||||
|
||||
class SchedulerBase:
|
||||
|
|
|
@ -6,11 +6,11 @@ from __future__ import annotations
|
|||
from typing import Any, Callable, List, Tuple
|
||||
|
||||
import anki
|
||||
import anki.backend_pb2 as _pb
|
||||
from anki import notetypes_pb2
|
||||
from anki.utils import from_json_bytes
|
||||
|
||||
# pylint: disable=no-member
|
||||
StockNotetypeKind = _pb.StockNotetype.Kind
|
||||
StockNotetypeKind = notetypes_pb2.StockNotetype.Kind
|
||||
|
||||
# add-on authors can add ("note type name", function)
|
||||
# to this list to have it shown in the add/clone note type screen
|
||||
|
|
|
@ -143,6 +143,13 @@ impl NotesService for Backend {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn get_single_notetype_of_notes(&self, input: pb::NoteIds) -> Result<pb::NotetypeId> {
|
||||
self.with_col(|col| {
|
||||
col.get_single_notetype_of_notes(&input.note_ids.into_newtype(NoteId))
|
||||
.map(Into::into)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn to_note_ids(ids: Vec<i64>) -> Vec<NoteId> {
|
||||
|
|
|
@ -159,13 +159,6 @@ impl NotetypesService for Backend {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_single_notetype_of_notes(&self, input: pb::NoteIds) -> Result<pb::NotetypeId> {
|
||||
self.with_col(|col| {
|
||||
col.get_single_notetype_of_notes(&input.note_ids.into_newtype(NoteId))
|
||||
.map(Into::into)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_change_notetype_info(
|
||||
&self,
|
||||
input: pb::GetChangeNotetypeInfoRequest,
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
pub mod backend {
|
||||
include!(concat!(env!("OUT_DIR"), "/anki.backend.rs"));
|
||||
macro_rules! protobuf {
|
||||
($ident:ident) => {
|
||||
pub mod $ident {
|
||||
include!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
concat!("/anki.", stringify!($ident), ".rs")
|
||||
));
|
||||
}
|
||||
pub mod i18n {
|
||||
include!(concat!(env!("OUT_DIR"), "/anki.i18n.rs"));
|
||||
}
|
||||
pub mod generic {
|
||||
include!(concat!(env!("OUT_DIR"), "/anki.generic.rs"));
|
||||
}
|
||||
pub mod cards {
|
||||
include!(concat!(env!("OUT_DIR"), "/anki.cards.rs"));
|
||||
}
|
||||
pub mod collection {
|
||||
include!(concat!(env!("OUT_DIR"), "/anki.collection.rs"));
|
||||
pub use $ident::*;
|
||||
};
|
||||
}
|
||||
|
||||
pub use backend::*;
|
||||
pub use cards::*;
|
||||
pub use collection::*;
|
||||
pub use generic::*;
|
||||
pub use i18n::*;
|
||||
protobuf!(backend);
|
||||
protobuf!(notes);
|
||||
protobuf!(notetypes);
|
||||
protobuf!(decks);
|
||||
protobuf!(deckconfig);
|
||||
protobuf!(i18n);
|
||||
protobuf!(cards);
|
||||
protobuf!(generic);
|
||||
protobuf!(collection);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@typescript-eslint/no-explicit-any: "off",
|
||||
*/
|
||||
|
||||
import { Backend } from "lib/proto";
|
||||
import { Notetypes } from "lib/proto";
|
||||
import { ChangeNotetypeState, negativeOneToNull, MapContext } from "./lib";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
|
@ -64,15 +64,15 @@ const exampleInfoSame = {
|
|||
|
||||
function differentState(): ChangeNotetypeState {
|
||||
return new ChangeNotetypeState(
|
||||
Backend.NotetypeNames.fromObject(exampleNames),
|
||||
Backend.ChangeNotetypeInfo.fromObject(exampleInfoDifferent)
|
||||
Notetypes.NotetypeNames.fromObject(exampleNames),
|
||||
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoDifferent)
|
||||
);
|
||||
}
|
||||
|
||||
function sameState(): ChangeNotetypeState {
|
||||
return new ChangeNotetypeState(
|
||||
Backend.NotetypeNames.fromObject(exampleNames),
|
||||
Backend.ChangeNotetypeInfo.fromObject(exampleInfoSame)
|
||||
Notetypes.NotetypeNames.fromObject(exampleNames),
|
||||
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoSame)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,22 @@
|
|||
@typescript-eslint/no-non-null-assertion: "off",
|
||||
*/
|
||||
|
||||
import { Backend } from "lib/proto";
|
||||
import { Notetypes } from "lib/proto";
|
||||
import { postRequest } from "lib/postrequest";
|
||||
import { readable, Readable } from "svelte/store";
|
||||
import { isEqual } from "lodash-es";
|
||||
|
||||
export async function getNotetypeNames(): Promise<Backend.NotetypeNames> {
|
||||
return Backend.NotetypeNames.decode(await postRequest("/_anki/notetypeNames", ""));
|
||||
export async function getNotetypeNames(): Promise<Notetypes.NotetypeNames> {
|
||||
return Notetypes.NotetypeNames.decode(
|
||||
await postRequest("/_anki/notetypeNames", "")
|
||||
);
|
||||
}
|
||||
|
||||
export async function getChangeNotetypeInfo(
|
||||
oldNotetypeId: number,
|
||||
newNotetypeId: number
|
||||
): Promise<Backend.ChangeNotetypeInfo> {
|
||||
return Backend.ChangeNotetypeInfo.decode(
|
||||
): Promise<Notetypes.ChangeNotetypeInfo> {
|
||||
return Notetypes.ChangeNotetypeInfo.decode(
|
||||
await postRequest(
|
||||
"/_anki/changeNotetypeInfo",
|
||||
JSON.stringify({ oldNotetypeId, newNotetypeId })
|
||||
|
@ -27,9 +29,9 @@ export async function getChangeNotetypeInfo(
|
|||
}
|
||||
|
||||
export async function changeNotetype(
|
||||
input: Backend.ChangeNotetypeRequest
|
||||
input: Notetypes.ChangeNotetypeRequest
|
||||
): Promise<void> {
|
||||
const data: Uint8Array = Backend.ChangeNotetypeRequest.encode(input).finish();
|
||||
const data: Uint8Array = Notetypes.ChangeNotetypeRequest.encode(input).finish();
|
||||
await postRequest("/_anki/changeNotetype", data);
|
||||
return;
|
||||
}
|
||||
|
@ -47,9 +49,9 @@ export function negativeOneToNull(list: number[]): (number | null)[] {
|
|||
export class ChangeNotetypeInfoWrapper {
|
||||
fields: (number | null)[];
|
||||
templates?: (number | null)[];
|
||||
readonly info: Backend.ChangeNotetypeInfo;
|
||||
readonly info: Notetypes.ChangeNotetypeInfo;
|
||||
|
||||
constructor(info: Backend.ChangeNotetypeInfo) {
|
||||
constructor(info: Notetypes.ChangeNotetypeInfo) {
|
||||
this.info = info;
|
||||
const templates = info.input!.newTemplates!;
|
||||
if (templates.length > 0) {
|
||||
|
@ -111,13 +113,13 @@ export class ChangeNotetypeInfoWrapper {
|
|||
);
|
||||
}
|
||||
|
||||
input(): Backend.ChangeNotetypeRequest {
|
||||
return this.info.input as Backend.ChangeNotetypeRequest;
|
||||
input(): Notetypes.ChangeNotetypeRequest {
|
||||
return this.info.input as Notetypes.ChangeNotetypeRequest;
|
||||
}
|
||||
|
||||
/// Pack changes back into input message for saving.
|
||||
intoInput(): Backend.ChangeNotetypeRequest {
|
||||
const input = this.info.input as Backend.ChangeNotetypeRequest;
|
||||
intoInput(): Notetypes.ChangeNotetypeRequest {
|
||||
const input = this.info.input as Notetypes.ChangeNotetypeRequest;
|
||||
input.newFields = nullToNegativeOne(this.fields);
|
||||
if (this.templates) {
|
||||
input.newTemplates = nullToNegativeOne(this.templates);
|
||||
|
@ -143,10 +145,13 @@ export class ChangeNotetypeState {
|
|||
|
||||
private info_: ChangeNotetypeInfoWrapper;
|
||||
private infoSetter!: (val: ChangeNotetypeInfoWrapper) => void;
|
||||
private notetypeNames: Backend.NotetypeNames;
|
||||
private notetypeNames: Notetypes.NotetypeNames;
|
||||
private notetypesSetter!: (val: NotetypeListEntry[]) => void;
|
||||
|
||||
constructor(notetypes: Backend.NotetypeNames, info: Backend.ChangeNotetypeInfo) {
|
||||
constructor(
|
||||
notetypes: Notetypes.NotetypeNames,
|
||||
info: Notetypes.ChangeNotetypeInfo
|
||||
) {
|
||||
this.info_ = new ChangeNotetypeInfoWrapper(info);
|
||||
this.info = readable(this.info_, (set) => {
|
||||
this.infoSetter = set;
|
||||
|
@ -197,7 +202,7 @@ export class ChangeNotetypeState {
|
|||
await changeNotetype(this.dataForSaving());
|
||||
}
|
||||
|
||||
dataForSaving(): Backend.ChangeNotetypeRequest {
|
||||
dataForSaving(): Notetypes.ChangeNotetypeRequest {
|
||||
return this.info_.intoInput();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@typescript-eslint/no-explicit-any: "off",
|
||||
*/
|
||||
|
||||
import { Backend } from "lib/proto";
|
||||
import { DeckConfig } from "lib/proto";
|
||||
import { DeckOptionsState } from "./lib";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
|
@ -94,7 +94,7 @@ const exampleData = {
|
|||
function startingState(): DeckOptionsState {
|
||||
return new DeckOptionsState(
|
||||
123,
|
||||
Backend.DeckConfigsForUpdate.fromObject(exampleData)
|
||||
DeckConfig.DeckConfigsForUpdate.fromObject(exampleData)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@typescript-eslint/no-non-null-assertion: "off",
|
||||
*/
|
||||
|
||||
import { Backend } from "lib/proto";
|
||||
import { DeckConfig } from "lib/proto";
|
||||
import { postRequest } from "lib/postrequest";
|
||||
import { Writable, writable, get, Readable, readable } from "svelte/store";
|
||||
import { isEqual, cloneDeep } from "lodash-es";
|
||||
|
@ -14,16 +14,16 @@ import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
|||
|
||||
export async function getDeckOptionsInfo(
|
||||
deckId: number
|
||||
): Promise<Backend.DeckConfigsForUpdate> {
|
||||
return Backend.DeckConfigsForUpdate.decode(
|
||||
): Promise<DeckConfig.DeckConfigsForUpdate> {
|
||||
return DeckConfig.DeckConfigsForUpdate.decode(
|
||||
await postRequest("/_anki/deckConfigsForUpdate", JSON.stringify({ deckId }))
|
||||
);
|
||||
}
|
||||
|
||||
export async function saveDeckOptions(
|
||||
input: Backend.UpdateDeckConfigsRequest
|
||||
input: DeckConfig.UpdateDeckConfigsRequest
|
||||
): Promise<void> {
|
||||
const data: Uint8Array = Backend.UpdateDeckConfigsRequest.encode(input).finish();
|
||||
const data: Uint8Array = DeckConfig.UpdateDeckConfigsRequest.encode(input).finish();
|
||||
await postRequest("/_anki/updateDeckConfigs", data);
|
||||
return;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ export async function saveDeckOptions(
|
|||
export type DeckOptionsId = number;
|
||||
|
||||
export interface ConfigWithCount {
|
||||
config: Backend.DeckConfig;
|
||||
config: DeckConfig.DeckConfig;
|
||||
useCount: number;
|
||||
}
|
||||
|
||||
|
@ -48,14 +48,14 @@ export interface ConfigListEntry {
|
|||
current: boolean;
|
||||
}
|
||||
|
||||
type ConfigInner = Backend.DeckConfig.Config;
|
||||
type ConfigInner = DeckConfig.DeckConfig.Config;
|
||||
export class DeckOptionsState {
|
||||
readonly currentConfig: Writable<ConfigInner>;
|
||||
readonly currentAuxData: Writable<Record<string, unknown>>;
|
||||
readonly configList: Readable<ConfigListEntry[]>;
|
||||
readonly parentLimits: Readable<ParentLimits>;
|
||||
readonly cardStateCustomizer: Writable<string>;
|
||||
readonly currentDeck: Backend.DeckConfigsForUpdate.CurrentDeck;
|
||||
readonly currentDeck: DeckConfig.DeckConfigsForUpdate.CurrentDeck;
|
||||
readonly defaults: ConfigInner;
|
||||
readonly addonComponents: Writable<DynamicSvelteComponent[]>;
|
||||
readonly v3Scheduler: boolean;
|
||||
|
@ -70,12 +70,13 @@ export class DeckOptionsState {
|
|||
private removedConfigs: DeckOptionsId[] = [];
|
||||
private schemaModified: boolean;
|
||||
|
||||
constructor(targetDeckId: number, data: Backend.DeckConfigsForUpdate) {
|
||||
constructor(targetDeckId: number, data: DeckConfig.DeckConfigsForUpdate) {
|
||||
this.targetDeckId = targetDeckId;
|
||||
this.currentDeck = data.currentDeck as Backend.DeckConfigsForUpdate.CurrentDeck;
|
||||
this.currentDeck =
|
||||
data.currentDeck as DeckConfig.DeckConfigsForUpdate.CurrentDeck;
|
||||
this.defaults = data.defaults!.config! as ConfigInner;
|
||||
this.configs = data.allConfig.map((config) => {
|
||||
const configInner = config.config as Backend.DeckConfig;
|
||||
const configInner = config.config as DeckConfig.DeckConfig;
|
||||
return {
|
||||
config: configInner,
|
||||
useCount: config.useCount!,
|
||||
|
@ -150,9 +151,9 @@ export class DeckOptionsState {
|
|||
}
|
||||
|
||||
/// Clone the current config, making it current.
|
||||
private addConfigFrom(name: string, source: Backend.DeckConfig.IConfig): void {
|
||||
private addConfigFrom(name: string, source: DeckConfig.DeckConfig.IConfig): void {
|
||||
const uniqueName = this.ensureNewNameUnique(name);
|
||||
const config = Backend.DeckConfig.create({
|
||||
const config = DeckConfig.DeckConfig.create({
|
||||
id: 0,
|
||||
name: uniqueName,
|
||||
config: cloneDeep(source),
|
||||
|
@ -188,7 +189,7 @@ export class DeckOptionsState {
|
|||
this.updateConfigList();
|
||||
}
|
||||
|
||||
dataForSaving(applyToChildren: boolean): Backend.UpdateDeckConfigsRequest {
|
||||
dataForSaving(applyToChildren: boolean): DeckConfig.UpdateDeckConfigsRequest {
|
||||
const modifiedConfigsExcludingCurrent = this.configs
|
||||
.map((c) => c.config)
|
||||
.filter((c, idx) => {
|
||||
|
@ -202,7 +203,7 @@ export class DeckOptionsState {
|
|||
// current must come last, even if unmodified
|
||||
this.configs[this.selectedIdx].config,
|
||||
];
|
||||
return Backend.UpdateDeckConfigsRequest.create({
|
||||
return DeckConfig.UpdateDeckConfigsRequest.create({
|
||||
targetDeckId: this.targetDeckId,
|
||||
removedConfigIds: this.removedConfigs,
|
||||
configs,
|
||||
|
|
|
@ -4,4 +4,6 @@
|
|||
import { anki } from "./backend_proto";
|
||||
import Backend = anki.backend;
|
||||
import Cards = anki.cards;
|
||||
export { Backend, Cards };
|
||||
import DeckConfig = anki.deckconfig;
|
||||
import Notetypes = anki.notetypes;
|
||||
export { Backend, Cards, DeckConfig, Notetypes };
|
||||
|
|
Loading…
Reference in a new issue