mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
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:
@@ -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>
|
||||
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
5
src/models/models.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface Settings {
|
||||
language: string
|
||||
isShowTopbar: boolean
|
||||
dockPosition: 'left' | 'right' | 'bottom'
|
||||
}
|
||||
@@ -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: ' 万' },
|
||||
|
||||
Reference in New Issue
Block a user