mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
feat: implement reset content feature in dock
This commit is contained in:
@@ -22,6 +22,7 @@ common:
|
||||
enable: 启用
|
||||
disable: 禁用
|
||||
refresh: 刷新
|
||||
reset: 重置
|
||||
settings:
|
||||
title: 设置
|
||||
menu_general: 通用
|
||||
|
||||
@@ -22,6 +22,7 @@ common:
|
||||
enable: 啓用
|
||||
disable: 停用
|
||||
refresh: 重新整理
|
||||
reset: 重置
|
||||
settings:
|
||||
title: 設定
|
||||
menu_general: 一般
|
||||
|
||||
@@ -22,6 +22,7 @@ common:
|
||||
enable: Enable
|
||||
disable: Disable
|
||||
refresh: Refresh
|
||||
reset: Reset
|
||||
settings:
|
||||
title: Settings
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ common:
|
||||
enable: 打開
|
||||
disable: 閂埋
|
||||
refresh: 重新整理
|
||||
reset: 重置
|
||||
settings:
|
||||
title: 設定
|
||||
menu_general: 一般
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import type { DockItem, HoveringDockItem } from './types'
|
||||
import { AppPage } from '~/enums/appEnums'
|
||||
import { dockItemVisibilityList, settings } from '~/logic'
|
||||
import type { CurrentDockItem, HoveringDockItem } from './types'
|
||||
import type { AppPage } from '~/enums/appEnums'
|
||||
import { settings } from '~/logic'
|
||||
import type { DockItem } from '~/stores/mainStore'
|
||||
import { useMainStore } from '~/stores/mainStore'
|
||||
|
||||
defineProps<{ activatedPage: AppPage }>()
|
||||
|
||||
const emit = defineEmits(['change-page', 'settings-visibility-change'])
|
||||
|
||||
const mainStore = useMainStore() as any
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const hideDock = ref<boolean>(false)
|
||||
@@ -35,15 +39,15 @@ const currentAppColorScheme = computed((): 'dark' | 'light' => {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
})
|
||||
|
||||
const dockItems = computed((): DockItem[] => {
|
||||
return [
|
||||
{ label: t('dock.search'), icon: 'mingcute:search-2-line', iconActivated: 'mingcute:search-2-fill', page: AppPage.Search },
|
||||
{ label: t('dock.home'), icon: 'mingcute:home-5-line', iconActivated: 'mingcute:home-5-fill', page: AppPage.Home },
|
||||
{ label: t('dock.anime'), icon: 'mingcute:tv-2-line', iconActivated: 'mingcute:tv-2-fill', page: AppPage.Anime },
|
||||
{ label: t('dock.favorites'), icon: 'mingcute:star-line', iconActivated: 'mingcute:star-fill', page: AppPage.Favorites },
|
||||
{ label: t('dock.history'), icon: 'mingcute:time-line', iconActivated: 'mingcute:time-fill', page: AppPage.History },
|
||||
{ label: t('dock.watch_later'), icon: 'mingcute:carplay-line', iconActivated: 'mingcute:carplay-fill', page: AppPage.WatchLater },
|
||||
]
|
||||
const currentDockItems = computed((): CurrentDockItem[] => {
|
||||
return mainStore.dockItems.map((e: DockItem) => {
|
||||
return {
|
||||
label: t(e.i18nKey),
|
||||
icon: e.icon,
|
||||
iconActivated: e.iconActivated,
|
||||
page: e.page,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
watch(() => settings.value.autoHideDock, (newValue) => {
|
||||
@@ -54,27 +58,27 @@ onMounted(() => {
|
||||
if (settings.value.autoHideDock)
|
||||
hideDock.value = true
|
||||
|
||||
if (dockItemVisibilityList.value.length < dockItems.value.length || dockItemVisibilityList.value.length > dockItems.value.length) {
|
||||
if (settings.value.dockItemVisibilityList.length < currentDockItems.value.length || settings.value.dockItemVisibilityList.length > currentDockItems.value.length) {
|
||||
const newDockItemVisibilityList = ref<{ page: AppPage; visible: boolean }[]>([])
|
||||
dockItems.value.forEach((item) => {
|
||||
currentDockItems.value.forEach((item) => {
|
||||
newDockItemVisibilityList.value.push({ page: item.page, visible: true })
|
||||
})
|
||||
|
||||
// Compare two arrays, get the differing elements, and delete or add them to the dockItemVisibilityList
|
||||
const notInNewDockItemVisibilityList = dockItemVisibilityList.value.filter(obj1 =>
|
||||
const notInNewDockItemVisibilityList = settings.value.dockItemVisibilityList.filter(obj1 =>
|
||||
!newDockItemVisibilityList.value.some(obj2 => obj1.page === obj2.page),
|
||||
)
|
||||
const notInDockItemVisibilityList = newDockItemVisibilityList.value.filter(obj1 =>
|
||||
!dockItemVisibilityList.value.some(obj2 => obj1.page === obj2.page),
|
||||
!settings.value.dockItemVisibilityList.some(obj2 => obj1.page === obj2.page),
|
||||
)
|
||||
const allDifferences = [...notInDockItemVisibilityList, ...notInNewDockItemVisibilityList]
|
||||
|
||||
if (dockItemVisibilityList.value.length < dockItems.value.length) {
|
||||
dockItemVisibilityList.value.push(...allDifferences)
|
||||
if (settings.value.dockItemVisibilityList.length < currentDockItems.value.length) {
|
||||
settings.value.dockItemVisibilityList.push(...allDifferences)
|
||||
}
|
||||
else {
|
||||
allDifferences.forEach((obj1) => {
|
||||
dockItemVisibilityList.value = dockItemVisibilityList.value.filter(obj2 => obj2.page !== obj1.page)
|
||||
settings.value.dockItemVisibilityList = settings.value.dockItemVisibilityList.filter(obj2 => obj2.page !== obj1.page)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -116,15 +120,15 @@ function toggleDockHide(hide: boolean) {
|
||||
shadow="$bew-shadow-2"
|
||||
backdrop-glass pointer-events-auto
|
||||
>
|
||||
<template v-for="dockItemVisibility in dockItemVisibilityList" :key="dockItemVisibility.page">
|
||||
<template v-for="dockItemVisibility in settings.dockItemVisibilityList" :key="dockItemVisibility.page">
|
||||
<template v-if="dockItemVisibility.visible">
|
||||
<Tooltip :content="dockItems.find((item) => item.page === dockItemVisibility.page)?.label ?? ''" :placement="tooltipPlacement">
|
||||
<Tooltip :content="currentDockItems.find((item) => item.page === dockItemVisibility.page)?.label as string" :placement="tooltipPlacement">
|
||||
<button
|
||||
class="dock-item"
|
||||
:class="{ active: activatedPage === dockItemVisibility.page }"
|
||||
@click="emit('change-page', dockItemVisibility.page)"
|
||||
>
|
||||
<Icon :icon="dockItems.find((item) => item.page === dockItemVisibility.page)?.icon ?? ''" />
|
||||
<Icon :icon="currentDockItems.find((item) => item.page === dockItemVisibility.page)?.icon as string" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AppPage } from '~/enums/appEnums'
|
||||
|
||||
export interface DockItem {
|
||||
export interface CurrentDockItem {
|
||||
label: string
|
||||
icon: string
|
||||
iconActivated: string
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import draggable from 'vuedraggable'
|
||||
import { dockItemVisibilityList, settings } from '~/logic'
|
||||
import { AppPage } from '~/enums/appEnums'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { settings } from '~/logic'
|
||||
import { useMainStore } from '~/stores/mainStore'
|
||||
|
||||
const mainStore = useMainStore() as any
|
||||
const { t, locale } = useI18n()
|
||||
|
||||
const langOptions = computed(() => {
|
||||
@@ -43,20 +45,28 @@ const dockPositions = computed(() => {
|
||||
]
|
||||
})
|
||||
|
||||
const pageOptions = computed((): { label: string; value: string }[] => {
|
||||
return [
|
||||
{ label: t('dock.search'), value: AppPage.Search },
|
||||
{ label: t('dock.home'), value: AppPage.Home },
|
||||
{ label: t('dock.anime'), value: AppPage.Anime },
|
||||
{ label: t('dock.history'), value: AppPage.History },
|
||||
{ label: t('dock.favorites'), value: AppPage.Favorites },
|
||||
{ label: t('dock.watch_later'), value: AppPage.WatchLater },
|
||||
]
|
||||
const pageOptions = computed((): { label: string;icon: string; value: string }[] => {
|
||||
return mainStore.dockItems.map((e: any) => {
|
||||
return {
|
||||
label: t(e.i18nKey),
|
||||
icon: e.icon,
|
||||
value: e.page,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
watch(() => settings.value.language, (newValue) => {
|
||||
locale.value = newValue
|
||||
})
|
||||
|
||||
function resetDockContent() {
|
||||
settings.value.dockItemVisibilityList = mainStore.dockItems.map((e: any) => {
|
||||
return {
|
||||
page: e.page,
|
||||
visible: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -110,9 +120,20 @@ watch(() => settings.value.language, (newValue) => {
|
||||
<SettingsItem :title="$t('settings.auto_hide_dock')">
|
||||
<Radio v-model="settings.autoHideDock" />
|
||||
</SettingsItem>
|
||||
<SettingsItem :title="$t('settings.dock_content_adjustment')" next-line>
|
||||
<SettingsItem next-line>
|
||||
<template #title>
|
||||
<div flex="~ gap-4 items-center">
|
||||
{{ $t('settings.dock_content_adjustment') }}
|
||||
<Button size="small" type="secondary" @click="resetDockContent">
|
||||
<template #left>
|
||||
<mingcute:back-line />
|
||||
</template>
|
||||
{{ $t('common.reset') }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
<draggable
|
||||
v-model="dockItemVisibilityList"
|
||||
v-model="settings.dockItemVisibilityList"
|
||||
item-key="page"
|
||||
:component-data="{ style: 'display: flex; gap: 0.5rem;' }"
|
||||
>
|
||||
@@ -120,12 +141,13 @@ watch(() => settings.value.language, (newValue) => {
|
||||
<div
|
||||
flex="~ gap-2 items-center" p="x-4 y-2" bg="$bew-fill-1" rounded="$bew-radius" cursor-all-scroll
|
||||
duration-300
|
||||
:style="{ opacity: element.visible ? 1 : 0.6 }"
|
||||
:style="{
|
||||
background: element.visible ? 'var(--bew-theme-color)' : 'var(--bew-fill-1)',
|
||||
color: element.visible ? 'white' : 'var(--bew-text-1)',
|
||||
}"
|
||||
@click="element.visible = !element.visible"
|
||||
>
|
||||
<div @click="element.visible = !element.visible">
|
||||
<line-md:watch v-if="element.visible" cursor-pointer />
|
||||
<line-md:watch-off v-else cursor-pointer />
|
||||
</div>
|
||||
<Icon :icon="pageOptions.find((page:any) => (page.value === element.page))?.icon as string" />
|
||||
{{ pageOptions.find(option => option.value === element.page)?.label }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title: string
|
||||
title?: string
|
||||
desc?: string
|
||||
nextLine?: boolean
|
||||
}>()
|
||||
@@ -10,13 +10,17 @@ defineProps<{
|
||||
<div class="b-settings-item" py-4>
|
||||
<div flex="~ gap-4" justify-betwee items-center text-base>
|
||||
<div :w="nextLine ? 'full' : '5/7'">
|
||||
{{ title }}
|
||||
<br>
|
||||
<span text="sm $bew-text-2">
|
||||
<div mb-2>
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<div text="sm $bew-text-2">
|
||||
<slot name="desc">
|
||||
{{ desc }}
|
||||
</slot>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!nextLine" w="2/7" class="right-content">
|
||||
|
||||
@@ -15,7 +15,7 @@ import { AppPage, LanguageType } from '~/enums/appEnums'
|
||||
import { getUserID, hexToRGBA, isHomePage, smoothScrollToTop } from '~/utils/main'
|
||||
import emitter from '~/utils/mitt'
|
||||
|
||||
const activatedPage = ref<AppPage>(settings.value.startupPage ?? AppPage.Home)
|
||||
const activatedPage = ref<AppPage>(settings.value.dockItemVisibilityList[0].page ?? AppPage.Home)
|
||||
const { locale } = useI18n()
|
||||
const [showSettings, toggleSettings] = useToggle(false)
|
||||
const pages = { Home, Search, Anime, History, WatchLater, Favorites }
|
||||
|
||||
@@ -1,10 +1,48 @@
|
||||
import { useStorageLocal } from '~/composables/useStorageLocal'
|
||||
import { AppPage } from '~/enums/appEnums'
|
||||
import type { Settings } from '~/models/settings'
|
||||
|
||||
// TODO: refactor: implement storage functionality using pinia + useStorageLocal()
|
||||
|
||||
export const storageDemo = useStorageLocal('webext-demo', 'Storage Demo')
|
||||
export const accessKey = useStorageLocal('accessKey', '')
|
||||
|
||||
export interface Settings {
|
||||
language: string
|
||||
enableHorizontalScrolling: boolean
|
||||
openLinkInCurrentTab: boolean
|
||||
enableVideoCtrlBarOnVideoCard: boolean
|
||||
isShowTopbar: boolean
|
||||
autoHideTopbar: boolean
|
||||
dockPosition: 'left' | 'right' | 'bottom'
|
||||
autoHideDock: boolean
|
||||
dockItemVisibilityList: { page: AppPage; visible: boolean }[]
|
||||
|
||||
theme: 'light' | 'dark' | 'auto'
|
||||
themeColor: string
|
||||
adaptToOtherPageStyles: boolean
|
||||
wallpaperMode: 'buildIn' | 'byUrl'
|
||||
wallpaper: string
|
||||
enableWallpaperMasking: boolean
|
||||
wallpaperMaskOpacity: number
|
||||
wallpaperBlurIntensity: number
|
||||
|
||||
searchPageDarkenOnSearchFocus: boolean
|
||||
searchPageBlurredOnSearchFocus: boolean
|
||||
searchPageLogoColor: 'white' | 'themeColor'
|
||||
searchPageLogoGlow: boolean
|
||||
searchPageShowLogo: boolean
|
||||
searchPageSearchBarFocusCharacter: string
|
||||
individuallySetSearchPageWallpaper: boolean
|
||||
searchPageWallpaperMode: 'buildIn' | 'byUrl'
|
||||
searchPageWallpaper: string
|
||||
searchPageEnableWallpaperMasking: boolean
|
||||
searchPageWallpaperMaskOpacity: number
|
||||
searchPageWallpaperBlurIntensity: number
|
||||
|
||||
recommendationMode: 'web' | 'app'
|
||||
useSearchPageModeOnHomePage: boolean
|
||||
searchPageModeWallpaperFixed: boolean
|
||||
}
|
||||
export const settings = useStorageLocal('settings', ref<Settings>({
|
||||
language: '',
|
||||
startupPage: AppPage.Home,
|
||||
@@ -15,6 +53,7 @@ export const settings = useStorageLocal('settings', ref<Settings>({
|
||||
autoHideTopbar: false,
|
||||
dockPosition: 'right',
|
||||
autoHideDock: false,
|
||||
dockItemVisibilityList: [],
|
||||
|
||||
theme: 'auto',
|
||||
themeColor: '#00a1d6',
|
||||
@@ -42,12 +81,3 @@ export const settings = useStorageLocal('settings', ref<Settings>({
|
||||
useSearchPageModeOnHomePage: false,
|
||||
searchPageModeWallpaperFixed: false,
|
||||
}), { mergeDefaults: true })
|
||||
|
||||
export const dockItemVisibilityList = useStorageLocal('dockItems', reactive<{ page: AppPage; visible: boolean }[]>([
|
||||
// { page: AppPage.Search, visible: true },
|
||||
// { page: AppPage.Home, visible: true },
|
||||
// { page: AppPage.Anime, visible: true },
|
||||
// { page: AppPage.Favorites, visible: true },
|
||||
// { page: AppPage.History, visible: true },
|
||||
// { page: AppPage.WatchLater, visible: true },
|
||||
]))
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import type { AppPage } from '~/enums/appEnums'
|
||||
|
||||
export interface Settings {
|
||||
language: string
|
||||
startupPage: AppPage
|
||||
enableHorizontalScrolling: boolean
|
||||
openLinkInCurrentTab: boolean
|
||||
enableVideoCtrlBarOnVideoCard: boolean
|
||||
isShowTopbar: boolean
|
||||
autoHideTopbar: boolean
|
||||
dockPosition: 'left' | 'right' | 'bottom'
|
||||
autoHideDock: boolean
|
||||
|
||||
theme: 'light' | 'dark' | 'auto'
|
||||
themeColor: string
|
||||
adaptToOtherPageStyles: boolean
|
||||
wallpaperMode: 'buildIn' | 'byUrl'
|
||||
wallpaper: string
|
||||
enableWallpaperMasking: boolean
|
||||
wallpaperMaskOpacity: number
|
||||
wallpaperBlurIntensity: number
|
||||
|
||||
searchPageDarkenOnSearchFocus: boolean
|
||||
searchPageBlurredOnSearchFocus: boolean
|
||||
searchPageLogoColor: 'white' | 'themeColor'
|
||||
searchPageLogoGlow: boolean
|
||||
searchPageShowLogo: boolean
|
||||
searchPageSearchBarFocusCharacter: string
|
||||
individuallySetSearchPageWallpaper: boolean
|
||||
searchPageWallpaperMode: 'buildIn' | 'byUrl'
|
||||
searchPageWallpaper: string
|
||||
searchPageEnableWallpaperMasking: boolean
|
||||
searchPageWallpaperMaskOpacity: number
|
||||
searchPageWallpaperBlurIntensity: number
|
||||
|
||||
recommendationMode: 'web' | 'app'
|
||||
useSearchPageModeOnHomePage: boolean
|
||||
searchPageModeWallpaperFixed: boolean
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// import { defineStore } from 'pinia'
|
||||
// import { useStorageLocal } from '~/composables/useStorageLocal'
|
||||
// import { AppPage } from '~/enums/appEnums'
|
||||
// import type { Settings } from '~/models/settings'
|
||||
|
||||
// export const useSettingsStore = defineStore('settings', () => {
|
||||
// const settings = useStorageLocal('settings', ref<Settings>({
|
||||
// language: '',
|
||||
// startupPage: AppPage.Home,
|
||||
// enableHorizontalScrolling: false,
|
||||
// openLinkInCurrentTab: false,
|
||||
// enableVideoCtrlBarOnVideoCard: false,
|
||||
// isShowTopbar: true,
|
||||
// autoHideTopbar: false,
|
||||
// dockPosition: 'right',
|
||||
// autoHideDock: false,
|
||||
|
||||
// theme: 'auto',
|
||||
// themeColor: '#00a1d6',
|
||||
// adaptToOtherPageStyles: true,
|
||||
// wallpaperMode: 'buildIn',
|
||||
// wallpaper: '',
|
||||
// enableWallpaperMasking: false,
|
||||
// wallpaperMaskOpacity: 0,
|
||||
// wallpaperBlurIntensity: 0,
|
||||
|
||||
// searchPageDarkenOnSearchFocus: true,
|
||||
// searchPageBlurredOnSearchFocus: false,
|
||||
// searchPageLogoColor: 'themeColor',
|
||||
// searchPageLogoGlow: true,
|
||||
// searchPageShowLogo: true,
|
||||
// searchPageSearchBarFocusCharacter: '',
|
||||
// individuallySetSearchPageWallpaper: false,
|
||||
// searchPageWallpaperMode: 'buildIn',
|
||||
// searchPageWallpaper: '',
|
||||
// searchPageEnableWallpaperMasking: false,
|
||||
// searchPageWallpaperMaskOpacity: 0,
|
||||
// searchPageWallpaperBlurIntensity: 0,
|
||||
|
||||
// recommendationMode: 'web',
|
||||
// useSearchPageModeOnHomePage: false,
|
||||
// searchPageModeWallpaperFixed: false,
|
||||
// }), { mergeDefaults: true })
|
||||
|
||||
// function updateSettingsItem<T extends keyof Settings>(key: T, value: Settings[T]) {
|
||||
// settings.value[key] = value
|
||||
// }
|
||||
// return { settings, updateSettingsItem }
|
||||
// })
|
||||
24
src/stores/mainStore.ts
Normal file
24
src/stores/mainStore.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { AppPage } from '~/enums/appEnums'
|
||||
|
||||
export interface DockItem {
|
||||
i18nKey: string
|
||||
icon: string
|
||||
iconActivated: string
|
||||
page: AppPage
|
||||
}
|
||||
|
||||
export const useMainStore = defineStore('main', () => {
|
||||
const dockItems = computed((): DockItem[] => {
|
||||
return [
|
||||
{ i18nKey: 'dock.home', icon: 'mingcute:home-5-line', iconActivated: 'mingcute:home-5-fill', page: AppPage.Home },
|
||||
{ i18nKey: 'dock.search', icon: 'mingcute:search-2-line', iconActivated: 'mingcute:search-2-fill', page: AppPage.Search },
|
||||
{ i18nKey: 'dock.anime', icon: 'mingcute:tv-2-line', iconActivated: 'mingcute:tv-2-fill', page: AppPage.Anime },
|
||||
{ i18nKey: 'dock.favorites', icon: 'mingcute:star-line', iconActivated: 'mingcute:star-fill', page: AppPage.Favorites },
|
||||
{ i18nKey: 'dock.history', icon: 'mingcute:time-line', iconActivated: 'mingcute:time-fill', page: AppPage.History },
|
||||
{ i18nKey: 'dock.watch_later', icon: 'mingcute:carplay-line', iconActivated: 'mingcute:carplay-fill', page: AppPage.WatchLater },
|
||||
]
|
||||
})
|
||||
|
||||
return { dockItems }
|
||||
})
|
||||
Reference in New Issue
Block a user