Skip to content

Commit

Permalink
Merge pull request live-codes#682 from live-codes/fix-sdk-set-appLang…
Browse files Browse the repository at this point in the history
…uage

Fix changing appLanguage from SDK
  • Loading branch information
hatemhosny authored Dec 10, 2024
2 parents 9068350 + 5ad16f4 commit b5fd5e6
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 33 deletions.
49 changes: 34 additions & 15 deletions src/livecodes/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,7 @@ const getAllEditors = (): CodeEditor[] => [

const setTheme = (theme: Theme, editorTheme: Config['editorTheme']) => {
const themes = ['light', 'dark'];
const root = document.querySelector(':root');
const root = document.documentElement;
root?.classList.remove(...themes);
root?.classList.add(theme);
changeThemeColor();
Expand Down Expand Up @@ -1783,7 +1783,7 @@ const changeThemeColor = () => {
const { themeColor, theme } = getConfig();
const color = themeColor || getDefaultColor();
const { h, s, l } = colorToHsla(color);
const root = document.querySelector(':root') as HTMLElement;
const root = document.documentElement;
root.style.setProperty('--hue', `${h}`);
root.style.setProperty('--st', `${s}%`);
root.style.setProperty('--lt', `${theme === 'light' ? 100 : l}%`);
Expand All @@ -1798,7 +1798,7 @@ const changeThemeColor = () => {

const getDefaultColor = () => {
if (defaultColor) return defaultColor;
const root = document.querySelector(':root') as HTMLElement;
const root = document.documentElement;
const theme = getConfig().theme;
root.classList.remove('light');
const h = getComputedStyle(root).getPropertyValue('--hue');
Expand All @@ -1816,7 +1816,7 @@ const getDefaultColor = () => {

const setFontSize = () => {
const fontSize = getConfig().fontSize || (isEmbed ? 12 : 14);
const root = document.querySelector(':root') as HTMLElement;
const root = document.documentElement;
root.style.setProperty('--font-size', `${fontSize + 2}px`);
};

Expand Down Expand Up @@ -2441,15 +2441,8 @@ const handleI18nMenu = () => {
eventsManager.addEventListener(link, 'click', (ev) => {
ev.preventDefault();
if (langCode === getConfig().appLanguage) return;
checkSavedAndExecute(async () => {
setUserConfig({ appLanguage: langCode as AppLanguage });
if (!i18n && langCode !== 'en') {
modal.show(loadingMessage(), { size: 'small' });
await loadI18n(langCode as AppLanguage);
}
await i18n?.changeLanguage(langCode);
setAppLanguage(/* reload= */ true);
})();
setUserConfig({ appLanguage: langCode as AppLanguage });
changeAppLanguage(langCode as AppLanguage);
});
li.appendChild(link);
i18nMenu.appendChild(li);
Expand Down Expand Up @@ -4490,8 +4483,16 @@ const translateStringMock = <Key extends I18nKeyType, Value extends string>(
return result;
};

const setAppLanguage = (reload: boolean = false) => {
const lang = i18n?.getLanguage() ?? 'en';
const setAppLanguage = ({
appLanguage,
reload = false,
url,
}: {
appLanguage?: AppLanguage;
reload?: boolean;
url?: string;
} = {}) => {
const lang = (appLanguage ?? i18n?.getLanguage() ?? 'en') as AppLanguage;
document.documentElement.lang = lang;
document.documentElement.dir = i18n?.getLanguageDirection() ?? 'ltr';
if (!reload && (isEmbed || params.appLanguage)) return;
Expand All @@ -4515,12 +4516,24 @@ const setAppLanguage = (reload: boolean = false) => {
data: i18nSplashData,
reload,
lang,
url,
},
},
location.origin,
);
};

const changeAppLanguage = async (appLanguage: AppLanguage) => {
if (!i18n && appLanguage !== 'en') {
modal.show(loadingMessage(), { size: 'small' });
await loadI18n(appLanguage);
}
await i18n?.changeLanguage(appLanguage);
const url = (await share(/* shortUrl = */ false, /* contentOnly = */ false)).url;
isSaved = true;
setAppLanguage({ appLanguage, reload: true, url });
};

const basicHandlers = () => {
notifications = createNotifications();
modal = createModal(translateElement);
Expand Down Expand Up @@ -4981,7 +4994,13 @@ const createApi = (): API => {

const apiSetConfig = async (newConfig: Partial<Config>): Promise<Config> => {
const newAppConfig = buildConfig({ ...getConfig(), ...newConfig });
const hasNewAppLanguage =
newConfig.appLanguage && newConfig.appLanguage !== i18n?.getLanguage();
setConfig(newAppConfig);
if (hasNewAppLanguage) {
changeAppLanguage(newConfig.appLanguage!);
return newAppConfig;
}
await applyConfig(newConfig);
const content = getContentConfig(newConfig as Config);
const hasContent = Object.values(content).some((value) => value != null);
Expand Down
6 changes: 6 additions & 0 deletions src/livecodes/languages/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export const languageIsEnabled = (language: Language, config: Config) => {
const lang = getLanguageByAlias(language);
if (!lang) return false;
if (!config.languages) return true;
if (
['javascript', 'typescript'].includes(lang) &&
['javascript', 'typescript'].includes(mapLanguage(lang))
) {
return true;
}
return config.languages?.map(getLanguageByAlias).filter(Boolean).includes(lang);
};

Expand Down
51 changes: 33 additions & 18 deletions src/livecodes/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,39 @@ export const livecodes = (container: string, config: Partial<Config> = {}): Prom
async (
e: MessageEventInit<{ method: keyof API; id: string; args: any; payload?: any }>,
) => {
if (e.data?.args === 'i18n') {
if (e.source !== iframe.contentWindow) return;

if (!isEmbed) {
// flatten i18n object `splash` and save to localStorage
const i18nSplashData = e.data.payload.data as { [k: string]: string };
for (const [key, value] of Object.entries(i18nSplashData)) {
localStorage.setItem(`i18n_splash.${key}`, value);
}
}

// Set document language
const lang = e.data.payload.lang as string;
document.documentElement.lang = lang;

// Reload the page to apply the new language
const reload = e.data.payload.reload as boolean;
const appUrl = e.data.payload.url as string | undefined;
if (reload) {
const url = new URL(appUrl || location.href);
if (appUrl && lang) {
url.searchParams.set('appLanguage', lang);
} else {
url.searchParams.delete('appLanguage');
}
if (isEmbed) {
url.searchParams.set('embed', '');
}
location.href = url.href;
}
return;
}

if (isEmbed) {
if (e.source !== parent || api == null) return;
const { method, id, args } = e.data ?? {};
Expand Down Expand Up @@ -175,24 +208,6 @@ export const livecodes = (container: string, config: Partial<Config> = {}): Prom
} else if (e.data?.args === 'console-message') {
// eslint-disable-next-line no-console
console.info(...(e.data.payload ?? []));
} else if (e.data?.args === 'i18n') {
// flatten i18n object `splash` and save to localStorage
const i18nSplashData = e.data.payload.data as { [k: string]: string };
for (const [key, value] of Object.entries(i18nSplashData)) {
localStorage.setItem(`i18n_splash.${key}`, value);
}

// Set document language
const lang = e.data.payload.lang as string;
document.documentElement.lang = lang;

// Reload the page to apply the new language
const reload = e.data.payload.reload as boolean;
if (reload) {
const url = new URL(location.href);
url.searchParams.delete('appLanguage');
location.href = url.href;
}
}
}
},
Expand Down

0 comments on commit b5fd5e6

Please sign in to comment.