Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 41 additions & 3 deletions CustomApps/lyrics-plus/OptionsMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ function getMusixmatchTranslationPrefix() {

const TranslationMenu = react.memo(({ friendlyLanguage, hasTranslation, musixmatchLanguages, musixmatchSelectedLanguage }) => {
const musixmatchTranslationPrefix = getMusixmatchTranslationPrefix();

const [languageMap, setLanguageMap] = react.useState({});

react.useEffect(() => {
let cancelled = false;

if (typeof ProviderMusixmatch !== "undefined" && ProviderMusixmatch && typeof ProviderMusixmatch.getLanguages === "function") {
(async () => {
try {
const languages = await ProviderMusixmatch.getLanguages();
if (!cancelled) {
setLanguageMap(languages);
}
} catch (error) {
console.error("Failed to fetch Musixmatch languages:", error);
}
})();
}

return () => {
cancelled = true;
};
}, []);

const items = useMemo(() => {
let sourceOptions = {
none: "None",
Expand Down Expand Up @@ -126,14 +150,27 @@ const TranslationMenu = react.memo(({ friendlyLanguage, hasTranslation, musixmat
}

if (availableMusixmatchLanguages.length) {
const musixmatchOptions = availableMusixmatchLanguages.reduce((acc, code) => {
const musixmatchOptionsArray = availableMusixmatchLanguages.map((code) => {
let label = "";
try {
label = musixmatchDisplay.of(code) ?? code.toUpperCase();
if (languageMap && languageMap[code]) {
label = languageMap[code];
} else {
label = musixmatchDisplay.of(code) ?? code.toUpperCase();
}
} catch (e) {
label = code.toUpperCase();
}
acc[`${musixmatchTranslationPrefix}${code}`] = `${label} (Musixmatch)`;
return {
key: `${musixmatchTranslationPrefix}${code}`,
label: `${label} (Musixmatch)`,
};
});

musixmatchOptionsArray.sort((a, b) => a.label.localeCompare(b.label));

const musixmatchOptions = musixmatchOptionsArray.reduce((acc, { key, label }) => {
acc[key] = label;
return acc;
}, {});
sourceOptions = { ...sourceOptions, ...musixmatchOptions };
Expand Down Expand Up @@ -225,6 +262,7 @@ const TranslationMenu = react.memo(({ friendlyLanguage, hasTranslation, musixmat
Array.isArray(musixmatchLanguages) ? musixmatchLanguages.join(",") : "",
musixmatchSelectedLanguage || "",
musixmatchTranslationPrefix,
languageMap,
]);

useEffect(() => {
Expand Down
54 changes: 53 additions & 1 deletion CustomApps/lyrics-plus/ProviderMusixmatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,57 @@ const ProviderMusixmatch = (() => {
}));
}

return { findLyrics, getKaraoke, getSynced, getUnsynced, getTranslation };
let languageMap = null;
async function getLanguages() {
if (languageMap) return languageMap;

try {
const cached = localStorage.getItem("lyrics-plus:musixmatch-languages");
if (cached) {
const tempMap = JSON.parse(cached);
// Check cache version
if (tempMap.__version === 1) {
delete tempMap.__version;
languageMap = tempMap;
return languageMap;
}
}
} catch (e) {
console.warn("Failed to parse cached languages", e);
}

const baseURL = "https://apic-desktop.musixmatch.com/ws/1.1/languages.get?app_id=web-desktop-app-v1.0&get_romanized_info=1&";

const params = {
usertoken: CONFIG.providers.musixmatch.token,
};

const finalURL =
baseURL +
Object.keys(params)
.map((key) => `${key}=${encodeURIComponent(params[key])}`)
.join("&");

try {
let body = await Spicetify.CosmosAsync.get(finalURL, null, headers);
if (body?.message?.body?.language_list) {
languageMap = {};
body.message.body.language_list.forEach((item) => {
const lang = item.language;
if (lang.language_name) {
const name = lang.language_name.charAt(0).toUpperCase() + lang.language_name.slice(1);
if (lang.language_iso_code_1) languageMap[lang.language_iso_code_1] = name;
if (lang.language_iso_code_3) languageMap[lang.language_iso_code_3] = name;
}
});
localStorage.setItem("lyrics-plus:musixmatch-languages", JSON.stringify({ ...languageMap, __version: 1 }));
return languageMap;
}
} catch (e) {
console.error("Failed to fetch languages", e);
}
return {};
}

return { findLyrics, getKaraoke, getSynced, getUnsynced, getTranslation, getLanguages };
})();