Skip to content

Commit

Permalink
align locale theme across sites (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
Germey authored May 11, 2024
1 parent be998e8 commit b3f722d
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "align across site for theme and locale",
"packageName": "@acedatacloud/hub",
"email": "[email protected]",
"dependentChangeType": "patch"
}
19 changes: 10 additions & 9 deletions src/components/common/DarkSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { defineComponent } from 'vue';
import { toggleDark } from 'vue-dark-switch';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { ElButton } from 'element-plus';
import { getCookie, setCookie } from 'typescript-cookie';
import { getDomain } from '@/utils/initializer';
export default defineComponent({
components: {
Expand All @@ -19,20 +21,13 @@ export default defineComponent({
emits: ['update:dark'],
computed: {
dark() {
return this.$store.getters.dark;
return getCookie('THEME') === 'dark';
}
// switchValue() {
// return isDark.value;
// }
},
watch: {
dark(val) {
this.setDark(val);
}
// switchValue(val) {
// console.log('switchValue', val);
// // this.$store.dispatch('setDark', val);
// }
},
mounted() {
console.log('mounted', this.dark);
Expand All @@ -41,12 +36,18 @@ export default defineComponent({
methods: {
setDark(flag: boolean) {
toggleDark(flag);
this.$store.dispatch('setDark', flag);
this.setCookie(flag);
if (flag === true) {
document.documentElement.classList.add('dark');
} else if (flag === false) {
document.documentElement.classList.remove('dark');
}
},
setCookie(isDark: boolean) {
setCookie('THEME', isDark ? 'dark' : 'light', {
path: '/',
domain: getDomain()
});
}
}
});
Expand Down
14 changes: 12 additions & 2 deletions src/components/common/LocaleSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@

<script lang="ts">
import { defineComponent } from 'vue';
import { ElDropdown, ElDropdownItem, ElDropdownMenu, ElButton } from 'element-plus';
import { ElDropdown, ElDropdownItem, ElDropdownMenu } from 'element-plus';
import { SUPPORTED_LOCALES, setI18nLanguage } from '@/i18n';
import { setCookie } from 'typescript-cookie';
import { getDomain } from '@/utils/initializer';
export default defineComponent({
name: 'LocaleSelector',
Expand All @@ -39,9 +41,17 @@ export default defineComponent({
},
methods: {
async onSelectLocale(locale: string) {
// change router
this.$router.push({ query: { ...this.$route.query, locale: undefined } });
await setI18nLanguage(locale);
this.$store.dispatch('setLocale', locale);
this.setCookie(locale);
window.location.reload();
},
setCookie(locale: string) {
setCookie('LOCALE', locale, {
path: '/',
domain: getDomain()
});
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export const loadLocalResource = async (name: string, locale: string) => {
}
};

export const getLocale = (): string => {
const canonicalLang = Intl.getCanonicalLocales(navigator.language)?.[0];
export const getLocale = (lang?: string): string => {
const canonicalLang = Intl.getCanonicalLocales(lang || navigator.language)?.[0];
const supportedLocales = SUPPORTED_LOCALES.map((locale) => locale.value);
// if the canonical language is supported, use it
if (canonicalLang && supportedLocales.includes(canonicalLang)) {
Expand Down
64 changes: 34 additions & 30 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,43 @@ import copyToClipboard from 'copy-to-clipboard';
import { initializeCookies, initializeFavicon, initializeTitle } from './utils/initializer';
import config from './plugins/config';

initializeCookies();
initializeTitle();
initializeFavicon();
const main = async () => {
await initializeCookies();
await initializeTitle();
await initializeFavicon();

const app = createApp(App);
const app = createApp(App);

app.use(router);
app.use(store);
app.use(i18n);
app.use(dayjs, {
formatString: 'YYYY-MM-DD HH:mm:ss'
});
app.use(config);
app.directive('loading', vLoading);
app.mount('#app');
console.debug('app mounted');
app.use(router);
app.use(store);
app.use(i18n);
app.use(dayjs, {
formatString: 'YYYY-MM-DD HH:mm:ss'
});
app.use(config);
app.directive('loading', vLoading);
app.mount('#app');
console.debug('app mounted');

app.directive('highlight', async (el) => {
const blocks = el.querySelectorAll('pre code');
blocks.forEach((block: HTMLPreElement) => {
// create the copy button
const copy = document.createElement('button');
copy.innerHTML = i18n.global.t('common.button.copy').toString();
// add the event listener to each click
copy.addEventListener('click', () => {
copyToClipboard(block.innerText);
app.directive('highlight', async (el) => {
const blocks = el.querySelectorAll('pre code');
blocks.forEach((block: HTMLPreElement) => {
// create the copy button
const copy = document.createElement('button');
copy.innerHTML = i18n.global.t('common.button.copy').toString();
// add the event listener to each click
copy.addEventListener('click', () => {
copyToClipboard(block.innerText);
});
// append the copy button to each code block
block.parentElement?.prepend(copy);
hl.highlightBlock(block);
});
// append the copy button to each code block
block.parentElement?.prepend(copy);
hl.highlightBlock(block);
});
});

// make app available globally
// @ts-ignore
window.app = app;
// make app available globally
// @ts-ignore
window.app = app;
};

main();
4 changes: 2 additions & 2 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import chatdoc from './chatdoc';
import qrart from './qrart';

import { ROUTE_CHAT_CONVERSATION_NEW, ROUTE_INDEX } from './constants';
import store from '@/store';
import { DEFAULT_LOCALE, setI18nLanguage } from '@/i18n';
import { getCookie } from 'typescript-cookie';

const routes = [
{
Expand All @@ -34,7 +34,7 @@ const router = createRouter({
});

router.beforeEach(async (to, from, next) => {
const locale = store.state.locale || DEFAULT_LOCALE;
const locale = getCookie('LOCALE') || DEFAULT_LOCALE;
await setI18nLanguage(locale);
return next();
});
Expand Down
10 changes: 0 additions & 10 deletions src/store/common/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ export const setToken = ({ commit }: ActionContext<IRootState, IRootState>, payl
commit('setToken', payload);
};

export const setDark = ({ commit }: ActionContext<IRootState, IRootState>, payload: boolean) => {
commit('setDark', payload);
};

export const setLocale = ({ commit }: ActionContext<IRootState, IRootState>, payload: string) => {
commit('setLocale', payload);
};

export const setUser = ({ commit }: ActionContext<IRootState, IRootState>, payload: IUser) => {
commit('setUser', payload);
};
Expand Down Expand Up @@ -61,13 +53,11 @@ export const getToken = async ({ commit }: ActionContext<IRootState, IRootState>
};

export default {
setLocale,
resetToken,
resetAll,
resetUser,
resetSetting,
setToken,
setDark,
setUser,
getToken,
getUser
Expand Down
10 changes: 0 additions & 10 deletions src/store/common/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ export const user = (state: IRootState): any => {
return state.user;
};

export const dark = (state: IRootState): boolean => {
return state.dark;
};

export const locale = (state: IRootState): string => {
return state.locale;
};

export const token = (state: IRootState): any => {
return state.token;
};
Expand All @@ -25,10 +17,8 @@ export const setting = (state: IRootState): any => {
};

export default {
locale,
authenticated,
user,
token,
dark,
setting
};
2 changes: 0 additions & 2 deletions src/store/common/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export interface ICommonState {
token: IToken;
user?: IUser;
setting?: ISetting;
locale: string;
dark: boolean;
}

export interface IRootState extends ICommonState {
Expand Down
10 changes: 0 additions & 10 deletions src/store/common/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ export const setUser = (state: IRootState, payload: IUser): void => {
};
};

export const setLocale = (state: IRootState, payload: string): void => {
state.locale = payload;
};

export const setDark = (state: IRootState, payload: boolean): void => {
state.dark = payload;
};

export const setToken = (state: IRootState, payload: any): void => {
state.token = {
...state.token,
Expand Down Expand Up @@ -43,11 +35,9 @@ export const setSetting = (state: IRootState, payload: any): void => {
};

export default {
setLocale,
setUser,
resetUser,
setToken,
setDark,
resetToken,
setSetting,
resetSetting
Expand Down
7 changes: 3 additions & 4 deletions src/store/common/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { IRootState } from './models';
import chatState from '../chat/state';
import midjourneyState from '../midjourney/state';
import chatdocState from '../chatdoc/state';
import { getLocale } from '@/i18n';
import qrartState from '../qrart/state';

export default (): IRootState => {
return {
user: {},
locale: getLocale(),
dark: window.matchMedia('(prefers-color-scheme: dark)').matches,
token: {
access: undefined,
refresh: undefined,
Expand All @@ -20,6 +18,7 @@ export default (): IRootState => {
},
chatdoc: chatdocState(),
chat: chatState(),
midjourney: midjourneyState()
midjourney: midjourneyState(),
qrart: qrartState()
};
};
60 changes: 52 additions & 8 deletions src/utils/initializer.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { setCookie } from 'typescript-cookie';
import { getCookie, setCookie } from 'typescript-cookie';
import config from '@/config';
import favicon from '@/assets/images/favicon.ico';
import { getLocale } from '@/i18n';

/**
* Initialize cookies.
*/
export const initializeCookies = () => {
export const getDomain = () => {
const host = window.location.hostname;
// process test env and prod env, for example:
// hub.acedata.cloud -> .acedata.cloud
// hub.test.acedata.cloud -> .acedata.cloud
const domain = host.replace(/^\S+?\.(test\.|local\.)?/, '.');
console.log('cookies domain', domain);
return domain;
};

export const initializeCookies = async () => {
// parse the query string and set to cookies
const query = new URLSearchParams(window.location.search);

// set the inviter id to cookies
const inviterId = query.get('inviter_id');
if (inviterId) {
// set the cookie to expire in 7 days
Expand All @@ -16,15 +26,49 @@ export const initializeCookies = () => {
console.log('set INVITER_ID to cookies', inviterId);
setCookie('INVITER_ID', inviterId, {
expires: expiration,
path: '/'
path: '/',
domain: getDomain()
});
}

// set the theme to cookies
const theme = query.get('theme');
if (theme) {
console.log('set THEME to cookies', theme);
setCookie('THEME', theme, {
path: '/',
domain: getDomain()
});
} else if (!getCookie('THEME')) {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
console.log('set THEME to cookies', isDark ? 'dark' : 'light');
setCookie('THEME', isDark ? 'dark' : 'light', {
path: '/',
domain: getDomain()
});
}

// set the locale to cookies
const lang = query.get('lang');
let locale = undefined;
if (lang) {
locale = getLocale(lang);
} else if (!getCookie('LOCALE')) {
locale = getLocale();
}
if (locale) {
console.log('set LOCALE to cookies', locale);
setCookie('LOCALE', locale, {
path: '/',
domain: getDomain()
});
}
};

/**
* Initialize title.
*/
export const initializeTitle = () => {
export const initializeTitle = async () => {
// set the title from config.global.title
const title = config.global.title;
// find the title element or insert a new one
Expand All @@ -39,7 +83,7 @@ export const initializeTitle = () => {
/**
* Initialize favicon.
*/
export const initializeFavicon = () => {
export const initializeFavicon = async () => {
// by default use favicon which imported
// if faviconUrl is set in config, use it instead
const favIconUrl = config.global.faviconUrl;
Expand Down

0 comments on commit b3f722d

Please sign in to comment.