mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 23:12:21 -04:00

- Introduced a new transact() method that wraps the return value in a separate struct that describes the changes that were made. - Changes are now gathered from the undo log, so we don't need to guess at what was changed - eg if update_note() is called with identical note contents, no changes are returned. Card changes will only be set if cards were actually generated by the update_note() call, and tag will only be set if a new tag was added. - mw.perform_op() has been updated to expect the op to return the changes, or a structure with the changes in it, and it will use them to fire the change hook, instead of fetching the changes from undo_status(), so there is no risk of race conditions. - the various calls to mw.perform_op() have been split into separate files like card_ops.py. Aside from making the code cleaner, this works around a rather annoying issue with mypy. Because we run it with no_strict_optional, mypy is happy to accept an operation that returns None, despite the type signature saying it requires changes to be returned. Turning no_strict_optional on for the whole codebase is not practical at the moment, but we can enable it for individual files. Still todo: - The cursor keeps moving back to the start of a field when typing - we need to ignore the refresh hook when we are the initiator. - The busy cursor icon should probably be delayed a few hundreds ms. - Still need to think about a nicer way of handling saveNow() - op_made_changes(), op_affects_study_queue() might be better embedded as properties in the object instead
91 lines
1.8 KiB
Rust
91 lines
1.8 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use crate::{backend_proto as pb, prelude::*};
|
|
|
|
impl From<Vec<u8>> for pb::Json {
|
|
fn from(json: Vec<u8>) -> Self {
|
|
pb::Json { json }
|
|
}
|
|
}
|
|
|
|
impl From<String> for pb::String {
|
|
fn from(val: String) -> Self {
|
|
pb::String { val }
|
|
}
|
|
}
|
|
|
|
impl From<bool> for pb::Bool {
|
|
fn from(val: bool) -> Self {
|
|
pb::Bool { val }
|
|
}
|
|
}
|
|
|
|
impl From<i64> for pb::Int64 {
|
|
fn from(val: i64) -> Self {
|
|
pb::Int64 { val }
|
|
}
|
|
}
|
|
|
|
impl From<u32> for pb::UInt32 {
|
|
fn from(val: u32) -> Self {
|
|
pb::UInt32 { val }
|
|
}
|
|
}
|
|
|
|
impl From<usize> for pb::UInt32 {
|
|
fn from(val: usize) -> Self {
|
|
pb::UInt32 { val: val as u32 }
|
|
}
|
|
}
|
|
|
|
impl From<()> for pb::Empty {
|
|
fn from(_val: ()) -> Self {
|
|
pb::Empty {}
|
|
}
|
|
}
|
|
|
|
impl From<pb::CardId> for CardID {
|
|
fn from(cid: pb::CardId) -> Self {
|
|
CardID(cid.cid)
|
|
}
|
|
}
|
|
|
|
impl Into<Vec<CardID>> for pb::CardIDs {
|
|
fn into(self) -> Vec<CardID> {
|
|
self.cids.into_iter().map(CardID).collect()
|
|
}
|
|
}
|
|
|
|
impl From<pb::NoteId> for NoteID {
|
|
fn from(nid: pb::NoteId) -> Self {
|
|
NoteID(nid.nid)
|
|
}
|
|
}
|
|
|
|
impl From<pb::NoteTypeId> for NoteTypeID {
|
|
fn from(ntid: pb::NoteTypeId) -> Self {
|
|
NoteTypeID(ntid.ntid)
|
|
}
|
|
}
|
|
|
|
impl From<pb::DeckConfigId> for DeckConfID {
|
|
fn from(dcid: pb::DeckConfigId) -> Self {
|
|
DeckConfID(dcid.dcid)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<String>> for pb::StringList {
|
|
fn from(vals: Vec<String>) -> Self {
|
|
pb::StringList { vals }
|
|
}
|
|
}
|
|
|
|
impl From<OpOutput<usize>> for pb::OpChangesWithCount {
|
|
fn from(out: OpOutput<usize>) -> Self {
|
|
pb::OpChangesWithCount {
|
|
count: out.output as u32,
|
|
changes: Some(out.changes.into()),
|
|
}
|
|
}
|
|
}
|