feat: add some settings to the search page

* style: adjust settings panel
This commit is contained in:
Hakadao
2023-07-31 02:09:20 +08:00
parent 0998564918
commit 2ce17cd997
8 changed files with 270 additions and 18 deletions

View File

@@ -1,16 +1,16 @@
<script setup lang="ts">
interface Props {
// color: string
color?: string
size: number
}
const props = withDefaults(defineProps<Props>(), {
// color: 'var(--bew-theme-color)',
color: 'var(--bew-theme-color)',
size: 60,
})
</script>
<template>
<div :style="{ filter: `drop-shadow(0 0 6px var(--bew-theme-color-40))` }">
<div :style="{ filter: `drop-shadow(0 0 10px var(--bew-theme-color-60))` }">
<svg
t="1645466458357"
class="icon"
@@ -19,7 +19,7 @@ const props = withDefaults(defineProps<Props>(), {
xmlns="http://www.w3.org/2000/svg"
p-id="2663"
:width="props.size"
:style="{ fill: 'var(--bew-theme-color)' }"
:style="{ fill: color }"
>
<path
d="M1775.840814 322.588002c6.0164 1.002733 53.144869-9.525967 55.150336-6.016401 3.0082 4.5123 24.065601 155.92504 18.550567 156.927774s-44.621635 10.027334-44.621635 10.027334c-3.0082-20.556034-28.577901-147.903173-29.079268-160.938707m75.205003-14.539634l20.556034 162.944174c10.5287-0.501367 53.144869-3.509567 57.155803-4.010934-6.0164-61.668103-16.545101-158.933241-16.545101-158.93324-20.054668-4.010934-41.112069-4.010934-61.166736 0m-40.610702 226.116376s92.752838-23.564234 126.344406-12.0328c17.046467 61.668103 48.131202 407.611118 51.139402 421.649386-21.057401 2.506833-90.246004 8.523234-95.761037 10.027333-4.5123-26.071068-81.72277-403.098818-81.722771-419.643919m343.436183-207.565809c5.515034 1.5041 54.648969-5.013667 55.150335-1.5041 1.002733 12.032801 6.0164 157.42914 0.501367 157.930507s-44.621635 4.010934-44.621635 4.010934c-1.002733-20.054668-12.032801-146.90044-11.030067-160.437341m75.70637-4.010933l4.010933 160.938707c10.5287 0 52.643502 2.506833 57.155803 2.005467-1.002733-61.668103 0-158.933241 0-158.933241-20.054668-3.509567-40.610702-5.013667-61.166736-4.010933m-64.676303 216.089043s94.758304-12.534167 126.845772 2.506833c7.019134 72.196803 6.0164 408.613852 7.019134 422.652119-21.558768 0-90.246004 1.002733-95.761038 2.005467-1.002733-26.071068-39.607968-410.619319-38.103868-427.164419m-220.099977-413.627519c54.648969 278.759879 96.262404 755.058234 97.766504 785.641602 0 0 43.117535 1.002733 91.750105 4.010934C2105.740095 614.383415 2070.644427 134.575493 2071.145794 119.033126c-12.032801-13.536901-126.344406 6.0164-126.344406 6.0164m-120.328005 659.297196c-10.5287-78.213204-290.291313-166.955108-447.720454-138.377206 0 0-19.553301-172.470141-27.073801-339.425248-6.517767-143.390873-1.002733-282.770813 0.501366-305.833681-10.5287-7.5205-123.837572 46.627102-185.004308 69.188603 0 0 73.199537 309.844614 126.344406 952.59671 0 0 84.730971 9.0246 230.12731-19.051934s317.365114-115.815705 302.825481-219.097244m-341.932083 140.88404l-24.566967-176.982441c6.0164-3.0082 156.927774 53.144869 172.971507 63.172203-2.506833 11.030067-148.40454 113.810238-148.40454 113.810238M610.664628 322.588002c6.0164 1.002733 53.144869-9.525967 55.150335-6.016401 3.0082 4.5123 24.065601 155.92504 18.550568 156.927774s-44.621635 10.027334-44.621635 10.027334c-3.0082-20.556034-28.577901-147.903173-29.079268-160.938707m75.205003-14.539634l20.556034 162.944174c10.5287-0.501367 53.144869-3.509567 57.155803-4.010934-6.517767-61.668103-16.545101-158.933241-16.545101-158.93324-20.054668-4.010934-41.112069-4.010934-61.166736 0m-40.610702 226.116376s92.752838-23.564234 126.344406-12.0328c17.046467 61.668103 48.131202 407.611118 51.139402 421.649386-21.057401 2.506833-90.246004 8.523234-95.761037 10.027333-4.5123-26.071068-81.72277-403.098818-81.722771-419.643919m343.436182-207.565809c5.515034 1.5041 54.648969-5.013667 55.150336-1.5041 1.002733 12.032801 6.0164 157.42914 0.501367 157.930507s-44.621635 4.010934-44.621635 4.010934c-1.002733-20.054668-11.531434-146.90044-11.030068-160.437341m75.706371-4.010933l4.010933 160.938707c10.5287 0 52.643502 2.506833 57.155803 2.005467-1.002733-61.668103 0-158.933241 0-158.933241-20.054668-3.509567-40.610702-4.5123-61.166736-4.010933m-64.676303 216.089043s94.758304-12.534167 126.845772 2.506833c7.019134 72.196803 6.0164 408.613852 7.019134 422.652119-21.558768 0-90.246004 1.002733-95.761038 2.005467-0.501367-26.071068-39.607968-410.619319-38.103868-427.164419m-220.099977-413.627519c54.648969 278.759879 96.262404 755.058234 97.766504 785.641602 0 0 43.117535 1.002733 91.750105 4.010934-28.577901-300.318647-63.67357-780.126569-63.172203-796.170303-12.032801-13.035534-126.344406 6.517767-126.344406 6.517767m-120.328005 659.297196c-10.5287-78.213204-290.291313-166.955108-447.720454-138.377206 0 0-19.553301-172.470141-27.073801-339.425248-6.517767-143.390873-1.002733-282.770813 0.501366-305.833681C174.475608-6.308547 61.166736 47.337689 0 69.89919c0 0 73.199537 309.844614 126.344406 952.59671 0 0 84.730971 9.0246 230.12731-19.051934s317.365114-115.815705 302.825481-219.097244m-341.932083 140.88404l-24.566967-176.982441c6.0164-3.0082 156.927774 53.144869 172.971507 63.172203-2.506833 11.030067-148.40454 113.810238-148.40454 113.810238"

View File

@@ -2,16 +2,19 @@
import { useI18n } from 'vue-i18n'
import General from './components/General.vue'
import Appearance from './components/Appearance.vue'
import SearchPage from './components/SearchPage.vue'
import Home from './components/Home.vue'
import About from './components/About.vue'
import { MenuType } from './types'
import { settings } from '~/logic'
const emit = defineEmits(['close'])
const { t } = useI18n()
const settingsMenu = { General, Appearance, Home, About }
const settingsMenu = { General, Appearance, SearchPage, Home, About }
const activatedMenuItem = ref<MenuType>(MenuType.General)
const title = ref<string>(t('settings.title'))
const settingsMenuItems = computed(() => {
return [
@@ -23,6 +26,10 @@ const settingsMenuItems = computed(() => {
value: MenuType.Appearance,
label: t('settings.menu_appearance'),
},
{
value: MenuType.SearchPage,
label: 'Search Page',
},
{
value: MenuType.Home,
label: t('settings.menu_home'),
@@ -34,12 +41,31 @@ const settingsMenuItems = computed(() => {
]
})
/**
* When changing language, set current title again to ensure it switches to the corresponding language
*/
watch(() => settings.value.language, () => {
setCurrentTitle()
})
onMounted(() => {
setCurrentTitle()
})
function handleClose() {
emit('close')
}
function changeMenuItem(menuItem: MenuType) {
activatedMenuItem.value = menuItem
setCurrentTitle()
}
function setCurrentTitle() {
settingsMenuItems.value.forEach((item) => {
if (item.value === activatedMenuItem.value)
title.value = item.label
})
}
</script>
@@ -53,7 +79,7 @@ function changeMenuItem(menuItem: MenuType) {
>
<aside class="group" shrink-0 p="x-2 md:x-4" pos="absolute left-0 md:left--42px" z-2>
<ul
flex="~ gap-4 col" rounded="30px hover:25px" bg="$bew-elevated-2" p-2 shadow="$bew-shadow-3"
flex="~ gap-2 col" rounded="30px hover:25px" bg="$bew-elevated-2" p-2 shadow="$bew-shadow-3"
scale="md:group-hover:105" duration-300
backdrop-glass
>
@@ -68,6 +94,7 @@ function changeMenuItem(menuItem: MenuType) {
<i w-40px text="xl center" flex="~ shrink-0" justify-center>
<tabler:settings v-if="item.value === MenuType.General" />
<tabler:brush v-else-if="item.value === MenuType.Appearance" />
<tabler:search v-else-if="item.value === MenuType.SearchPage" />
<tabler:home v-else-if="item.value === MenuType.Home" />
<tabler:info-circle v-else-if="item.value === MenuType.About" />
</i>
@@ -91,7 +118,7 @@ function changeMenuItem(menuItem: MenuType) {
"
>
<div text="3xl">
{{ $t('settings.title') }}
{{ title }}
</div>
<div
text-2xl leading-0 bg="$bew-fill-1" w="32px" h="32px" p="1" rounded-8 cursor="pointer" backdrop-glass

View File

@@ -0,0 +1,166 @@
<script lang="ts" setup>
import { settings } from '~/logic'
const wallpapers = reactive<Array<{ name: string; url: string; thumbnail: string }>>([
{
name: 'Unsplash Random Nature Image',
url: 'https://source.unsplash.com/1920x1080/?nature',
thumbnail: 'https://source.unsplash.com/1920x1080/?nature',
},
{
name: 'BML2019 VR (pid: 74271400)',
url: 'https://pic.imgdb.cn/item/638e1d63b1fccdcd36103811.jpg',
thumbnail: 'https://pic.imgdb.cn/item/64ac5e341ddac507cc750ae8.jpg',
},
{
name: '2020 拜年祭活动',
url: 'https://pic.imgdb.cn/item/638e1d7ab1fccdcd36106346.jpg',
thumbnail: 'https://pic.imgdb.cn/item/64ac5f251ddac507cc7658af.jpg',
},
{
name: '2020 BDF',
url: 'https://pic.imgdb.cn/item/63830f1816f2c2beb1868554.jpg',
thumbnail: 'https://pic.imgdb.cn/item/64ac5fc01ddac507cc77224e.jpg',
},
])
watch(() => settings.value.individuallySetSearchPageWallpaper, (newValue) => {
if (newValue)
document.documentElement.style.backgroundImage = `url(${settings.value.searchPageWallpaper})`
else
document.documentElement.style.backgroundImage = `url(${settings.value.wallpaper})`
})
function changeWallpaper(url: string) {
settings.value.searchPageWallpaper = url
}
</script>
<template>
<SettingItem title="Logo color">
<div flex rounded="$bew-radius" bg="$bew-fill-1" p-1>
<div
flex="1 ~" items-center justify-center py-1 cursor-pointer text-center rounded="$bew-radius"
:style="{
background: settings.searchPageLogoColor === 'themeColor' || !settings.searchPageLogoColor ? 'var(--bew-theme-color)' : '',
color: settings.searchPageLogoColor === 'themeColor' || !settings.searchPageLogoColor ? 'white' : '',
}"
@click="settings.searchPageLogoColor = 'themeColor'"
>
{{ 'theme color' }}
</div>
<div
flex="1 ~" items-center justify-center py-1 cursor-pointer text-center rounded="$bew-radius"
:style="{
background: settings.searchPageLogoColor === 'white' ? 'var(--bew-theme-color)' : '',
color: settings.searchPageLogoColor === 'white' ? 'white' : '',
}"
@click="settings.searchPageLogoColor = 'white'"
>
{{ 'white' }}
</div>
</div>
</SettingItem>
<SettingItem title="Logo visible">
<Radio v-model:value="settings.searchPageShowLogo" />
</SettingItem>
<SettingItem title="Individually set search page wallpaper (EXPERIMENTAL)">
<template #desc>
<span color="$bew-warning-color">{{ $t('common.performance_impact_warn') }}</span>
</template>
<Radio v-model:value="settings.individuallySetSearchPageWallpaper" />
</SettingItem>
<template v-if="settings.individuallySetSearchPageWallpaper">
<SettingItem :title="$t('settings.wallpaper_mode')" :desc="$t('settings.wallpaper_mode_desc')">
<div flex rounded="$bew-radius" bg="$bew-fill-1" p-1>
<div
flex-1 py-1 cursor-pointer text-center rounded="$bew-radius"
:style="{
background: settings.searchPageWallpaperMode === 'buildIn' ? 'var(--bew-theme-color)' : '',
color: settings.searchPageWallpaperMode === 'buildIn' ? 'white' : '',
}"
@click="settings.searchPageWallpaperMode = 'buildIn'"
>
{{ $t('settings.wallpaper_mode_opt.build_in') }}
</div>
<div
flex-1 py-1 cursor-pointer text-center rounded="$bew-radius"
:style="{
background: settings.searchPageWallpaperMode === 'byUrl' ? 'var(--bew-theme-color)' : '',
color: settings.searchPageWallpaperMode === 'byUrl' ? 'white' : '',
}"
@click="settings.searchPageWallpaperMode = 'byUrl'"
>
{{ $t('settings.wallpaper_mode_opt.by_url') }}
</div>
</div>
</SettingItem>
<SettingItem v-if="settings.searchPageWallpaperMode === 'buildIn'" :title="$t('settings.choose_ur_wallpaper')" next-line>
<div grid="~ xl:cols-4 lg:cols-3 cols-2 gap-4">
<picture
aspect-video bg="$bew-fill-1" rounded="$bew-radius" overflow-hidden
un-border="4 transparent" pointer-cursor
grid place-items-center
:class="{ 'selected-wallpaper': settings.searchPageWallpaper === '' }"
@click="changeWallpaper('')"
>
<tabler:photo-off text="3xl $bew-text-3" />
</picture>
<Tooltip v-for="item in wallpapers" :key="item.url" placement="top" :content="item.name" aspect-video>
<picture
aspect-video bg="$bew-fill-1" rounded="$bew-radius" overflow-hidden
un-border="4 transparent" w-full
:class="{ 'selected-wallpaper': settings.searchPageWallpaper === item.url }"
@click="changeWallpaper(item.url)"
>
<img :src="item.thumbnail" alt="" w-full h-full object-cover>
</picture>
</Tooltip>
</div>
</SettingItem>
<SettingItem v-else :title="$t('settings.image_url')" next-line>
<div flex items-center gap-4>
<picture
aspect-video bg="$bew-fill-1" rounded="$bew-radius" overflow-hidden
un-border="4 transparent" pointer-cursor shrink-0
w="xl:1/4 lg:1/3 md:1/2"
>
<img v-if="settings.searchPageWallpaper" :src="settings.searchPageWallpaper" alt="" w-full h-full object-cover onerror="this.style.display='none'; this.onerror=null;">
</picture>
<div>
<Input v-model:value="settings.searchPageWallpaper" w-full />
<p color="sm $bew-text-3" mt-2>
{{ $t('settings.image_url_hint') }}
</p>
</div>
</div>
</SettingItem>
<SettingItem :title="$t('settings.enable_wallpaper_masking')">
<template #desc>
<span color="$bew-warning-color">{{ $t('common.performance_impact_warn') }}</span>
</template>
<Radio v-model:value="settings.searchPageEnableWallpaperMasking" />
</SettingItem>
<SettingItem v-if="settings.searchPageEnableWallpaperMasking" :title="$t('settings.wallpaper_mask_opacity')">
<Slider v-model:value="settings.searchPageWallpaperMaskOpacity" :label="`${settings.searchPageWallpaperMaskOpacity ?? 0}%`" />
</SettingItem>
<SettingItem v-if="settings.searchPageEnableWallpaperMasking" :title="$t('settings.wallpaper_blur_intensity')">
<template #desc>
<span color="$bew-warning-color">{{ $t('common.performance_impact_warn') }}</span>
</template>
<Slider v-model:value="settings.searchPageWallpaperBlurIntensity" :min="0" :max="60" :label="`${settings.searchPageWallpaperBlurIntensity ?? 0}px`" />
</SettingItem>
</template>
</template>
<style scoped lang="scss">
.selected-wallpaper {
--at-apply: border-$bew-theme-color-60
}
</style>

View File

@@ -1,6 +1,7 @@
export enum MenuType {
General = 'General',
Appearance = 'Appearance',
SearchPage = 'SearchPage',
Home = 'Home',
About = 'About',
}

View File

@@ -80,14 +80,32 @@ watch(() => accessKey.value, () => {
accessKey.value = ''
})
watch(() => settings.value.wallpaper, (newValue) => {
watch(() => settings.value.wallpaper, () => {
setAppWallpaper()
})
watch(() => settings.value.wallpaperMaskOpacity, (newValue) => {
watch(() => settings.value.searchPageWallpaper, () => {
if (activatedPage.value === AppPage.Search)
setAppWallpaper()
})
watch(() => settings.value.wallpaperMaskOpacity, () => {
setAppWallpaperMaskingOpacity()
})
watch(() => settings.value.searchPageWallpaperMaskOpacity, () => {
setAppWallpaperMaskingOpacity()
})
watch(() => activatedPage.value, (newValue, oldValue) => {
// If u have set the `individuallySetSearchPageWallpaper`, reapply the wallpaper when the new page is search page
// or when switching from a search page to another page, since search page has its own wallpaper.
if (settings.value.individuallySetSearchPageWallpaper && (newValue === AppPage.Search || oldValue === AppPage.Search)) {
setAppWallpaper()
setAppWallpaperMaskingOpacity()
}
})
onMounted(() => {
nextTick(() => {
setTimeout(() => {
@@ -174,26 +192,46 @@ function setAppThemeColor() {
}
function setAppWallpaper() {
document.documentElement.style.backgroundImage = `url(${settings.value.wallpaper})`
document.documentElement.style.backgroundSize = 'cover'
document.documentElement.style.backgroundPosition = 'center'
nextTick(() => {
if (settings.value.individuallySetSearchPageWallpaper && activatedPage.value === AppPage.Search)
document.documentElement.style.backgroundImage = `url(${settings.value.searchPageWallpaper})`
else
document.documentElement.style.backgroundImage = `url(${settings.value.wallpaper})`
document.documentElement.style.backgroundSize = 'cover'
document.documentElement.style.backgroundPosition = 'center'
document.documentElement.style.transition = 'backgroundImage .5s ease-in-out'
})
}
function setAppWallpaperMaskingOpacity() {
const bewlyElement = document.querySelector('#bewly') as HTMLElement
bewlyElement.style.setProperty('--bew-bg-mask-opacity', `${settings.value.wallpaperMaskOpacity}%`)
if (settings.value.individuallySetSearchPageWallpaper && activatedPage.value === AppPage.Search)
bewlyElement.style.setProperty('--bew-bg-mask-opacity', `${settings.value.searchPageWallpaperMaskOpacity}%`)
else
bewlyElement.style.setProperty('--bew-bg-mask-opacity', `${settings.value.wallpaperMaskOpacity}%`)
}
</script>
<template>
<!-- background mask -->
<div
v-if="settings.enableWallpaperMasking"
v-if="(!settings.individuallySetSearchPageWallpaper && settings.enableWallpaperMasking) || (activatedPage !== AppPage.Search && settings.enableWallpaperMasking)"
pos="absolute top-0 left-0" w-full h-full pointer-events-none bg="$bew-bg-mask" z--1
:style="{ backdropFilter: `blur(${settings.wallpaperBlurIntensity}px)` }"
:style="{
backdropFilter: `blur(${settings.wallpaperBlurIntensity}px)`,
}"
/>
<div
v-else-if="settings.individuallySetSearchPageWallpaper && activatedPage === AppPage.Search && settings.searchPageEnableWallpaperMasking"
pos="absolute top-0 left-0" w-full h-full pointer-events-none bg="$bew-bg-mask" z--1
:style="{
backdropFilter: `blur(${settings.searchPageWallpaperBlurIntensity}px)`,
}"
/>
<div ref="mainAppRef" text="$bew-text-1" transition="opacity duration-300" h-100vh overflow-y-scroll :style="{ opacity: mainAppOpacity }">
<div m-auto max-w="$bew-page-max-width" :style="{ opacity: showSettings ? 0.2 : 1 }">
<div m-auto max-w="$bew-page-max-width" :style="{ opacity: showSettings ? 0.4 : 1 }">
<Transition name="topbar">
<Topbar
v-show="settings.isShowTopbar"

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup></script>
<script lang="ts" setup>
import { settings } from '~/logic'
</script>
<template>
<div
@@ -8,7 +10,7 @@
w-full
m="t-20vh"
>
<Logo :size="180" mb-12 />
<Logo v-if="settings.searchPageShowLogo" :size="180" mb-12 :color="settings.searchPageLogoColor === 'white' ? 'white' : 'var(--bew-theme-color)'" />
<SearchBar />
</div>
</template>

View File

@@ -18,4 +18,13 @@ export const settings = useStorageLocal('settings', ref<Settings>({
enableWallpaperMasking: false,
wallpaperMaskOpacity: 0,
wallpaperBlurIntensity: 0,
searchPageLogoColor: 'themeColor',
searchPageShowLogo: true,
individuallySetSearchPageWallpaper: false,
searchPageWallpaperMode: 'buildIn',
searchPageWallpaper: '',
searchPageEnableWallpaperMasking: false,
searchPageWallpaperMaskOpacity: 0,
searchPageWallpaperBlurIntensity: 0,
}), { mergeDefaults: true })

View File

@@ -10,4 +10,13 @@ export interface Settings {
enableWallpaperMasking: boolean
wallpaperMaskOpacity: number
wallpaperBlurIntensity: number
searchPageLogoColor: 'white' | 'themeColor'
searchPageShowLogo: boolean
individuallySetSearchPageWallpaper: boolean
searchPageWallpaperMode: 'buildIn' | 'byUrl'
searchPageWallpaper: string
searchPageEnableWallpaperMasking: boolean
searchPageWallpaperMaskOpacity: number
searchPageWallpaperBlurIntensity: number
}