refactor(top-bar): move all relative logic to TopBar.vue && remove alwaysShowTheTopBarLogoOnSearchPageMode setting

This commit is contained in:
Hakadao
2024-07-21 19:08:23 +08:00
parent d4d5fbe318
commit 95ae47b0af
8 changed files with 403 additions and 439 deletions

View File

@@ -151,7 +151,6 @@ settings:
home_tabs_adjustment: 标签栏调整
home_tabs_adjustment_desc: 第一个激活的标签项是默认界面
always_show_tabs_on_home_page: 总是显示首页标签栏
always_show_the_top_bar_logo: 总是显示顶栏 Logo
# Compatibility
# Common

View File

@@ -154,7 +154,6 @@ settings:
home_tabs_adjustment: 標籤欄調整
home_tabs_adjustment_desc: 第一個啟用的標籤項目調整頁面將是起始頁面
always_show_tabs_on_home_page: 總是顯示首頁標籤欄
always_show_the_top_bar_logo: 永遠顯示頂欄 Logo
# Compatibility
# Common

View File

@@ -152,7 +152,6 @@ settings:
home_tabs_adjustment: Tabs adjustment
home_tabs_adjustment_desc: The first activated tab is the default page
always_show_tabs_on_home_page: Always show tabs on the home page
always_show_the_top_bar_logo: Always show the top bar logo
# Compatibility
# Common

View File

@@ -154,7 +154,6 @@ settings:
home_tabs_adjustment: 分頁欄調整
home_tabs_adjustment_desc: 第一個啓用嘅分頁項目會係開始頁面
always_show_tabs_on_home_page: 永遠顯示主頁分頁欄
always_show_the_top_bar_logo: 永遠顯示頂欄 Logo
# Compatibility
# Common

View File

