import { ModelRef, Ref } from 'vue'; import { Dark } from 'quasar'; import { setLocale as setDateTimeLocale } from './datetime'; import { i18n } from 'src/boot/i18n'; import { fileToBase64 } from './file'; export enum Theme { Light = 'light', Dark = 'dark', Auto = 'auto', } /** * This is used to detect current theme that set before entering app. * * **Warning:** This must be used after initialize vue and quasar as it use quasar api. */ export function initTheme(): Theme { const current = localStorage.getItem('currentTheme') as Theme | null; if (!current) return setTheme(Theme.Auto); return setTheme(current); } /** * This is used to set quasar theme through quasar api. * * **Warning:** Must be called after initialize vue and quasar. */ export function setTheme(theme: Theme): Theme { switch (theme) { case Theme.Light: case Theme.Dark: localStorage.setItem('currentTheme', theme); Dark.set(theme === Theme.Dark); return theme; default: localStorage.setItem('currentTheme', Theme.Auto); Dark.set(window.matchMedia('(prefers-color-scheme: dark)').matches); return Theme.Auto; } } export enum Lang { English = 'eng', Thai = 'tha', } /** * This is used to get remembered language and use it. * * **Warning:** Must be used after initialize vue and vue-i18n */ export function initLang(): Lang { const current = localStorage.getItem('currentLanguage') as Lang | null; switch (current) { case Lang.English: case Lang.Thai: return setLang(current); default: return setLang(Lang.Thai); } } /** * This is used to set language and also remember the language set. * * **Warning:** Must be used after initialize vue and vue-i18n */ export function setLang(lang: Lang): Lang { const { locale } = i18n.global; locale.value = lang; localStorage.setItem('currentLanguage', lang); // TODO: Make date time get locale from i18n instead of telling it to use specific lang. setDateTimeLocale(lang === Lang.English ? 'en' : 'th'); return lang; } /** * This is for use with ContentEditable element and with q-editor */ export function createEditorImageDrop(ref: Ref | ModelRef) { return async (e: DragEvent) => { e.preventDefault(); e.stopPropagation(); const target = e.target; if (!target || !(target instanceof HTMLElement)) return; const items = e.dataTransfer?.items; const promises: Promise[] = []; if (!items) return; for (let i = 0; i < items.length; i++) { const file = items[i].getAsFile(); if (!file || file.type.indexOf('image') === -1) continue; promises.push(fileToBase64(file)); } const getCaret = () => { if (target.isContentEditable || document.designMode === 'on') { target.focus(); const range = document.getSelection()?.getRangeAt(0); if (!range?.collapsed) return null; const tmp = document.createTextNode('\0'); range.insertNode(tmp); const pos = target.innerHTML.indexOf('\0'); tmp.parentNode?.removeChild(tmp); return pos; } return null; }; for (const base64 of await Promise.all(promises)) { const image = document.createElement('img') as HTMLImageElement; const caret = getCaret(); image.src = base64; if (caret) { ref.value = ref.value.substring(0, caret) + image.outerHTML + ref.value.substring(caret, ref.value.length); } else { ref.value += image.outerHTML; } } }; }