feat: add dock position setting

* refactor(storage.ts): move `language` and `isShowTopbar` to `setting` variable
* refactor: rename `BewSelect.vue` to `Select.vue`
This commit is contained in:
Hakadao
2023-03-23 02:13:04 +08:00
parent d5daa2a74d
commit 8a86ffaf43
8 changed files with 104 additions and 38 deletions

View File

@@ -1,14 +1,14 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import type { Ref } from 'vue'
import { grantAccessKey, revokeAccessKey } from '~/utils/index'
import { accessKey, isShowTopbar, language } from '~/logic'
// import { grantAccessKey, revokeAccessKey } from '~/utils/index'
import { accessKey, settings } from '~/logic'
const emit = defineEmits(['close'])
const { t, locale } = useI18n()
const authorizeBtn = ref<HTMLButtonElement>() as Ref<HTMLButtonElement>
// const authorizeBtn = ref<HTMLButtonElement>() as Ref<HTMLButtonElement>
const langsSelect = ref<HTMLElement>() as Ref<HTMLElement>
const langs = computed(() => {
@@ -31,8 +31,24 @@ const langs = computed(() => {
},
]
})
const dockPositions = computed(() => {
return [
{
value: 'left',
label: 'Left',
},
{
value: 'right',
label: 'Right',
},
{
value: 'bottom',
label: 'Bottom',
},
]
})
watch(() => language.value, (newValue, oldValue) => {
watch(() => settings.value.language, (newValue, oldValue) => {
locale.value = newValue
})
@@ -40,13 +56,13 @@ function close() {
emit('close')
}
function onAuthorize() {
grantAccessKey(authorizeBtn.value)
}
// function onAuthorize() {
// grantAccessKey(authorizeBtn.value)
// }
function onRevoke() {
revokeAccessKey()
}
// function onRevoke() {
// revokeAccessKey()
// }
</script>
<template>
@@ -77,9 +93,9 @@ function onRevoke() {
{{ $t('settings.select_language') }}
</div>
<bew-select
<Select
ref="langsSelect"
v-model="language"
v-model="settings.language"
:options="langs"
w="full"
/>
@@ -112,12 +128,27 @@ function onRevoke() {
</div>
<div>
<label for="topbarVisiable" class="chk-btn" cursor="pointer" pointer="auto">
<template v-if="isShowTopbar">{{ $t('settings.chk_box.show') }}</template>
<template v-if="settings.isShowTopbar">{{ $t('settings.chk_box.show') }}</template>
<template v-else>{{ $t('settings.chk_box.hidden') }}</template>
<input id="topbarVisiable" v-model="isShowTopbar" type="checkbox">
<input id="topbarVisiable" v-model="settings.isShowTopbar" type="checkbox">
</label>
</div>
</div>
<div class="settings-item">
<div>
Dock position
<br>
<span class="desc">Position on screen</span>
</div>
<div>
<Select
v-model="settings.dockPosition"
:options="dockPositions"
w="full"
/>
</div>
</div>
</div>
</template>

View File

@@ -5,9 +5,7 @@ import { onMounted, reactive, ref, watch } from 'vue'
import { isNewArticle, isNewVideo, setLastestOffsetID } from './notify'
import { MomentType } from './types'
import type { MomentItem } from './types'
import { language } from '~/logic'
import { calcTimeSince, getUserID } from '~/utils'
import { LanguageType } from '~/enums/appEnums'
const { t } = useI18n()
const moments = reactive<Array<MomentItem>>([]) as UnwrapNestedRefs<

View File

@@ -51,14 +51,15 @@ import { SVG_ICONS, getCookie, i18n, setCookie } from '~/utils'
styleEl.setAttribute('href', browser.runtime.getURL('dist/contentScripts/style.css'))
shadowDOM.appendChild(styleEl)
shadowDOM.appendChild(root)
document.body.appendChild(container)
const app = createApp(App)
setupApp(app)
app.use(i18n).mount(root)
// inject svg icons
const svgDiv = document.createElement('div')
svgDiv.innerHTML = SVG_ICONS
document.body.appendChild(svgDiv)
shadowDOM.appendChild(svgDiv)
document.body.appendChild(container)
const app = createApp(App)
setupApp(app)
app.use(i18n).mount(root)
}
})()

View File

@@ -9,8 +9,7 @@ import Anime from './Anime/Anime.vue'
import History from './History/History.vue'
import Favorites from './Favorites/Favorites.vue'
import Video from './Video/Video.vue'
import { activatedPage, isShowTopbar } from '~/logic/storage'
import { language } from '~/logic'
import { activatedPage, settings } from '~/logic'
import '~/styles/index.ts'
import { AppPage, LanguageType } from '~/enums/appEnums'
@@ -49,7 +48,7 @@ watch(() => isDark.value, (newValue, oldValue) => {
setAppAppearance()
})
watch(() => language.value, (newValue, oldValue) => {
watch(() => settings.value.language, (newValue, oldValue) => {
setAppLanguage()
})
@@ -65,24 +64,24 @@ function changeActivatePage(pageName: AppPage) {
async function setAppLanguage() {
// if there is first-time load extension, set the default language by browser display language
if (!language.value) {
if (!settings.value.language) {
if (browser.i18n.getUILanguage() === 'zh-CN') {
language.value = LanguageType.Mandarin_CN
settings.value.language = LanguageType.Mandarin_CN
}
else if (browser.i18n.getUILanguage() === 'zh-TW') {
// Since getUILanguage() cannot get the zh-HK language code
// use getAcceptLanguages() to get the language code
const languages: string[] = await browser.i18n.getAcceptLanguages()
if (languages.includes('zh-HK'))
language.value = LanguageType.Cantonese
else language.value = LanguageType.Mandarin_TW
settings.value.language = LanguageType.Cantonese
else settings.value.language = LanguageType.Mandarin_TW
}
else {
language.value = LanguageType.English
settings.value.language = LanguageType.English
}
}
locale.value = language.value
locale.value = settings.value.language
}
/**
@@ -103,17 +102,26 @@ function setAppAppearance() {
<div m-auto max-w="$bew-page-max-width">
<Transition name="topbar">
<Topbar
v-show="isShowTopbar"
v-show="settings.isShowTopbar"
:show-search-bar="activatedPage !== AppPage.Search"
class="fixed top-0 left-0 z-50"
/>
</Transition>
<div flex="~" max-w="$bew-page-max-width">
<aside pos="fixed left-0 top-0" flex="~ col" h-100vh justify-center z-999>
<aside
class="dock-wrap"
:class="{
left: settings.dockPosition === 'left',
right: settings.dockPosition === 'right',
bottom: settings.dockPosition === 'bottom',
}"
pos="fixed top-0" flex="~ col" h-100vh justify-center z-999
>
<div
class="dock-content"
p-2
ml-2
m-2
bg="$bew-content-1"
flex="~ col gap-2 shrink-0"
rounded="$bew-radius"
@@ -221,6 +229,24 @@ function setAppAppearance() {
--at-apply: opacity-0;
}
.dock-wrap {
&.left {
--at-apply: left-0;
}
&.right {
--at-apply: right-0;
}
&.bottom{
--at-apply: top-unset bottom-0 items-center w-full h-[fit-content];
.dock-content {
--at-apply: flex-row;
}
}
}
.tab-item {
--shadow: 0 0 30px 4px var(--bew-theme-color-50);
--shadow-dark: 0 0 30px 4px rgba(255, 255, 255, 0.6);

View File

@@ -1,8 +1,13 @@
import { useStorageLocal } from '~/composables/useStorageLocal'
import { AppPage } from '~/enums/appEnums'
import type { Settings } from '~/models/models'
export const storageDemo = useStorageLocal('webext-demo', 'Storage Demo')
export const language = useStorageLocal('language', '')
export const isShowTopbar = useStorageLocal('isShowTopbar', ref<boolean>(true))
export const accessKey = useStorageLocal('accessKey', '')
export const activatedPage = useStorageLocal('activatedPage', ref<AppPage>(AppPage.Home))
export const settings = useStorageLocal('settings', ref<Settings>({
language: '',
isShowTopbar: true,
dockPosition: 'left',
}), { mergeDefaults: true })

5
src/models/models.ts Normal file
View File

@@ -0,0 +1,5 @@
export interface Settings {
language: string
isShowTopbar: boolean
dockPosition: 'left' | 'right' | 'bottom'
}

View File

@@ -1,11 +1,11 @@
import { language } from '~/logic'
import { settings } from '~/logic'
import { i18n } from '~/utils/i18n'
export const { t } = i18n.global
export const numFormatter = (num: number) => {
const digits = 1 // specify number of digits after decimal
let lookup
if (language.value === 'en') {
if (settings.value.language === 'en') {
lookup = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'K' },
@@ -13,7 +13,7 @@ export const numFormatter = (num: number) => {
{ value: 1e9, symbol: 'B' },
]
}
else if (language.value === 'cmn-CN') {
else if (settings.value.language === 'cmn-CN') {
lookup = [
{ value: 1, symbol: ' ' },
{ value: 1e4, symbol: ' 万' },