@@ -325,10 +325,6 @@ function handleToggleHomeTab(tab: any) {
<SettingsItem :title="$t('settings.search_page_mode_wallpaper_fixed')">
<Radio v-model="settings.searchPageModeWallpaperFixed" />
</SettingsItem>
<SettingsItem :title="$t('settings.always_show_the_top_bar_logo')">
<Radio v-model="settings.alwaysShowTheTopBarLogoOnSearchPageMode" />
</SettingsItem>
</template>
</SettingsItemGroup>
</div>

View File

@@ -5,6 +5,7 @@ import type { Ref, UnwrapNestedRefs } from 'vue'
import { useApiClient } from '~/composables/api'
import { useBewlyApp } from '~/composables/useAppProvider'
import { useDelayedHover } from '~/composables/useDelayedHover'
import { AppPage } from '~/enums/appEnums'
import { settings } from '~/logic'
import { getUserID, isHomePage } from '~/utils/main'
import emitter from '~/utils/mitt'
@@ -24,26 +25,15 @@ import type { UnReadDm, UnReadMessage, UserInfo } from './types'
// import { useTopBarStore } from '~/stores/topBarStore'
const props = withDefaults(defineProps<Props>(), {
showSearchBar: true,
showLogo: true,
})
// const popups = { NotificationsPop, MomentsPop, FavoritesPop, HistoryPop }
// const topBarStore = useTopBarStore()
interface Props {
showSearchBar?: boolean
showLogo?: boolean
mask?: boolean
}
// const topBarItems = computed(() => {
// return topBarStore.topBarItems
// })
const { activatedPage, scrollbarRef } = useBewlyApp()
const { activatedPage, scrollbarRef, reachTop } = useBewlyApp()
const mid = getUserID() || ''
const userInfo = reactive<UserInfo | NonNullable<unknown>>({}) as UnwrapNestedRefs<UserInfo>
@@ -52,16 +42,63 @@ const hideTopBar = ref<boolean>(false)
const headerTarget = ref(null)
const { isOutside: isOutsideTopBar } = useMouseInElement(headerTarget)
// const showChannelsPop = ref<boolean>(false)
// const showUserPanelPop = ref<boolean>(false)
// const showNotificationsPop = ref<boolean>(false)
// const showMomentsPop = ref<boolean>(false)
// const showFavoritesPop = ref<boolean>(false)
// const showHistoryPop = ref<boolean>(false)
// const showWatchLaterPop = ref<boolean>(false)
// const showUploadPop = ref<boolean>(false)
// const showMorePop = ref<boolean>(false)
const api = useApiClient()
// initially, assume the user is logged in cuz data retrieval is slow, which may show the login
// button even after login. if the user is not logged in, the login button will show up later
const isLogin = ref<boolean>(true)
const logo = ref<HTMLElement>() as Ref<HTMLElement>
const avatarImg = ref<HTMLImageElement>() as Ref<HTMLImageElement>
const avatarShadow = ref<HTMLImageElement>() as Ref<HTMLImageElement>
const favoritesPopRef = ref<any>()
const momentsPopRef = ref()
const scrollTop = ref<number>(0)
const oldScrollTop = ref<number>(0)
const isSearchPage = computed(() => {
if (/https?:\/\/search.bilibili.com\/.*$/.test(location.href))
return true
return false
})
const showSearchBar = computed(() => {
if (isHomePage()) {
if (settings.value.useOriginalBilibiliHomepage)
return true
if (activatedPage.value === AppPage.Search)
return false
if (settings.value.useSearchPageModeOnHomePage && activatedPage.value === AppPage.Home && reachTop.value)
return false
}
else {
if (isSearchPage.value)
return false
}
return true
})
const isTopBarFixed = computed(() => {
if (
(isHomePage() && settings.value.useOriginalBilibiliHomepage)
// video page
|| /https?:\/\/(?:www.)?bilibili.com\/(?:video|list)\/.*/.test(location.href)
// anime playback & movie page
|| /https?:\/\/(?:www.)?bilibili.com\/bangumi\/play\/.*/.test(location.href)
// moment page
|| /https?:\/\/t.bilibili.com.*/.test(location.href)
// channel, anime, chinese anime, tv shows, movie, variety shows, mooc
|| /https?:\/\/(?:www.)?bilibili.com\/(?:v|anime|guochuang|tv|movie|variety|mooc).*/.test(location.href)
// articles page
|| /https?:\/\/(?:www.)?bilibili.com\/read\/home.*/.test(location.href)
) {
return true
}
return false
})
// #region Popups visibility control
const popupVisible = reactive({
channels: false,
userPanel: false,
@@ -73,25 +110,6 @@ const popupVisible = reactive({
upload: false,
more: false,
})
const api = useApiClient()
// initially, assume the user is logged in cuz data retrieval is slow, which may show the login
// button even after login. if the user is not logged in, the login button will show up later
const isLogin = ref<boolean>(true)
const unReadMessage = reactive<UnReadMessage | NonNullable<unknown>>(
{},
) as UnwrapNestedRefs<UnReadMessage>
const unReadDm = reactive<UnReadDm>({} as UnwrapNestedRefs<UnReadDm>)
const unReadMessageCount = ref<number>(0)
const newMomentsCount = ref<number>(0)
const logo = ref<HTMLElement>() as Ref<HTMLElement>
const avatarImg = ref<HTMLImageElement>() as Ref<HTMLImageElement>
const avatarShadow = ref<HTMLImageElement>() as Ref<HTMLImageElement>
const favoritesPopRef = ref<any>()
const momentsPopRef = ref()
const scrollTop = ref<number>(0)
const oldScrollTop = ref<number>(0)
function closeAllTopBarPopup(exceptionKey?: keyof typeof popupVisible) {
Object.keys(popupVisible).forEach((key) => {
@@ -145,6 +163,7 @@ const notifications = useDelayedHover({
popupVisible.notifications = false
},
})
// Moments
const moments = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup('moments'),
@@ -156,6 +175,7 @@ const moments = useDelayedHover({
popupVisible.moments = false
},
})
// Favorites
const favorites = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup('favorites'),
@@ -166,6 +186,7 @@ const favorites = useDelayedHover({
popupVisible.favorites = false
},
})
// History
const history = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup('history'),
@@ -176,6 +197,7 @@ const history = useDelayedHover({
popupVisible.history = false
},
})
// Watch Later
const watchLater = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup('watchLater'),
@@ -186,6 +208,7 @@ const watchLater = useDelayedHover({
popupVisible.watchLater = false
},
})
// Upload
const upload = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup('upload'),
@@ -196,6 +219,7 @@ const upload = useDelayedHover({
popupVisible.upload = false
},
})
// More
const more = useDelayedHover({
beforeEnter: () => closeAllTopBarPopup(),
@@ -205,6 +229,8 @@ const more = useDelayedHover({
leave: () => popupVisible.more = false,
})
// #endregion
watch(() => settings.value.autoHideTopBar, (newVal) => {
if (!newVal)
toggleTopBarVisible(true)
@@ -317,6 +343,13 @@ async function getUserInfo() {
}
}
// #region Notifications
const unReadMessage = reactive<UnReadMessage | NonNullable<unknown>>(
{},
) as UnwrapNestedRefs<UnReadMessage>
const unReadDm = reactive<UnReadDm>({} as UnwrapNestedRefs<UnReadDm>)
const unReadMessageCount = ref<number>(0)
async function getUnreadMessageCount() {
if (!isLogin.value)
return
@@ -350,6 +383,10 @@ async function getUnreadMessageCount() {
unReadMessageCount.value = result
}
}
// #endregion
// #region Moments
const newMomentsCount = ref<number>(0)
async function getTopBarNewMomentsCount() {
if (!isLogin.value)
@@ -368,6 +405,7 @@ async function getTopBarNewMomentsCount() {
newMomentsCount.value = result
}
}
// #endregion
function toggleTopBarVisible(visible: boolean) {
hideTopBar.value = !visible
@@ -381,52 +419,53 @@ defineExpose({
</script>
<template>
<header
ref="headerTarget"
w="full" transition="all 300 ease-in-out"
:class="{ hide: hideTopBar }"
>
<main
max-w="$bew-page-max-width"
flex="~ justify-between items-center gap-4"
p="lg:x-20 md:x-16 x-14" m-auto
h="$bew-top-bar-height"
<Transition name="top-bar">
<header
v-if="settings.showTopBar"
ref="headerTarget"
w="full" transition="all 300 ease-in-out"
:class="{ hide: hideTopBar }"
:style="{ position: isTopBarFixed ? 'fixed' : 'absolute' }"
>
<!-- Top bar mask -->
<div
v-if="mask"
style="
mask-image: linear-gradient(to bottom, black 20%, transparent);
"
:style="{ backdropFilter: settings.disableFrostedGlass ? 'none' : 'blur(4px)' }"
pos="absolute top-0 left-0" w-full h-80px
pointer-events-none transform-gpu
/>
<Transition name="fade">
<main
max-w="$bew-page-max-width"
flex="~ justify-between items-center gap-4"
p="lg:x-20 md:x-16 x-14" m-auto
h="$bew-top-bar-height"
>
<!-- Top bar mask -->
<div
v-if="mask"
v-if="!reachTop"
style="
mask-image: linear-gradient(to bottom, black 20%, transparent);
"
:style="{ backdropFilter: settings.disableFrostedGlass ? 'none' : 'blur(4px)' }"
pos="absolute top-0 left-0" w-full h-80px
pointer-events-none opacity-80
:style="{
background: `linear-gradient(to bottom, ${(
settings.wallpaper
|| settings.useSearchPageModeOnHomePage
&& settings.searchPageWallpaper
&& settings.individuallySetSearchPageWallpaper)
&& isHomePage()
? 'rgba(0,0,0,.6)' : `${isHomePage() ? 'var(--bew-homepage-bg)' : 'var(--bew-bg)'}`}, transparent)`,
}"
pointer-events-none transform-gpu
/>
</Transition>
<Transition name="fade">
<div
v-if="!reachTop"
pos="absolute top-0 left-0" w-full h-80px
pointer-events-none opacity-80
:style="{
background: `linear-gradient(to bottom, ${(
settings.wallpaper
|| settings.useSearchPageModeOnHomePage
&& settings.searchPageWallpaper
&& settings.individuallySetSearchPageWallpaper)
&& isHomePage()
? 'rgba(0,0,0,.6)' : `${isHomePage() ? 'var(--bew-homepage-bg)' : 'var(--bew-bg)'}`}, transparent)`,
}"
/>
</Transition>
<div shrink-0 flex="inline xl:1 justify-center">
<div
ref="channels"
z-1 relative w-fit mr-auto
>
<Transition name="slide-out">
<div shrink-0 flex="inline xl:1 justify-center">
<div
ref="channels"
z-1 relative w-fit mr-auto
>
<a
v-show="showLogo"
ref="logo" href="//www.bilibili.com"
class="group logo"
:class="{ activated: popupVisible.channels }"
@@ -447,117 +486,116 @@ defineExpose({
>
<path d="M450.803484 456.506027l-120.670435 23.103715 10.333298 45.288107 119.454151-23.102578-9.117014-45.289244z m65.04448 120.060586c-29.483236 63.220622-55.926329 15.502222-55.926328 15.502223l-19.754098 12.768142s38.90176 53.192249 75.986489 12.764729c43.770311 40.42752 77.203911-13.068516 77.203911-13.068516l-17.934791-11.55072c0.001138-0.304924-31.305956 44.983182-59.575183-16.415858z m59.57632-74.773617L695.182222 524.895573l10.029511-45.288106-120.364373-23.103716-9.423076 45.289245z m237.784178-88.926436c-1.905778-84.362809-75.487004-100.540871-75.487004-100.540871s-57.408853-0.316302-131.944676-0.95232l54.237867-52.332089s8.562916-10.784996-6.026809-22.834062c-14.592-12.051342-15.543182-6.660551-20.615396-3.487289-4.441884 3.169849-69.462471 66.920676-80.878933 78.340551-29.494613 0-60.2624-0.319716-90.075591-0.319716h10.466418s-77.705671-76.754489-82.781298-80.241777c-5.075627-3.488427-5.709369-8.56064-20.616533 3.487289-14.589724 12.05248-6.026809 22.8352-6.026809 22.8352l55.504213 53.919288c-60.261262 0-112.280462 0.319716-136.383147 1.268623-78.025387 22.521173-71.99744 100.859449-71.99744 100.859449s0.950044 168.100978 0 253.103217c8.562916 85.00224 73.899804 98.636231 73.899805 98.636231s26.007324 0.63488 45.357511 0.63488c1.900089 5.391929 3.486151 32.034133 33.302756 32.034134 29.495751 0 33.30048-32.034133 33.30048-32.034134s217.263218-0.950044 235.340231-0.950044c0.953458 9.196658 5.394204 33.619058 35.207395 33.303893 29.494613-0.636018 31.714418-35.20512 31.714418-35.20512s10.151253-0.95232 40.280747 0c70.413653-13.005938 74.534684-95.468658 74.534684-95.468657s-1.265209-169.689316-0.312889-254.056676zM752.628622 681.8304c0 13.319964-10.467556 24.102684-23.471218 24.102684H300.980907c-13.003662 0-23.47008-10.78272-23.47008-24.102684V397.961671c0-13.32224 10.467556-24.106098 23.47008-24.106098h428.176497c13.003662 0 23.471218 10.783858 23.471218 24.106098v283.868729z" p-id="1478" /></svg>
</a>
</Transition>
<Transition name="slide-in">
<ChannelsPop
v-show="popupVisible.channels"
class="bew-popover"
pos="!left-0 !top-70px"
transform="!translate-x-0"
/>
</Transition>
<Transition name="slide-in">
<ChannelsPop
v-show="popupVisible.channels"
class="bew-popover"
pos="!left-0 !top-70px"
transform="!translate-x-0"
/>
</Transition>
</div>
</div>
</div>
<!-- search bar -->
<div flex="inline 1 md:justify-center <md:justify-end items-center" w="full">
<Transition name="slide-out">
<SearchBar
v-if="props.showSearchBar"
style="
<!-- search bar -->
<div flex="inline 1 md:justify-center <md:justify-end items-center" w="full">
<Transition name="slide-out">
<SearchBar
v-if="showSearchBar"
style="
--b-search-bar-color: var(--bew-elevated);
--b-search-bar-hover: var(--bew-elevated-hover);
"
/>
</Transition>
</div>
<!-- right content -->
<div
class="right-side"
flex="inline xl:1 justify-end items-center"
>
<!-- Avatar -->
<div
v-if="isLogin"
ref="avatar"
class="avatar right-side-item relative"
shadow="$bew-shadow-2" rounded-full
>
<a
ref="avatarImg"
:href="`https://space.bilibili.com/${mid}`"
:target="isHomePage() ? '_blank' : '_self'"
class="avatar-img"
:class="{ hover: popupVisible.userPanel }"
:style="{
backgroundImage: `url(${`${userInfo.face}`.replace(
'http:',
'',
)})`,
}"
rounded-full w-40px h-40px
shadow="$bew-shadow-2"
bg="$bew-fill-3 cover center"
z-1
/>
<div
ref="avatarShadow"
class="avatar-shadow"
:class="{ hover: popupVisible.userPanel }"
:style="{
backgroundImage: `url(${`${userInfo.face}`.replace(
'http:',
'',
)})`,
}"
pos="absolute top-0" z-0 pointer-events-none
bg="cover center" blur-sm
rounded-full
w-40px h-40px
/>
<svg
v-if="userInfo.vip?.status === 1"
class="vip-img"
:class="{ hover: popupVisible.userPanel }"
:style="{ opacity: popupVisible.userPanel ? 1 : 0 }"
bg="[url(https://i0.hdslb.com/bfs/seed/jinkela/short/user-avatar/big-vip.svg)] cover no-repeat"
w="27.5%" h="27.5%" z-1
pos="absolute bottom-0 right-0" duration-300
/>
<Transition name="slide-in">
<UserPanelPop
v-if="popupVisible.userPanel"
:user-info="userInfo"
after:h="!0"
class="bew-popover"
/>
</Transition>
</div>
<!-- right content -->
<div
class="others"
:class="{ inactive: rightSideInactive }"
style="
class="right-side"
flex="inline xl:1 justify-end items-center"
>
<!-- Avatar -->
<div
v-if="isLogin"
ref="avatar"
class="avatar right-side-item relative"
shadow="$bew-shadow-2" rounded-full
>
<a
ref="avatarImg"
:href="`https://space.bilibili.com/${mid}`"
:target="isHomePage() ? '_blank' : '_self'"
class="avatar-img"
:class="{ hover: popupVisible.userPanel }"
:style="{
backgroundImage: `url(${`${userInfo.face}`.replace(
'http:',
'',
)})`,
}"
rounded-full w-40px h-40px
shadow="$bew-shadow-2"
bg="$bew-fill-3 cover center"
z-1
/>
<div
ref="avatarShadow"
class="avatar-shadow"
:class="{ hover: popupVisible.userPanel }"
:style="{
backgroundImage: `url(${`${userInfo.face}`.replace(
'http:',
'',
)})`,
}"
pos="absolute top-0" z-0 pointer-events-none
bg="cover center" blur-sm
rounded-full
w-40px h-40px
/>
<svg
v-if="userInfo.vip?.status === 1"
class="vip-img"
:class="{ hover: popupVisible.userPanel }"
:style="{ opacity: popupVisible.userPanel ? 1 : 0 }"
bg="[url(https://i0.hdslb.com/bfs/seed/jinkela/short/user-avatar/big-vip.svg)] cover no-repeat"
w="27.5%" h="27.5%" z-1
pos="absolute bottom-0 right-0" duration-300
/>
<Transition name="slide-in">
<UserPanelPop
v-if="popupVisible.userPanel"
:user-info="userInfo"
after:h="!0"
class="bew-popover"
/>
</Transition>
</div>
<div
class="others"
:class="{ inactive: rightSideInactive }"
style="
backdrop-filter: var(--bew-filter-glass-1);
box-shadow: var(--bew-shadow-edge-glow-1), var(--bew-shadow-2);
"
flex h-50px px-6px bg="$bew-elevated"
transition="transition-property-colors duration-150"
text="$bew-text-1" border="1 $bew-border-color" rounded-full
transform-gpu
>
<div v-if="!isLogin" class="right-side-item">
<a href="https://passport.bilibili.com/login" class="login">
<div i-ic:outline-account-circle class="text-xl mr-2" />{{
$t('topbar.sign_in')
}}
</a>
</div>
<template v-if="isLogin">
<!-- TODO: need to refactor to this -->
<!-- <div display="lg:flex none">
flex h-50px px-6px bg="$bew-elevated"
transition="transition-property-colors duration-150"
text="$bew-text-1" border="1 $bew-border-color" rounded-full
transform-gpu
>
<div v-if="!isLogin" class="right-side-item">
<a href="https://passport.bilibili.com/login" class="login">
<div i-ic:outline-account-circle class="text-xl mr-2" />{{
$t('topbar.sign_in')
}}
</a>
</div>
<template v-if="isLogin">
<!-- TODO: need to refactor to this -->
<!-- <div display="lg:flex none">
<div v-for="item in topBarItems" :key="item.i18nKey" class="right-side-item">
<a :href="item.url" target="_blank" :title="$t(item.i18nKey)">
<Icon :icon="item.icon" />
@@ -571,204 +609,215 @@ defineExpose({
</div>
</div> -->
<!-- TODO: need to refactor to above code -->
<div class="hidden lg:flex" gap-1>
<!-- Notifications -->
<div
ref="notifications"
class="right-side-item"
:class="{ active: popupVisible.notifications }"
>
<template v-if="unReadMessageCount > 0">
<div
v-if="settings.topBarIconBadges === 'number'"
class="unread-num-dot"
<!-- TODO: need to refactor to above code -->
<div class="hidden lg:flex" gap-1>
<!-- Notifications -->
<div
ref="notifications"
class="right-side-item"
:class="{ active: popupVisible.notifications }"
>
<template v-if="unReadMessageCount > 0">
<div
v-if="settings.topBarIconBadges === 'number'"
class="unread-num-dot"
>
{{ unReadMessageCount > 99 ? '99+' : unReadMessageCount }}
</div>
<div
v-else-if="settings.topBarIconBadges === 'dot'"
class="unread-dot"
/>
</template>
<a
href="https://message.bilibili.com"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.notifications')"
>
{{ unReadMessageCount > 99 ? '99+' : unReadMessageCount }}
</div>
<div
v-else-if="settings.topBarIconBadges === 'dot'"
class="unread-dot"
/>
</template>
<a
href="https://message.bilibili.com"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.notifications')"
>
<div i-tabler:bell />
</a>
<div i-tabler:bell />
</a>
<Transition name="slide-in">
<NotificationsPop
v-if="popupVisible.notifications"
class="bew-popover"
/>
</Transition>
</div>
<!-- Moments -->
<div
ref="moments"
class="right-side-item"
:class="{ active: popupVisible.moments }"
>
<template v-if="newMomentsCount > 0">
<div
v-if="settings.topBarIconBadges === 'number'"
class="unread-num-dot"
>
{{ newMomentsCount > 99 ? '99+' : newMomentsCount }}
</div>
<div
v-else-if="settings.topBarIconBadges === 'dot'"
class="unread-dot"
/>
</template>
<a
href="https://t.bilibili.com"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.moments')"
>
<div i-tabler:windmill />
</a>
<Transition name="slide-in">
<MomentsPop v-show="popupVisible.moments" ref="momentsPopRef" class="bew-popover" />
</Transition>
</div>
<!-- Favorites -->
<div
ref="favorites"
class="right-side-item"
:class="{ active: popupVisible.favorites }"
>
<a
:href="`https://space.bilibili.com/${mid}/favlist`"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.favorites')"
>
<div i-mingcute:star-line />
</a>
<Transition name="slide-in">
<KeepAlive>
<FavoritesPop
v-if="popupVisible.favorites"
ref="favoritesPopRef"
<Transition name="slide-in">
<NotificationsPop
v-if="popupVisible.notifications"
class="bew-popover"
/>
</KeepAlive>
</Transition>
</Transition>
</div>
<!-- Moments -->
<div
ref="moments"
class="right-side-item"
:class="{ active: popupVisible.moments }"
>
<template v-if="newMomentsCount > 0">
<div
v-if="settings.topBarIconBadges === 'number'"
class="unread-num-dot"
>
{{ newMomentsCount > 99 ? '99+' : newMomentsCount }}
</div>
<div
v-else-if="settings.topBarIconBadges === 'dot'"
class="unread-dot"
/>
</template>
<a
href="https://t.bilibili.com"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.moments')"
>
<div i-tabler:windmill />
</a>
<Transition name="slide-in">
<MomentsPop v-show="popupVisible.moments" ref="momentsPopRef" class="bew-popover" />
</Transition>
</div>
<!-- Favorites -->
<div
ref="favorites"
class="right-side-item"
:class="{ active: popupVisible.favorites }"
>
<a
:href="`https://space.bilibili.com/${mid}/favlist`"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.favorites')"
>
<div i-mingcute:star-line />
</a>
<Transition name="slide-in">
<KeepAlive>
<FavoritesPop
v-if="popupVisible.favorites"
ref="favoritesPopRef"
class="bew-popover"
/>
</KeepAlive>
</Transition>
</div>
<!-- History -->
<div
ref="history"
class="right-side-item"
:class="{ active: popupVisible.history }"
>
<a
href="https://www.bilibili.com/account/history"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.history')"
>
<div i-mingcute:time-line />
</a>
<Transition name="slide-in">
<HistoryPop v-if="popupVisible.history" class="bew-popover" />
</Transition>
</div>
<!-- Watch later -->
<div
ref="watchLater"
class="right-side-item"
:class="{ active: popupVisible.watchLater }"
>
<a
href="https://www.bilibili.com/watchlater/#/list"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.watch_later')"
>
<div i-mingcute:carplay-line />
</a>
<Transition name="slide-in">
<WatchLaterPop v-if="popupVisible.watchLater" class="bew-popover" ml--30px />
</Transition>
</div>
<!-- Creative center -->
<div class="right-side-item">
<a
href="https://member.bilibili.com/platform/home"
target="_blank"
:title="$t('topbar.creative_center')"
>
<div i-mingcute:bulb-line />
</a>
</div>
</div>
<!-- History -->
<!-- More -->
<div
ref="history"
class="right-side-item"
:class="{ active: popupVisible.history }"
ref="more"
class="right-side-item lg:!hidden flex"
:class="{ active: popupVisible.more }"
>
<a
href="https://www.bilibili.com/account/history"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.history')"
>
<div i-mingcute:time-line />
<a title="More">
<div i-mingcute:menu-line />
</a>
<Transition name="slide-in">
<HistoryPop v-if="popupVisible.history" class="bew-popover" />
<MorePop v-show="popupVisible.more" class="bew-popover" />
</Transition>
</div>
<!-- Watch later -->
<!-- Upload -->
<div
ref="watchLater"
class="right-side-item"
:class="{ active: popupVisible.watchLater }"
ref="upload"
class="upload right-side-item"
>
<a
href="https://www.bilibili.com/watchlater/#/list"
:target="isHomePage() ? '_blank' : '_self'"
:title="$t('topbar.watch_later')"
>
<div i-mingcute:carplay-line />
</a>
<Transition name="slide-in">
<WatchLaterPop v-if="popupVisible.watchLater" class="bew-popover" ml--30px />
</Transition>
</div>
<!-- Creative center -->
<div class="right-side-item">
<a
href="https://member.bilibili.com/platform/home"
href="https://member.bilibili.com/platform/upload/video/frame"
target="_blank"
:title="$t('topbar.creative_center')"
:title="$t('topbar.upload')"
bg="$bew-theme-color"
rounded-40px
un-text="!white !base"
w-35px h-35px ml-1
flex="~ justify-center"
shadow
filter="hover:brightness-110"
style="--un-shadow: 0 0 10px var(--bew-theme-color-60)"
>
<div i-mingcute:bulb-line />
</a>
</div>
</div>
<!-- More -->
<div
ref="more"
class="right-side-item lg:!hidden flex"
:class="{ active: popupVisible.more }"
>
<a title="More">
<div i-mingcute:menu-line />
</a>
<Transition name="slide-in">
<MorePop v-show="popupVisible.more" class="bew-popover" />
</Transition>
</div>
<!-- Upload -->
<div
ref="upload"
class="upload right-side-item"
>
<a
href="https://member.bilibili.com/platform/upload/video/frame"
target="_blank"
:title="$t('topbar.upload')"
bg="$bew-theme-color"
rounded-40px
un-text="!white !base"
w-35px h-35px ml-1
flex="~ justify-center"
shadow
filter="hover:brightness-110"
style="--un-shadow: 0 0 10px var(--bew-theme-color-60)"
>
<div i-mingcute:upload-2-line flex-shrink-0 />
<div i-mingcute:upload-2-line flex-shrink-0 />
<!-- <span m="l-2" class="hidden xl:block">{{
$t('topbar.upload')
}}</span> -->
</a>
</a>
<Transition name="slide-in">
<UploadPop
v-if="popupVisible.upload"
class="bew-popover"
pos="!left-auto !right-0"
transform="!translate-x-0"
/>
</Transition>
</div>
</template>
<Transition name="slide-in">
<UploadPop
v-if="popupVisible.upload"
class="bew-popover"
pos="!left-auto !right-0"
transform="!translate-x-0"
/>
</Transition>
</div>
</template>
</div>
</div>
</div>
</main>
</header>
</main>
</header>
</Transition>
</template>
<style lang="scss" scoped>
.top-bar-enter-active,
.top-bar-leave-active {
transition: all 0.5s ease;
}
.top-bar-enter-from,
.top-bar-leave-to {
--uno: "opacity-0 transform -translate-y-full";
}
.slide-in-enter-active,
.slide-in-leave-active {
--uno: "transition-all duration-300 pointer-events-none transform-gpu";

View File

@@ -31,7 +31,6 @@ const pages = {
}
const mainAppRef = ref<HTMLElement>() as Ref<HTMLElement>
const scrollbarRef = ref()
const showTopBarMask = ref<boolean>(false)
const handlePageRefresh = ref<() => void>()
const handleReachBottom = ref<() => void>()
const handleThrottledPageRefresh = useThrottleFn(() => handlePageRefresh.value?.(), 500)
@@ -40,31 +39,6 @@ const handleThrottledBackToTop = useThrottleFn(() => handleBackToTop(), 1000)
const topBarRef = ref()
const reachTop = ref<boolean>(true)
const isSearchPage = computed(() => {
if (/https?:\/\/search.bilibili.com\/.*$/.test(location.href))
return true
return false
})
const isTopBarFixed = computed(() => {
if (
isHomePage()
// video page
|| /https?:\/\/(?:www.)?bilibili.com\/(?:video|list)\/.*/.test(location.href)
// anime playback & movie page
|| /https?:\/\/(?:www.)?bilibili.com\/bangumi\/play\/.*/.test(location.href)
// moment page
|| /https?:\/\/t.bilibili.com.*/.test(location.href)
// channel, anime, chinese anime, tv shows, movie, variety shows, mooc
|| /https?:\/\/(?:www.)?bilibili.com\/(?:v|anime|guochuang|tv|movie|variety|mooc).*/.test(location.href)
// articles page
|| /https?:\/\/(?:www.)?bilibili.com\/read\/home.*/.test(location.href)
) {
return true
}
return false
})
watch(
() => activatedPage.value,
() => {
@@ -122,8 +96,9 @@ onMounted(() => {
document.addEventListener('scroll', () => {
if (window.scrollY > 0)
showTopBarMask.value = true
else showTopBarMask.value = false
reachTop.value = false
else
reachTop.value = true
})
handleChangeAccessKey()
@@ -207,11 +182,9 @@ function handleOsScroll() {
const { scrollTop, scrollHeight, clientHeight } = viewport // get scroll offset
if (scrollTop === 0) {
showTopBarMask.value = false
reachTop.value = true
}
else {
showTopBarMask.value = true
reachTop.value = false
}
@@ -265,20 +238,6 @@ function handleReduceFrostedGlassBlur() {
}
}
// fix #166 https://github.com/hakadao/BewlyBewly/issues/166
// function openVideoPageIfBvidExists() {
// Assume the URL is https://www.bilibili.com/?bvid=BV1be41127ft&spm_id_from=333.788.seo.out
// // Get the current URL's query string
// const queryString = window.location.search
// // Create a URLSearchParams instance
// const urlParams = new URLSearchParams(queryString)
// const bvid = urlParams.get('bvid')
// if (bvid)
// window.open(`https://www.bilibili.com/video/${bvid}`, '_self')
// }
/**
* Checks if the current viewport has a scrollbar.
* @returns {boolean} Returns true if the viewport has a scrollbar, false otherwise.
@@ -340,33 +299,9 @@ provide<BewlyAppProvider>('BEWLY_APP', {
<!-- TopBar -->
<div m-auto max-w="$bew-page-max-width">
<Transition name="top-bar">
<TopBar
v-if="settings.showTopBar && !isHomePage()"
pos="top-0 left-0" z="99 hover:1001" w-full
:style="{ position: isTopBarFixed ? 'fixed' : 'absolute' }"
:show-search-bar="!isSearchPage"
:mask="showTopBarMask"
/>
<TopBar
v-else-if="settings.showTopBar && isHomePage()"
ref="topBarRef"
:show-search-bar="showTopBarMask && settings.useSearchPageModeOnHomePage
|| (
!settings.useSearchPageModeOnHomePage && activatedPage !== AppPage.Search
|| activatedPage !== AppPage.Home && activatedPage !== AppPage.Search
)
|| settings.useOriginalBilibiliHomepage"
:show-logo="settings.alwaysShowTheTopBarLogoOnSearchPageMode
|| (
showTopBarMask && settings.useSearchPageModeOnHomePage
|| (!settings.useSearchPageModeOnHomePage || activatedPage !== AppPage.Home)
|| settings.useOriginalBilibiliHomepage
)"
:mask="showTopBarMask"
pos="fixed top-0 left-0" z="99 hover:1001" w-full
/>
</Transition>
<TopBar
pos="top-0 left-0" z="99 hover:1001" w-full
/>
</div>
<div
@@ -399,16 +334,6 @@ provide<BewlyAppProvider>('BEWLY_APP', {
</template>
<style lang="scss" scoped>
.top-bar-enter-active,
.top-bar-leave-active {
transition: all 0.5s ease;
}
.top-bar-enter-from,
.top-bar-leave-to {
--uno: "opacity-0 transform -translate-y-full";
}
.bewly-wrapper {
--uno: "text-size-$bew-base-font-size";

View File

@@ -59,7 +59,6 @@ export interface Settings {
alwaysShowTabsOnHomePage: boolean
useSearchPageModeOnHomePage: boolean
searchPageModeWallpaperFixed: boolean
alwaysShowTheTopBarLogoOnSearchPageMode: boolean
adaptToOtherPageStyles: boolean
showTopBar: boolean
@@ -117,7 +116,6 @@ export const settings = useStorageLocal('settings', ref<Settings>({
alwaysShowTabsOnHomePage: false,
useSearchPageModeOnHomePage: false,
searchPageModeWallpaperFixed: false,
alwaysShowTheTopBarLogoOnSearchPageMode: false,
adaptToOtherPageStyles: true,
showTopBar: true,