Skip to content

Migration from webL10n to i18next #4459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d78919c
Add files via upload
ac-mmi Feb 19, 2025
ac566eb
Add files via upload
ac-mmi Feb 20, 2025
29a4416
Merge branch 'sugarlabs:master' into master
ac-mmi Feb 21, 2025
1678672
Merge branch 'sugarlabs:master' into master
ac-mmi Feb 24, 2025
5ead512
Migrate internationalization from webL10n to i18next in JS files
ac-mmi Feb 24, 2025
b844c94
removed random encodings spoiling the .po files
ac-mmi Feb 24, 2025
5cf011e
Add files via upload
ac-mmi Feb 24, 2025
1680230
Changed the function definition of _() suited for i18next
ac-mmi Feb 24, 2025
d8bbb85
Merge branch 'internalization-js' of https://github.com/ac-mmi/musicb…
ac-mmi Feb 24, 2025
d6b1114
updated the i18next json files
ac-mmi Feb 24, 2025
e6e8c5a
changed the language switch functions to i18next standard in activity…
ac-mmi Feb 25, 2025
c21fb14
Merge branch 'master' into internalization-js
ac-mmi Mar 4, 2025
7c46058
Add files via upload
ac-mmi Mar 7, 2025
a238ef8
Add files via upload
ac-mmi Mar 7, 2025
ce5a5e5
Delete locales/ja-kana.json
ac-mmi Mar 7, 2025
c9d69ca
Delete locales/ja.json
ac-mmi Mar 7, 2025
fe630ea
Add files via upload
ac-mmi Mar 7, 2025
c25e7fb
Merge branch 'master' into internalization-js
ac-mmi Mar 7, 2025
740b4da
Merge branch 'master' into internalization-js
ac-mmi Mar 15, 2025
dcb2d7e
Merge branch 'master' into internalization-js
ac-mmi Mar 23, 2025
040a030
Add files via upload
ac-mmi Mar 24, 2025
bbaca35
Add files via upload
ac-mmi Mar 24, 2025
4540621
Add files via upload
ac-mmi Mar 24, 2025
75f50db
Add files via upload
ac-mmi Mar 24, 2025
45990f8
Update translate_ai.py
ac-mmi Mar 24, 2025
ea46f98
Add files via upload
ac-mmi Mar 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 58 additions & 27 deletions js/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,19 +308,23 @@ class Activity {
let lang = "en";
if (this.storage.languagePreference !== undefined) {
lang = this.storage.languagePreference;
document.webL10n.setLanguage(lang);
// If Japanese is selected, append the kanaPreference for proper lookup
if (lang === "ja" && this.storage.kanaPreference) {
lang += "-" + this.storage.kanaPreference; // e.g., "ja-kanji" or "ja-kana"
}
i18next.changeLanguage(lang);
} else {
lang = navigator.language;
if (lang.includes("-")) {
lang = lang.slice(0, lang.indexOf("-"));
document.webL10n.setLanguage(lang);
}
i18next.changeLanguage(lang);
}
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}


