mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
refactor(top-bar): move all relative logic to TopBar.vue && remove alwaysShowTheTopBarLogoOnSearchPageMode setting
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user