Fix IO groups breaking upon editing (#2766)

* Fix IO groups breaking upon editing

* Emit change signal after group/ungroup
This commit is contained in:
Abdo 2023-10-23 02:43:31 +03:00 committed by GitHub
parent 9740393d72
commit 14940a617b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 14 deletions

View file

@ -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;

View file

@ -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()
}

View file

@ -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,
});

View file

@ -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}

View file

@ -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]);
}
}