this.KeySignatureEnv = ["C", "major", false];
try {
if (this.storage.KeySignatureEnv !== undefined) {
Expand Down Expand Up @@ -561,15 +565,6 @@ class Activity {
if (helpfulWheelTop + 350 > windowHeight) {
docById("helpfulWheelDiv").style.top = (windowHeight - 350) + "px";
}
const selectedBlocksCount = this.blocks.selectedBlocks.filter(block => !block.trash).length;

if (selectedBlocksCount) {
this.helpfulWheelItems.find(ele => ele.label === "Move to trash").display = true;
this.helpfulWheelItems.find(ele => ele.label === "Duplicate").display = true;
} else {
this.helpfulWheelItems.find(ele => ele.label === "Move to trash").display = false;
this.helpfulWheelItems.find(ele => ele.label === "Duplicate").display = false;
}

docById("helpfulWheelDiv").style.display = "";

Expand Down Expand Up @@ -1419,6 +1414,14 @@ class Activity {
const confirmBtn = document.createElement("button");
confirmBtn.classList.add("confirm-button");
confirmBtn.textContent = "Confirm";
confirmBtn.style.backgroundColor = platformColor.blueButton;
confirmBtn.style.color = "white";
confirmBtn.style.border = "none";
confirmBtn.style.borderRadius = "4px";
confirmBtn.style.padding = "8px 16px";
confirmBtn.style.fontWeight = "bold";
confirmBtn.style.cursor = "pointer";
confirmBtn.style.marginRight = "16px";
confirmBtn.addEventListener("click", () => {
document.body.removeChild(modal);
clearCanvasAction();
Expand All @@ -1427,6 +1430,13 @@ class Activity {
const cancelBtn = document.createElement("button");
cancelBtn.classList.add("cancel-button");
cancelBtn.textContent = "Cancel";
cancelBtn.style.backgroundColor = "#f1f1f1";
cancelBtn.style.color = "black";
cancelBtn.style.border = "none";
cancelBtn.style.borderRadius = "4px";
cancelBtn.style.padding = "8px 16px";
cancelBtn.style.fontWeight = "bold";
cancelBtn.style.cursor = "pointer";
cancelBtn.addEventListener("click", () => {
document.body.removeChild(modal);
});
Expand Down Expand Up @@ -2971,6 +2981,7 @@ class Activity {
// note block to the active block.
this.blocks.activeBlock = this.blocks.blockList.length - 1;
};


//To create a sampler widget
this.makeSamplerWidget = (sampleName, sampleData) => {
Expand All @@ -2988,6 +2999,7 @@ class Activity {
this.blocks.loadNewBlocks(samplerStack);
};


/*
* Handles keyboard shortcuts in MB
*/
Expand Down Expand Up @@ -4259,6 +4271,33 @@ class Activity {
}, 5000);
};


const standardDurations = [
{ value: "1/1", duration: 1 },
{ value: "1/2", duration: 0.5 },
{ value: "1/4", duration: 0.25 },
{ value: "1/8", duration: 0.125 },
{ value: "1/16", duration: 0.0625 },
{ value: "1/32", duration: 0.03125 },
{ value: "1/64", duration: 0.015625 },
{ value: "1/128", duration: 0.0078125 }
];

this.getClosestStandardNoteValue = function(duration) {
let closest = standardDurations[0];
let minDiff = Math.abs(duration - closest.duration);

for (let i = 1; i < standardDurations.length; i++) {
let diff = Math.abs(duration - standardDurations[i].duration);
if (diff < minDiff) {
closest = standardDurations[i];
minDiff = diff;
}
}

return closest.value.split('/').map(Number);
}

/**
* Loads MB project from Planet.
* @param projectID {Planet project ID}
Expand Down Expand Up @@ -5647,13 +5686,7 @@ class Activity {

if (!this.helpfulWheelItems.find(ele => ele.label === "Select"))
this.helpfulWheelItems.push({label: "Select", icon: "imgsrc:data:image/svg+xml;base64," + window.btoa(base64Encode(SELECTBUTTON)), display: true, fn: this.selectMode });

if (!this.helpfulWheelItems.find(ele => ele.label === "Move to trash"))
this.helpfulWheelItems.push({label: "Move to trash", icon: "imgsrc:header-icons/empty-trash-button.svg", display: false, fn: this.deleteMultipleBlocks });

if (!this.helpfulWheelItems.find(ele => ele.label === "Duplicate"))
this.helpfulWheelItems.push({label: "Duplicate", icon: "imgsrc:header-icons/copy-button.svg" , display: false, fn: this.copyMultipleBlocks});


if (!this.helpfulWheelItems.find(ele => ele.label === "Clear"))
this.helpfulWheelItems.push({label: "Clear", icon: "imgsrc:data:image/svg+xml;base64," + window.btoa(base64Encode(CLEARBUTTON)), display: true, fn: () => this._allClear(false)});

Expand Down Expand Up @@ -6022,6 +6055,7 @@ class Activity {
// end the drag on navbar
document.getElementById("toolbars").addEventListener("mouseover", () => {this.isDragging = false;});


this.deleteMultipleBlocks = () => {
if (this.blocks.selectionModeOn) {
const blocksArray = this.blocks.selectedBlocks;
Expand Down Expand Up @@ -6084,13 +6118,18 @@ class Activity {
};



this.selectMode = () => {
this.moving = false;
this.isSelecting = !this.isSelecting;
(this.isSelecting) ? this.textMsg(_("Select is enabled.")) : this.textMsg(_("Select is disabled."));

}

docById("helpfulWheelDiv").style.display = "none";
};


this._create2Ddrag = () => {
this.dragArea = {};
this.selectedBlocks = [];
Expand Down Expand Up @@ -6578,8 +6617,6 @@ class Activity {
that.errorMsg(
_("Cannot load project from the file. Please check the file type.")
);
} else if (files[0].type === "audio/wav") {
this.makeSamplerWidget(files[0].name, reader.result);
} else {
const cleanData = rawData.replace("\n", " ");
let obj;
Expand Down Expand Up @@ -6696,12 +6733,6 @@ class Activity {
abcReader.readAsText(files[0]);
return;
}

if (files[0].type === "audio/wav") {
reader.readAsDataURL(files[0]);
return;
}

reader.readAsText(files[0]);
reader.readAsText(files[0]);
window.scroll(0, 0);
Expand Down
17 changes: 15 additions & 2 deletions js/languagebox.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
* @returns {void}
*/
ja_onclick() {
this._language = "ja";
this._language = "ja-kanji";
this.activity.storage.kanaPreference = "kanji";
this.hide();
}
Expand All @@ -69,7 +69,7 @@
* @returns {void}
*/
kana_onclick() {
this._language = "ja";
this._language = "ja-kana";
this.activity.storage.kanaPreference = "kana";
this.hide();
}
Expand Down Expand Up @@ -226,13 +226,26 @@
ur:"اپنی زبان کی ترجیح کو تبدیل کرنے کے لئے اپنے براؤزر کو تازہ دم کریں۔"
};
if (localStorage.getItem("languagePreference") === this._language) {
if(this._language.includes('ja'))

Check warning on line 229 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote
{
this._language=this._language.split('-')[0];

Check warning on line 231 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote

Check warning on line 231 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Trailing spaces not allowed
}

localStorage.setItem("languagePreference",this._language);
this.activity.textMsg(_("Music Blocks is already set to this language."));
}
else{
this.activity.storage.languagePreference = this._language;

if (this._language === "ja" && this.activity.storage.kanaPreference === "kana") {
this.activity.textMsg(MSGPrefix + MSG["kana"] + MSGSuffix);
} else {

if(this._language.includes('ja'))

Check warning on line 244 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote
{
this._language=this._language.split('-')[0];

Check warning on line 246 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote

Check warning on line 246 in js/languagebox.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Trailing spaces not allowed
}

this.activity.textMsg(MSGPrefix + MSG[this._language] + MSGSuffix);
}
}
Expand Down
101 changes: 99 additions & 2 deletions js/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,106 @@
prefixfree: "../bower_components/prefixfree/prefixfree.min",
samples: "../sounds/samples",
planet: "../js/planet",
tonejsMidi: "../node_modules/@tonejs/midi/dist/Midi"
tonejsMidi: "../node_modules/@tonejs/midi/dist/Midi",
i18next: "../node_modules/i18next/dist/umd/i18next.min",
i18nextHttpBackend: "../node_modules/i18next-http-backend/i18nextHttpBackend.min"
},
packages: []
});

requirejs(["utils/utils", "activity/activity"]);
require.config({
urlArgs: "bust=" + (new Date()).getTime()
});

requirejs(['i18next', 'i18nextHttpBackend'], function(i18next, i18nextHttpBackend) {

Check warning on line 41 in js/loader.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote

Check warning on line 41 in js/loader.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote

function updateContent() {
console.log('updateContent() called'); // Debugging line

Check warning on line 44 in js/loader.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote
const elements = document.querySelectorAll("[data-i18n]");

elements.forEach((element) => {
const key = element.getAttribute("data-i18n");
const translation = i18next.t(key);
element.textContent = translation;
});
}

async function initializeI18next() {
return new Promise((resolve, reject) => {
i18next
.use(i18nextHttpBackend)
.init({
lng: 'en',

Check warning on line 59 in js/loader.js

View workflow job for this annotation

GitHub Actions / Lint updated JavaScript files with ESLint

Strings must use doublequote
fallbackLng: 'en',
keySeparator: '=)',
nsSeparator: 'false',
interpolation: {
escapeValue: false
},
backend: {
loadPath: '../locales/{{lng}}.json'
}
}, function(err, t) {
if (err) {
console.error('i18next init failed:', err);
reject(err);
} else {
console.log('i18next initialized');
window.i18next = i18next;
console.log('i18next Store:', i18next.store.data);
resolve(i18next);
}
});


i18next.on('initialized', function() {
console.log('i18next initialized');
});

i18next.on('loaded', function(loaded) {
console.log('i18next loaded:', loaded);
});




});
}

async function main() {
try {
await initializeI18next();

if (document.readyState === 'loading') {
document.addEventListener("DOMContentLoaded", function() {
console.log('DOMContentLoaded event triggered');
updateContent();
});
} else { // DOM is already fully loaded
console.log('DOM already loaded, updating content immediately');
updateContent();
}
} catch (error) {
console.error('Error initializing i18next:', error);
}
}

main().then(() => {
requirejs(["utils/utils", "activity/activity"]);
});

i18next.changeLanguage(lang, (err, t) => {
if (err) {
console.error('Error changing language:', err);
return;
}
console.log('Language changed to:', lang);
updateContent();
});

i18next.on('languageChanged', function() {
updateContent();
});
});

// requirejs(["utils/utils", "activity/activity"]);
Loading
Loading