mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Fix IO groups breaking upon editing (#2766)
* Fix IO groups breaking upon editing * Emit change signal after group/ungroup
This commit is contained in:
parent
9740393d72
commit
14940a617b
5 changed files with 35 additions and 14 deletions
|
@ -59,11 +59,15 @@ message GetImageOcclusionNoteResponse {
|
|||
string value = 2;
|
||||
}
|
||||
|
||||
message ImageOcclusion {
|
||||
message ImageOcclusionShape {
|
||||
string shape = 1;
|
||||
repeated ImageOcclusionProperty properties = 2;
|
||||
}
|
||||
|
||||
message ImageOcclusion {
|
||||
repeated ImageOcclusionShape shapes = 1;
|
||||
}
|
||||
|
||||
message ImageOcclusionNote {
|
||||
bytes image_data = 1;
|
||||
repeated ImageOcclusion occlusions = 2;
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusion;
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusionShape;
|
||||
use htmlescape::encode_attribute;
|
||||
use lazy_static::lazy_static;
|
||||
use nom::branch::alt;
|
||||
|
@ -317,14 +319,20 @@ fn render_image_occlusion(text: &str, question_side: bool, active: bool, ordinal
|
|||
}
|
||||
|
||||
pub fn parse_image_occlusions(text: &str) -> Vec<ImageOcclusion> {
|
||||
parse_text_with_clozes(text)
|
||||
.iter()
|
||||
.filter_map(|node| match node {
|
||||
TextOrCloze::Cloze(cloze) if cloze.image_occlusion().is_some() => {
|
||||
parse_image_cloze(cloze.image_occlusion().unwrap())
|
||||
let mut occlusions: HashMap<u16, Vec<ImageOcclusionShape>> = HashMap::new();
|
||||
for node in parse_text_with_clozes(text) {
|
||||
if let TextOrCloze::Cloze(cloze) = node {
|
||||
if cloze.image_occlusion().is_some() {
|
||||
if let Some(shape) = parse_image_cloze(cloze.image_occlusion().unwrap()) {
|
||||
occlusions.entry(cloze.ordinal).or_default().push(shape);
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
occlusions
|
||||
.values()
|
||||
.map(|v| ImageOcclusion { shapes: v.to_vec() })
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
use std::fmt::Write;
|
||||
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusion;
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusionProperty;
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusionShape;
|
||||
use htmlescape::encode_attribute;
|
||||
use nom::bytes::complete::escaped;
|
||||
use nom::bytes::complete::is_not;
|
||||
|
@ -18,7 +18,7 @@ fn unescape(text: &str) -> String {
|
|||
text.replace("\\:", ":")
|
||||
}
|
||||
|
||||
pub fn parse_image_cloze(text: &str) -> Option<ImageOcclusion> {
|
||||
pub fn parse_image_cloze(text: &str) -> Option<ImageOcclusionShape> {
|
||||
if let Some((shape, _)) = text.split_once(':') {
|
||||
let mut properties = vec![];
|
||||
let mut remaining = &text[shape.len()..];
|
||||
|
@ -36,7 +36,7 @@ pub fn parse_image_cloze(text: &str) -> Option<ImageOcclusion> {
|
|||
})
|
||||
}
|
||||
|
||||
return Some(ImageOcclusion {
|
||||
return Some(ImageOcclusionShape {
|
||||
shape: shape.to_string(),
|
||||
properties,
|
||||
});
|
||||
|
|
|
@ -200,6 +200,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
{iconSize}
|
||||
on:click={() => {
|
||||
tool.action(canvas);
|
||||
emitChangeSignal();
|
||||
}}
|
||||
>
|
||||
{@html tool.icon}
|
||||
|
|
|
@ -18,9 +18,17 @@ export function extractShapesFromClozedField(
|
|||
): ShapeOrShapes[] {
|
||||
const output: ShapeOrShapes[] = [];
|
||||
for (const occlusion of occlusions) {
|
||||
if (isValidType(occlusion.shape)) {
|
||||
const props = Object.fromEntries(occlusion.properties.map(prop => [prop.name, prop.value]));
|
||||
output.push(buildShape(occlusion.shape, props));
|
||||
const group: Shape[] = [];
|
||||
for (const shape of occlusion.shapes) {
|
||||
if (isValidType(shape.shape)) {
|
||||
const props = Object.fromEntries(shape.properties.map(prop => [prop.name, prop.value]));
|
||||
group.push(buildShape(shape.shape, props));
|
||||
}
|
||||
}
|
||||
if (group.length > 1) {
|
||||
output.push(group);
|
||||
} else {
|
||||
output.push(group[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue