Skip to content

Commit

Permalink
fix: editor sentence translation management
Browse files Browse the repository at this point in the history
* fix: editing translations

fix: deletion of translation

* chore: update browserslist db

* chore: update browserslist db

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
deltork and github-actions[bot] authored Nov 8, 2024
1 parent 58a4af7 commit ffeeedf
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 27 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 26 additions & 13 deletions packages/studio-web/src/app/shared/download/download.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ Please host all assets on your server, include the font and package imports defi
readalong: Components.ReadAlong,
): Promise<boolean> {
const translations: any = await readalong.getTranslations();

if (Object.keys(translations).length == 0) {
//if there are no translations
//remove all existing translations
doc
.querySelectorAll("s.translation, s.sentence__translation")
.forEach((sentence: Element) => {
sentence.remove();
});
return false;
} else {
const sentence_nodes = doc.querySelectorAll(
Expand All @@ -73,16 +81,31 @@ Please host all assets on your server, include the font and package imports defi
(t_node) => t_node.id,
),
);
//update current text or remove deleted translation
doc
.querySelectorAll("s.translation, s.sentence__translation")
.forEach((sentence: Element) => {
const sentenceID: string = sentence.hasAttribute("sentence-id")
? (sentence.getAttribute("sentence-id") as string)
: sentence.id;
if (sentenceID in translations) {
sentence.textContent = translations[sentenceID];
} else {
//remove deleted translations
sentence.remove();
}
});
// Add new translations
sentence_nodes.forEach((sentence: Element) => {
// Add a translation
if (
sentence.id in translations &&
!translation_node_ids.has(sentence.id)
) {
// No namespaces!! NO! NO! NO!
let newSentence = document.createElementNS(null, "s");
newSentence.setAttribute("do-not-align", "true");
newSentence.setAttribute("id", sentence.id);
newSentence.setAttribute("id", `${sentence.id}`);
newSentence.setAttribute("sentence-id", sentence.id);
newSentence.setAttribute(
"class",
"sentence__translation editable__translation",
Expand All @@ -91,18 +114,8 @@ Please host all assets on your server, include the font and package imports defi
newSentence.append(translations[sentence.id]);
sentence.insertAdjacentElement("afterend", newSentence);
}
// Remove a translation
if (
sentence.id in translations &&
translations[sentence.id] === null &&
translation_node_ids.has(sentence.id)
) {
let elementToRemove = doc.querySelector(
`#${sentence.id}.sentence__translation`,
);
elementToRemove?.remove();
}
});

return true;
}
}
Expand Down
9 changes: 3 additions & 6 deletions packages/web-component/cypress/e2e/edit.cy.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
context("The Readalong Component", () => {
/**
* Wait for the audio and the SMIL to load.
*/
const EXPECTED_LOADING_TIME = 2000; // ms

beforeEach(() => {
cy.intercept(/\.readalong/).as("text");
cy.intercept(/\.m4a/).as("audio");
cy.visit("/ej-fra/index-edit.html");
});

it("should have editable translation buttons", () => {
cy.wait(EXPECTED_LOADING_TIME);
cy.wait(["@text", "@audio"]);
cy.readalongElement().should("be.visible");

cy.readalong().within(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { distinctUntilChanged } from "rxjs/operators";
import {
Component,
Element,
Fragment,
h,
Listen,
Method,
Expand All @@ -23,6 +24,7 @@ import {
USER_PREFERENCE_VERSION,
setUserPreferences,
extractMeta,
sentenceIsAligned,
} from "../../utils/utils";
import {
Alignment,
Expand Down Expand Up @@ -185,6 +187,7 @@ export class ReadAlongComponent {
hasTextTranslations: boolean = false;
@State() images: { [key: string]: string | null };
@State() translations: { [key: string]: string | null };

latestTranslation: string; // when a new translation line is added, this is populated with the added HTMLElement's ID which is queried and focused after the component re-renders
assetsStatus: ASSETS_STATUS = {
AUDIO: LOADING,
Expand Down Expand Up @@ -1065,7 +1068,9 @@ export class ReadAlongComponent {
const paragraphs = (page as Page).paragraphs;
const sentences = paragraphs[
paragraphs.length - 1
].querySelectorAll("s:not(.translation)"); //get non-translation sentences in the last paragraph
].querySelectorAll(
"s:not(.translation), s:not(.sentence__translation)",
); //get non-translation sentences in the last paragraph
const word =
sentences[sentences.length - 1].querySelector("w:last-of-type"); //get the last word of the last sentence
this.endOfPageTags[word.id] = [
Expand All @@ -1074,6 +1079,40 @@ export class ReadAlongComponent {
];
this.finalTaggedWord = word.id; // do not pause on the last word of the read-along
} catch (err) {}

let lastAlignedSentenceId: string | null = null;
//get the translations
page.paragraphs
.map((paragraph) => paragraph.querySelectorAll("s"))
.forEach((sentences) => {
if (sentences.length) {
sentences.forEach((sentence) => {
if (sentence.id && sentenceIsAligned(sentence)) {
lastAlignedSentenceId = `${sentence.id}`;
} else if (/translation/.test(sentence.className)) {
const translation: { [key: string]: string } = {};
if ((sentence as Element).hasAttribute("sentence-id")) {
let sentenceID = (sentence as Element).getAttribute(
"sentence-id",
);

translation[sentenceID] = sentence.textContent;
this.translations = {
...this.translations,
...translation,
};
} else if (lastAlignedSentenceId != null) {
translation[lastAlignedSentenceId] = sentence.textContent;
lastAlignedSentenceId = null;
this.translations = {
...this.translations,
...translation,
};
}
}
});
}
});
}
}
// this.parsed_text.map((page, i) => page.img ? [i, page.img] : [i, null])
Expand Down Expand Up @@ -1347,13 +1386,13 @@ export class ReadAlongComponent {
}

removeLine(sentence_element: Element) {
let newTranslation = {};
newTranslation[sentence_element.id] = null;
this.translations = { ...this.translations, ...newTranslation };
delete this.translations[sentence_element.id];
this.translations = { ...this.translations };
}

updateTranslation(sentence_id: string, text: string) {
this.translations[sentence_id] = text;
//console.log(JSON.stringify(this.translations));
}

async handleFiles(event: any, pageIndex: number) {
Expand Down Expand Up @@ -1608,7 +1647,11 @@ export class ReadAlongComponent {
if (props.sentenceData.hasAttribute("xml:lang")) {
nodeProps["lang"] = props.sentenceData.getAttribute("xml:lang");
}

if (
this.mode === "EDIT" &&
/translation/.test(props.sentenceData.getAttribute("class"))
)
return <Fragment></Fragment>;
return (
<div
{...nodeProps}
Expand Down Expand Up @@ -1708,6 +1751,7 @@ export class ReadAlongComponent {
if (event.key == "Enter") event.preventDefault();
}}
data-placeholder={this.getI18nString("line-placeholder")}
innerHTML={this.translations[sentenceID]}
></p>
</span>
);
Expand Down
4 changes: 4 additions & 0 deletions packages/web-component/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,7 @@ export const setUserPreferences = (userPref: UserPreferences) => {
JSON.stringify(userPref),
);
};

export const sentenceIsAligned = (sentence: Element): boolean => {
return sentence.innerHTML.includes("</w>");
};

0 comments on commit ffeeedf

Please sign in to comment.