mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add games popup (#5055)
This commit is contained in:
parent
1d1246eb4a
commit
81ef584251
@ -4,7 +4,8 @@ import { ranking } from './ranking/ranking'
|
||||
import { userInfo } from './user-info/user-info'
|
||||
import { logo } from './logo/logo'
|
||||
import { home } from './home/home'
|
||||
import { gamesIframe, livesIframe, mangaIframe } from './iframe/iframe'
|
||||
import { livesIframe, mangaIframe } from './iframe/iframe'
|
||||
import { games } from './games/games'
|
||||
import { blanks } from './flexible-blank/flexible-blank'
|
||||
import { bangumi, music, shop, match, creations } from './simple-links/simple-links'
|
||||
import { upload } from './upload/upload'
|
||||
@ -23,7 +24,7 @@ export const getBuiltInItems = (): CustomNavbarItemInit[] => [
|
||||
bangumi,
|
||||
ranking,
|
||||
music,
|
||||
gamesIframe,
|
||||
games,
|
||||
livesIframe,
|
||||
shop,
|
||||
match,
|
||||
|
||||
170
registry/lib/components/style/custom-navbar/games/GamesPopup.vue
Normal file
170
registry/lib/components/style/custom-navbar/games/GamesPopup.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, defineExpose, defineProps } from 'vue'
|
||||
import { VLoading } from '@/ui'
|
||||
import type { GameInfo } from './types'
|
||||
import { bilibiliApi, getJson } from '@/core/ajax'
|
||||
import { usePopper } from '../mixins'
|
||||
import { CustomNavbarItem } from '../custom-navbar-item'
|
||||
|
||||
const props = defineProps<{
|
||||
item: CustomNavbarItem
|
||||
container: HTMLElement
|
||||
}>()
|
||||
const popper = usePopper(props)
|
||||
|
||||
const gameInfo = ref<GameInfo | undefined>(undefined)
|
||||
const loading = ref(true)
|
||||
const loadGameInfo = async () => {
|
||||
if (gameInfo.value !== undefined) {
|
||||
return
|
||||
}
|
||||
const response = await bilibiliApi<GameInfo>(
|
||||
getJson('https://le3-api.game.bilibili.com/pc/game/nav/info'),
|
||||
)
|
||||
gameInfo.value = response
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
popupShow() {
|
||||
popper.popupShow()
|
||||
loadGameInfo()
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div class="custom-navbar-games-popup">
|
||||
<div v-if="loading" class="loading-container">
|
||||
<VLoading />
|
||||
</div>
|
||||
<div v-if="gameInfo" class="custom-navbar-games-panel">
|
||||
<div class="custom-navbar-games-left-panel">
|
||||
<a class="banner-game-card" :href="gameInfo.banner.href" :title="gameInfo.banner.title">
|
||||
<img :src="gameInfo.banner.poster" :alt="gameInfo.banner.title" />
|
||||
<div class="banner-game-card-title">
|
||||
{{ gameInfo.banner.title }}
|
||||
</div>
|
||||
</a>
|
||||
<div class="panel-game-cards">
|
||||
<a
|
||||
v-for="card of gameInfo.panel"
|
||||
:key="card.href"
|
||||
class="panel-game-card"
|
||||
:href="card.href"
|
||||
:title="card.title"
|
||||
>
|
||||
<img :src="card.poster" :alt="card.title" />
|
||||
<div class="panel-game-card-title">
|
||||
{{ card.title }}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="custom-navbar-games-panel-separator"></div>
|
||||
<div class="custom-navbar-games-right-panel">
|
||||
<div class="list-game-cards-title">新游预告</div>
|
||||
<div class="list-game-cards">
|
||||
<a
|
||||
v-for="card of gameInfo.list.slice(0, 9)"
|
||||
:key="card.href"
|
||||
class="list-game-card"
|
||||
:href="card.href"
|
||||
:title="card.title"
|
||||
>
|
||||
{{ card.title }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
|
||||
.custom-navbar-games-popup {
|
||||
width: 420px;
|
||||
font-size: 12px;
|
||||
$gap: 12px;
|
||||
@include v-stretch();
|
||||
.loading-container {
|
||||
flex-grow: 1;
|
||||
@include v-center();
|
||||
justify-content: center;
|
||||
height: 240px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.custom-navbar-games-panel {
|
||||
@include h-stretch($gap);
|
||||
padding: $gap;
|
||||
}
|
||||
.custom-navbar-games-left-panel {
|
||||
flex-basis: 60%;
|
||||
min-width: 0;
|
||||
@include v-stretch($gap);
|
||||
.banner-game-card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@include v-stretch();
|
||||
@include round-corner();
|
||||
img {
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
&:hover img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
&-title {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
padding: 8px;
|
||||
background-image: linear-gradient(to top, #0008, transparent);
|
||||
}
|
||||
}
|
||||
.panel-game-cards {
|
||||
@include h-stretch($gap);
|
||||
.panel-game-card {
|
||||
@include v-stretch(6px);
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
transition: color 0.2s ease-out;
|
||||
&:hover {
|
||||
color: var(--theme-color) !important;
|
||||
}
|
||||
&-title {
|
||||
@include max-line(2);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.custom-navbar-games-right-panel {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
@include v-stretch($gap);
|
||||
padding: 6px 4px;
|
||||
.list-game-cards-title {
|
||||
font-size: large;
|
||||
@include semi-bold();
|
||||
}
|
||||
.list-game-cards {
|
||||
@include v-stretch(8px);
|
||||
.list-game-card {
|
||||
@include single-line();
|
||||
opacity: 0.6;
|
||||
transition: all 0.2s ease-out;
|
||||
&:hover {
|
||||
color: var(--theme-color) !important;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.custom-navbar-games-panel-separator {
|
||||
width: 1px;
|
||||
background-color: #8882;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
14
registry/lib/components/style/custom-navbar/games/games.ts
Normal file
14
registry/lib/components/style/custom-navbar/games/games.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { CustomNavbarItemInit } from '../custom-navbar-item'
|
||||
|
||||
export const games: CustomNavbarItemInit = {
|
||||
name: 'games',
|
||||
displayName: '游戏中心',
|
||||
content: '游戏中心',
|
||||
|
||||
touch: true,
|
||||
href: 'https://game.bilibili.com/',
|
||||
|
||||
boundingWidth: 420,
|
||||
noPopupPadding: true,
|
||||
popupContent: () => import('./GamesPopup.vue').then(m => m.default),
|
||||
}
|
||||
11
registry/lib/components/style/custom-navbar/games/types.ts
Normal file
11
registry/lib/components/style/custom-navbar/games/types.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export interface GameListItem {
|
||||
href: string
|
||||
title: string
|
||||
poster: string
|
||||
}
|
||||
|
||||
export interface GameInfo {
|
||||
panel: GameListItem[]
|
||||
list: GameListItem[]
|
||||
banner: GameListItem
|
||||
}
|
||||
@ -21,15 +21,6 @@ const getIframeItem = (config: NavbarIframeConfig): CustomNavbarItemInit & Navba
|
||||
noPopupPadding: true,
|
||||
transparentPopup: true,
|
||||
})
|
||||
export const gamesIframe = getIframeItem({
|
||||
src: 'https://www.bilibili.com/page-proxy/game-nav.html',
|
||||
href: 'https://game.bilibili.com/',
|
||||
width: 680,
|
||||
height: 260,
|
||||
lazy: true,
|
||||
displayName: '游戏中心',
|
||||
iframeName: 'games',
|
||||
})
|
||||
export const livesIframe = getIframeItem({
|
||||
src: 'https://live.bilibili.com/blackboard/dropdown-menu.html',
|
||||
href: 'https://live.bilibili.com',
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { onMounted } from 'vue'
|
||||
import { CustomNavbarItem } from './custom-navbar-item'
|
||||
|
||||
export const popperMixin = Vue.extend({
|
||||
@ -25,3 +26,23 @@ export const popperMixin = Vue.extend({
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export interface UsePopperProps {
|
||||
item: CustomNavbarItem
|
||||
container: HTMLElement
|
||||
}
|
||||
export const usePopper = (props: UsePopperProps) => {
|
||||
onMounted(() => {
|
||||
const navBarItem = props.item
|
||||
const containerElement = props.container
|
||||
if (containerElement) {
|
||||
navBarItem?.usePopper(containerElement, containerElement.children[0] as HTMLElement)
|
||||
}
|
||||
})
|
||||
return {
|
||||
popupShow() {
|
||||
const navBarItem = props.item
|
||||
navBarItem?.popper?.update()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user