mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
重构多个组件以优化代码格式和可读性,删除不必要的文件,更新类型定义,添加数据分析路由
This commit is contained in:
@@ -1,24 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { useDanmakuClient } from '@/store/useDanmakuClient';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import MessageRender from './blivechat/MessageRender.vue';
|
||||
import { useDanmakuClient } from '@/store/useDanmakuClient';
|
||||
// @ts-ignore
|
||||
import * as constants from './blivechat/constants';
|
||||
// @ts-ignore
|
||||
import * as chatModels from '../../data/chat/models';
|
||||
import * as pronunciation from './blivechat/utils/pronunciation';
|
||||
// @ts-ignore
|
||||
import * as pronunciation from './blivechat/utils/pronunciation'
|
||||
// @ts-ignore
|
||||
import * as trie from './blivechat/utils/trie'
|
||||
import { EventModel } from '@/api/api-models';
|
||||
import { DownloadConfig, useAccount } from '@/api/account';
|
||||
import { useWebRTC } from '@/store/useRTC';
|
||||
import { QueryGetAPI } from '@/api/query';
|
||||
import { OPEN_LIVE_API_URL, VTSURU_API_URL } from '@/data/constants';
|
||||
import { CustomChart } from 'echarts/charts';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { NAlert } from 'naive-ui';
|
||||
import { VTSURU_API_URL } from '@/data/constants';
|
||||
import { DanmakuInfo, GiftInfo, GuardInfo, SCInfo } from '@/data/DanmakuClients/OpenLiveClient';
|
||||
import { useWebRTC } from '@/store/useRTC';
|
||||
import { NAlert } from 'naive-ui';
|
||||
import { useRoute } from 'vue-router';
|
||||
// @ts-ignore
|
||||
import * as trie from './blivechat/utils/trie';
|
||||
|
||||
export interface DanmujiConfig {
|
||||
minGiftPrice: number,
|
||||
@@ -411,7 +408,17 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NAlert v-if="!$route.query.token && isOBS" type="error"> 未携带token参数 </NAlert>
|
||||
<MessageRender v-else ref="messageRender" :customCss="customCss" :showGiftName="config.showGiftName"
|
||||
style="height: 100%; width: 100%" />
|
||||
<NAlert
|
||||
v-if="!$route.query.token && isOBS"
|
||||
type="error"
|
||||
>
|
||||
未携带token参数
|
||||
</NAlert>
|
||||
<MessageRender
|
||||
v-else
|
||||
ref="messageRender"
|
||||
:custom-css="customCss"
|
||||
:show-gift-name="config.showGiftName"
|
||||
style="height: 100%; width: 100%"
|
||||
/>
|
||||
</template>
|
||||
@@ -54,12 +54,25 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="lottery-background" v-bind="$attrs">
|
||||
<p class="lottery-header">抽奖</p>
|
||||
<NDivider v-if="result.type == OpenLiveLotteryType.Waiting" class="lottery-divider">
|
||||
<p class="lottery-header-count">已有 {{ users?.length ?? 0 }} 人</p>
|
||||
<div
|
||||
class="lottery-background"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<p class="lottery-header">
|
||||
抽奖
|
||||
</p>
|
||||
<NDivider
|
||||
v-if="result.type == OpenLiveLotteryType.Waiting"
|
||||
class="lottery-divider"
|
||||
>
|
||||
<p class="lottery-header-count">
|
||||
已有 {{ users?.length ?? 0 }} 人
|
||||
</p>
|
||||
</NDivider>
|
||||
<div class="lottery-content" ref="listContainerRef">
|
||||
<div
|
||||
ref="listContainerRef"
|
||||
class="lottery-content"
|
||||
>
|
||||
<template v-if="users.length > 0">
|
||||
<Vue3Marquee
|
||||
v-if="result.type == OpenLiveLotteryType.Waiting"
|
||||
@@ -69,25 +82,38 @@ onUnmounted(() => {
|
||||
:style="`height: ${height}px;`"
|
||||
>
|
||||
<span
|
||||
class="lottery-list-item"
|
||||
:id="index.toString()"
|
||||
v-for="(user, index) in users"
|
||||
:id="index.toString()"
|
||||
:key="user.uId"
|
||||
class="lottery-list-item"
|
||||
style="height: 50px"
|
||||
>
|
||||
<img class="lottery-avatar" :src="user.avatar + '@30h'" referrerpolicy="no-referrer" />
|
||||
<img
|
||||
class="lottery-avatar"
|
||||
:src="user.avatar + '@30h'"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
<div>
|
||||
<p class="lottery-name">{{ user.name }}</p>
|
||||
</div>
|
||||
</span>
|
||||
</Vue3Marquee>
|
||||
</template>
|
||||
<div v-else style="position: relative; top: 20%">
|
||||
<div
|
||||
v-else
|
||||
style="position: relative; top: 20%"
|
||||
>
|
||||
<NEmpty description="暂无人参与" />
|
||||
</div>
|
||||
<template v-if="result.type == OpenLiveLotteryType.Result">
|
||||
<p style="text-align: center; font-size: 20px; margin: 0; font-weight: bold; color: #eeabab">结果</p>
|
||||
<Vue3Marquee v-if="100 * result.resultUsers.length > width" justify="center" style="height: 100px">
|
||||
<p style="text-align: center; font-size: 20px; margin: 0; font-weight: bold; color: #eeabab">
|
||||
结果
|
||||
</p>
|
||||
<Vue3Marquee
|
||||
v-if="100 * result.resultUsers.length > width"
|
||||
justify="center"
|
||||
style="height: 100px"
|
||||
>
|
||||
<div
|
||||
v-for="user in result.resultUsers"
|
||||
:key="user.uId"
|
||||
@@ -111,7 +137,7 @@ onUnmounted(() => {
|
||||
style="border-radius: 50%"
|
||||
:src="user.avatar + '@50h_50w'"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
>
|
||||
<NText style="font-size: large">
|
||||
{{ user.name }}
|
||||
</NText>
|
||||
@@ -141,7 +167,7 @@ onUnmounted(() => {
|
||||
style="border-radius: 50%"
|
||||
:src="user.avatar + '@50h_50w'"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
>
|
||||
<NText style="font-size: large; margin-top: 10px">
|
||||
{{ user.name }}
|
||||
</NText>
|
||||
|
||||
@@ -58,7 +58,7 @@ const songs = computed(() => {
|
||||
}
|
||||
}
|
||||
if (settings.value.isReverse) {
|
||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||
|
||||
return result.Reverse().ToArray()
|
||||
} else {
|
||||
return result.ToArray()
|
||||
@@ -110,7 +110,6 @@ const allowGuardTypes = computed(() => {
|
||||
return types
|
||||
})
|
||||
async function update() {
|
||||
if (!visiable.value || !active.value) return
|
||||
const r = await get()
|
||||
if (r) {
|
||||
const isCountChange = originSongs.value.length != r.songs.length
|
||||
@@ -129,9 +128,6 @@ async function onAddedItem() {
|
||||
|
||||
const direction = ref<'normal' | 'reverse'>('normal')
|
||||
|
||||
const visiable = ref(true)
|
||||
const active = ref(true)
|
||||
let timer: any
|
||||
onMounted(() => {
|
||||
update()
|
||||
// 接收点播结果消息
|
||||
@@ -148,72 +144,151 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="cardRef" class="live-request-background" v-bind="$attrs">
|
||||
<p class="live-request-header">{{ settings.obsTitle ?? '点播' }}</p>
|
||||
<div
|
||||
ref="cardRef"
|
||||
class="live-request-background"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<p class="live-request-header">
|
||||
{{ settings.obsTitle ?? '点播' }}
|
||||
</p>
|
||||
<NDivider class="live-request-divider">
|
||||
<p class="live-request-header-count">已有 {{ activeSongs.length ?? 0 }} 条</p>
|
||||
<p class="live-request-header-count">
|
||||
已有 {{ activeSongs.length ?? 0 }} 条
|
||||
</p>
|
||||
</NDivider>
|
||||
<div class="live-request-processing-container"
|
||||
:singing="songs.findIndex((s) => s.status == SongRequestStatus.Singing) > -1" :from="singing?.from as number"
|
||||
:status="singing?.status as number">
|
||||
<div class="live-request-processing-prefix"></div>
|
||||
<div
|
||||
class="live-request-processing-container"
|
||||
:singing="songs.findIndex((s) => s.status == SongRequestStatus.Singing) > -1"
|
||||
:from="singing?.from as number"
|
||||
:status="singing?.status as number"
|
||||
>
|
||||
<div class="live-request-processing-prefix" />
|
||||
<template v-if="singing">
|
||||
<img class="live-request-processing-avatar" :src="singing?.user?.face" referrerpolicy="no-referrer" />
|
||||
<p class="live-request-processing-song-name">{{ singing?.songName }}</p>
|
||||
<p class="live-request-processing-name">{{ singing?.user?.name }}</p>
|
||||
<img
|
||||
class="live-request-processing-avatar"
|
||||
:src="singing?.user?.face"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
<p class="live-request-processing-song-name">
|
||||
{{ singing?.songName }}
|
||||
</p>
|
||||
<p class="live-request-processing-name">
|
||||
{{ singing?.user?.name }}
|
||||
</p>
|
||||
</template>
|
||||
<div v-else class="live-request-processing-empty">暂无</div>
|
||||
<div class="live-request-processing-suffix"></div>
|
||||
<div
|
||||
v-else
|
||||
class="live-request-processing-empty"
|
||||
>
|
||||
暂无
|
||||
</div>
|
||||
<div class="live-request-processing-suffix" />
|
||||
</div>
|
||||
<div class="live-request-content" ref="listContainerRef">
|
||||
<div
|
||||
ref="listContainerRef"
|
||||
class="live-request-content"
|
||||
>
|
||||
<template v-if="activeSongs.length > 0">
|
||||
<Vue3Marquee class="live-request-list" :key="key" vertical :duration="20" :pause="!isMoreThanContainer"
|
||||
:style="`height: ${height}px;width: ${width}px;`">
|
||||
<div class="live-request-list-item" :from="song.from as number" :status="song.status as number"
|
||||
v-for="(song, index) in activeSongs" :key="song.id" :style="`height: ${itemHeight}px`">
|
||||
<div class="live-request-list-item-index" :index="index + 1">
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
class="live-request-list"
|
||||
vertical
|
||||
:duration="20"
|
||||
:pause="!isMoreThanContainer"
|
||||
:style="`height: ${height}px;width: ${width}px;`"
|
||||
>
|
||||
<div
|
||||
v-for="(song, index) in activeSongs"
|
||||
:key="song.id"
|
||||
class="live-request-list-item"
|
||||
:from="song.from as number"
|
||||
:status="song.status as number"
|
||||
:style="`height: ${itemHeight}px`"
|
||||
>
|
||||
<div
|
||||
class="live-request-list-item-index"
|
||||
:index="index + 1"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div class="live-request-list-item-song-name">
|
||||
{{ song.songName }}
|
||||
</div>
|
||||
<p v-if="settings.showUserName" class="live-request-list-item-name">
|
||||
<p
|
||||
v-if="settings.showUserName"
|
||||
class="live-request-list-item-name"
|
||||
>
|
||||
{{ song.from == SongRequestFrom.Manual ? '主播添加' : song.user?.name }}
|
||||
</p>
|
||||
<div v-if="settings.showFanMadelInfo" class="live-request-list-item-level"
|
||||
:has-level="(song.user?.fans_medal_level ?? 0) > 0">
|
||||
<div
|
||||
v-if="settings.showFanMadelInfo"
|
||||
class="live-request-list-item-level"
|
||||
:has-level="(song.user?.fans_medal_level ?? 0) > 0"
|
||||
>
|
||||
{{ `${song.user?.fans_medal_name} ${song.user?.fans_medal_level}` }}
|
||||
</div>
|
||||
</div>
|
||||
<NDivider v-if="isMoreThanContainer" class="live-request-footer-divider" style="margin: 10px 0 10px 0" />
|
||||
<NDivider
|
||||
v-if="isMoreThanContainer"
|
||||
class="live-request-footer-divider"
|
||||
style="margin: 10px 0 10px 0"
|
||||
/>
|
||||
</Vue3Marquee>
|
||||
</template>
|
||||
<div v-else style="position: relative; top: 20%">
|
||||
<NEmpty class="live-request-empty" description="暂无人点播" />
|
||||
<div
|
||||
v-else
|
||||
style="position: relative; top: 20%"
|
||||
>
|
||||
<NEmpty
|
||||
class="live-request-empty"
|
||||
description="暂无人点播"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="live-request-footer" v-if="settings.showRequireInfo" ref="footerRef">
|
||||
<Vue3Marquee :key="key" ref="footerListRef" class="live-request-footer-marquee" :duration="10"
|
||||
animate-on-overflow-only>
|
||||
<span class="live-request-tag" type="prefix">
|
||||
<div
|
||||
v-if="settings.showRequireInfo"
|
||||
ref="footerRef"
|
||||
class="live-request-footer"
|
||||
>
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
ref="footerListRef"
|
||||
class="live-request-footer-marquee"
|
||||
:duration="10"
|
||||
animate-on-overflow-only
|
||||
>
|
||||
<span
|
||||
class="live-request-tag"
|
||||
type="prefix"
|
||||
>
|
||||
<div class="live-request-tag-key">前缀</div>
|
||||
<div class="live-request-tag-value">
|
||||
{{ settings.orderPrefix }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="live-request-tag" type="prefix">
|
||||
<span
|
||||
class="live-request-tag"
|
||||
type="prefix"
|
||||
>
|
||||
<div class="live-request-tag-key">允许</div>
|
||||
<div class="live-request-tag-value">
|
||||
{{ settings.allowAllDanmaku ? '所有弹幕' : allowGuardTypes.length > 0 ? allowGuardTypes.join(',') : '无' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="live-request-tag" type="sc">
|
||||
<span
|
||||
class="live-request-tag"
|
||||
type="sc"
|
||||
>
|
||||
<div class="live-request-tag-key">SC点歌</div>
|
||||
<div class="live-request-tag-value">
|
||||
{{ settings.allowSC ? '> ¥' + settings.scMinPrice : '不允许' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="live-request-tag" type="fan-madel">
|
||||
<span
|
||||
class="live-request-tag"
|
||||
type="fan-madel"
|
||||
>
|
||||
<div class="live-request-tag-key">粉丝牌</div>
|
||||
<div class="live-request-tag-value">
|
||||
{{
|
||||
|
||||
@@ -55,7 +55,7 @@ const songs = computed(() => {
|
||||
}
|
||||
}
|
||||
if (settings.value.isReverse) {
|
||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||
|
||||
return result.Reverse().ToArray()
|
||||
} else {
|
||||
return result.ToArray()
|
||||
@@ -124,36 +124,78 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<NMessageProvider :to="cardRef" />
|
||||
<div ref="cardRef" class="live-request-background" v-bind="$attrs">
|
||||
<p class="live-request-header">{{ settings.obsTitleToday ?? '今日已唱' }}</p>
|
||||
<div
|
||||
ref="cardRef"
|
||||
class="live-request-background"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<p class="live-request-header">
|
||||
{{ settings.obsTitleToday ?? '今日已唱' }}
|
||||
</p>
|
||||
<NDivider class="live-request-divider">
|
||||
<p class="live-request-header-count">{{ songs.length ?? 0 }} 条</p>
|
||||
<p class="live-request-header-count">
|
||||
{{ songs.length ?? 0 }} 条
|
||||
</p>
|
||||
</NDivider>
|
||||
<div class="live-request-content" ref="listContainerRef">
|
||||
<div
|
||||
ref="listContainerRef"
|
||||
class="live-request-content"
|
||||
>
|
||||
<template v-if="songs.length > 0">
|
||||
<Vue3Marquee class="live-request-list" :key="key" vertical :duration="20" :pause="!isMoreThanContainer"
|
||||
:style="`height: ${height}px;width: ${width}px;`">
|
||||
<div class="live-request-list-item" :from="song.from as number" :status="song.status as number"
|
||||
v-for="(song, index) in songs" :key="song.id" :style="`height: ${itemHeight}px`">
|
||||
<div class="live-request-list-item-index" :index="index + 1">
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
class="live-request-list"
|
||||
vertical
|
||||
:duration="20"
|
||||
:pause="!isMoreThanContainer"
|
||||
:style="`height: ${height}px;width: ${width}px;`"
|
||||
>
|
||||
<div
|
||||
v-for="(song, index) in songs"
|
||||
:key="song.id"
|
||||
class="live-request-list-item"
|
||||
:from="song.from as number"
|
||||
:status="song.status as number"
|
||||
:style="`height: ${itemHeight}px`"
|
||||
>
|
||||
<div
|
||||
class="live-request-list-item-index"
|
||||
:index="index + 1"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div class="live-request-list-item-song-name">
|
||||
{{ song.songName }}
|
||||
</div>
|
||||
<p v-if="settings.showUserName" class="live-request-list-item-name">
|
||||
<p
|
||||
v-if="settings.showUserName"
|
||||
class="live-request-list-item-name"
|
||||
>
|
||||
{{ song.from == SongRequestFrom.Manual ? '主播添加' : song.user?.name }}
|
||||
</p>
|
||||
<div v-if="settings.showFanMadelInfo" class="live-request-list-item-level"
|
||||
:has-level="(song.user?.fans_medal_level ?? 0) > 0">
|
||||
<div
|
||||
v-if="settings.showFanMadelInfo"
|
||||
class="live-request-list-item-level"
|
||||
:has-level="(song.user?.fans_medal_level ?? 0) > 0"
|
||||
>
|
||||
{{ `${song.user?.fans_medal_name} ${song.user?.fans_medal_level}` }}
|
||||
</div>
|
||||
</div>
|
||||
<NDivider v-if="isMoreThanContainer" class="live-request-footer-divider" style="margin: 10px 0 10px 0" />
|
||||
<NDivider
|
||||
v-if="isMoreThanContainer"
|
||||
class="live-request-footer-divider"
|
||||
style="margin: 10px 0 10px 0"
|
||||
/>
|
||||
</Vue3Marquee>
|
||||
</template>
|
||||
<div v-else style="position: relative; top: 20%">
|
||||
<NEmpty class="live-request-empty" description="今日暂无" />
|
||||
<div
|
||||
v-else
|
||||
style="position: relative; top: 20%"
|
||||
>
|
||||
<NEmpty
|
||||
class="live-request-empty"
|
||||
description="今日暂无"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -59,15 +59,11 @@ const isMoreThanContainer = computed(() => {
|
||||
return originSongs.value.waiting.length * itemHeight > height.value
|
||||
})
|
||||
async function update() {
|
||||
if (!visiable.value || !active.value) return
|
||||
const r = await get()
|
||||
if (r) {
|
||||
originSongs.value = r
|
||||
}
|
||||
}
|
||||
const visiable = ref(true)
|
||||
const active = ref(true)
|
||||
let timer: any
|
||||
onMounted(() => {
|
||||
update()
|
||||
window.$mitt.on('onOBSComponentUpdate', () => {
|
||||
@@ -80,31 +76,69 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="music-request-background" v-bind="$attrs">
|
||||
<p class="music-request-header">点歌</p>
|
||||
<div
|
||||
class="music-request-background"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<p class="music-request-header">
|
||||
点歌
|
||||
</p>
|
||||
<NDivider class="music-request-divider">
|
||||
<p class="music-request-header-count">已有 {{ originSongs.waiting.length ?? 0 }} 首</p>
|
||||
<p class="music-request-header-count">
|
||||
已有 {{ originSongs.waiting.length ?? 0 }} 首
|
||||
</p>
|
||||
</NDivider>
|
||||
<div class="music-request-singing-container" :playing="originSongs.playing ? 'true' : 'false'"
|
||||
:from="originSongs.playing?.music.from ?? -1">
|
||||
<div class="music-request-singing-prefix"></div>
|
||||
<div
|
||||
class="music-request-singing-container"
|
||||
:playing="originSongs.playing ? 'true' : 'false'"
|
||||
:from="originSongs.playing?.music.from ?? -1"
|
||||
>
|
||||
<div class="music-request-singing-prefix" />
|
||||
<template v-if="originSongs.playing">
|
||||
<img class="music-request-singing-avatar"
|
||||
<img
|
||||
class="music-request-singing-avatar"
|
||||
:src="originSongs.playing.music.cover ?? AVATAR_URL + originSongs.playing.from?.uid"
|
||||
referrerpolicy="no-referrer" />
|
||||
<p class="music-request-singing-song-name">{{ originSongs.playing.music.name }}</p>
|
||||
<p class="music-request-singing-name">{{ originSongs.playing.from?.name }}</p>
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
<p class="music-request-singing-song-name">
|
||||
{{ originSongs.playing.music.name }}
|
||||
</p>
|
||||
<p class="music-request-singing-name">
|
||||
{{ originSongs.playing.from?.name }}
|
||||
</p>
|
||||
</template>
|
||||
<div v-else class="music-request-singing-empty">暂无点歌</div>
|
||||
<div class="music-request-singing-suffix"></div>
|
||||
<div
|
||||
v-else
|
||||
class="music-request-singing-empty"
|
||||
>
|
||||
暂无点歌
|
||||
</div>
|
||||
<div class="music-request-singing-suffix" />
|
||||
</div>
|
||||
<div class="music-request-content" ref="listContainerRef">
|
||||
<div
|
||||
ref="listContainerRef"
|
||||
class="music-request-content"
|
||||
>
|
||||
<template v-if="originSongs.waiting.length > 0">
|
||||
<Vue3Marquee class="music-request-list" :key="key" vertical :pause="!isMoreThanContainer" :duration="20"
|
||||
:style="`height: ${height}px;width: ${width}px;`">
|
||||
<span class="music-request-list-item" :from="item.music.from as number"
|
||||
v-for="(item, index) in originSongs.waiting" :key="item.music.id" :style="`height: ${itemHeight}px`">
|
||||
<div class="music-request-list-item-index" :index="index + 1">
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
class="music-request-list"
|
||||
vertical
|
||||
:pause="!isMoreThanContainer"
|
||||
:duration="20"
|
||||
:style="`height: ${height}px;width: ${width}px;`"
|
||||
>
|
||||
<span
|
||||
v-for="(item, index) in originSongs.waiting"
|
||||
:key="item.music.id"
|
||||
class="music-request-list-item"
|
||||
:from="item.music.from as number"
|
||||
:style="`height: ${itemHeight}px`"
|
||||
>
|
||||
<div
|
||||
class="music-request-list-item-index"
|
||||
:index="index + 1"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div class="music-request-list-item-song-name">
|
||||
@@ -114,8 +148,14 @@ onUnmounted(() => {
|
||||
</span>
|
||||
</Vue3Marquee>
|
||||
</template>
|
||||
<div v-else style="position: relative; top: 20%">
|
||||
<NEmpty class="music-request-empty" description="暂无人点歌" />
|
||||
<div
|
||||
v-else
|
||||
style="position: relative; top: 20%"
|
||||
>
|
||||
<NEmpty
|
||||
class="music-request-empty"
|
||||
description="暂无人点歌"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -71,5 +71,9 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QuestionDisplayCard ref="cardRef" :question="question" :setting="setting" />
|
||||
<QuestionDisplayCard
|
||||
ref="cardRef"
|
||||
:question="question"
|
||||
:setting="setting"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -132,86 +132,169 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="queue-background" v-bind="$attrs">
|
||||
<p class="queue-header">排队</p>
|
||||
<div
|
||||
class="queue-background"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<p class="queue-header">
|
||||
排队
|
||||
</p>
|
||||
<NDivider class="queue-divider">
|
||||
<p class="queue-header-count">已有 {{ activeItems.length ?? 0 }} 人</p>
|
||||
<p class="queue-header-count">
|
||||
已有 {{ activeItems.length ?? 0 }} 人
|
||||
</p>
|
||||
</NDivider>
|
||||
<div class="queue-singing-container" :singing="queue.findIndex((s) => s.status == QueueStatus.Progressing) > -1"
|
||||
:from="progressing?.from as number" :status="progressing?.status as number">
|
||||
<div class="queue-singing-prefix"></div>
|
||||
<div
|
||||
class="queue-singing-container"
|
||||
:singing="queue.findIndex((s) => s.status == QueueStatus.Progressing) > -1"
|
||||
:from="progressing?.from as number"
|
||||
:status="progressing?.status as number"
|
||||
>
|
||||
<div class="queue-singing-prefix" />
|
||||
<template v-if="progressing">
|
||||
<img class="queue-singing-avatar" :src="progressing?.user?.face" referrerpolicy="no-referrer" />
|
||||
<p class="queue-singing-name">{{ progressing?.user?.name }}</p>
|
||||
<img
|
||||
class="queue-singing-avatar"
|
||||
:src="progressing?.user?.face"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
<p class="queue-singing-name">
|
||||
{{ progressing?.user?.name }}
|
||||
</p>
|
||||
</template>
|
||||
<div v-else class="queue-singing-empty">等待中</div>
|
||||
<div class="queue-singing-suffix"></div>
|
||||
<div
|
||||
v-else
|
||||
class="queue-singing-empty"
|
||||
>
|
||||
等待中
|
||||
</div>
|
||||
<div class="queue-singing-suffix" />
|
||||
</div>
|
||||
<div class="queue-content" ref="listContainerRef">
|
||||
<div
|
||||
ref="listContainerRef"
|
||||
class="queue-content"
|
||||
>
|
||||
<template v-if="activeItems.length > 0">
|
||||
<Vue3Marquee class="queue-list" :key="key" vertical :pause="!isMoreThanContainer" :duration="20"
|
||||
:style="`height: ${height}px;width: ${width}px;`">
|
||||
<span class="queue-list-item" :from="item.from as number" :status="item.status as number"
|
||||
:payment="item.giftPrice ?? 0" v-for="(item, index) in activeItems" :key="item.id"
|
||||
:style="`height: ${itemHeight}px`">
|
||||
<div class="queue-list-item-index" :index="index + 1">
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
class="queue-list"
|
||||
vertical
|
||||
:pause="!isMoreThanContainer"
|
||||
:duration="20"
|
||||
:style="`height: ${height}px;width: ${width}px;`"
|
||||
>
|
||||
<span
|
||||
v-for="(item, index) in activeItems"
|
||||
:key="item.id"
|
||||
class="queue-list-item"
|
||||
:from="item.from as number"
|
||||
:status="item.status as number"
|
||||
:payment="item.giftPrice ?? 0"
|
||||
:style="`height: ${itemHeight}px`"
|
||||
>
|
||||
<div
|
||||
class="queue-list-item-index"
|
||||
:index="index + 1"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
<div v-if="settings.showFanMadelInfo" class="queue-list-item-level"
|
||||
:has-level="(item.user?.fans_medal_level ?? 0) > 0">
|
||||
<div
|
||||
v-if="settings.showFanMadelInfo"
|
||||
class="queue-list-item-level"
|
||||
:has-level="(item.user?.fans_medal_level ?? 0) > 0"
|
||||
>
|
||||
{{ `${item.user?.fans_medal_name} ${item.user?.fans_medal_level}` }}
|
||||
</div>
|
||||
<div class="queue-list-item-user-name">
|
||||
{{ item.user?.name }}
|
||||
</div>
|
||||
<p v-if="settings.showPayment" class="queue-list-item-payment">
|
||||
<p
|
||||
v-if="settings.showPayment"
|
||||
class="queue-list-item-payment"
|
||||
>
|
||||
{{
|
||||
item.from == QueueFrom.Manual ? '主播添加' : item.giftPrice == undefined ? '无' : '¥ ' + item.giftPrice
|
||||
}}
|
||||
</p>
|
||||
</span>
|
||||
|
||||
<NDivider v-if="isMoreThanContainer" class="queue-footer-divider" style="margin: 10px 0 10px 0" />
|
||||
<NDivider
|
||||
v-if="isMoreThanContainer"
|
||||
class="queue-footer-divider"
|
||||
style="margin: 10px 0 10px 0"
|
||||
/>
|
||||
</Vue3Marquee>
|
||||
</template>
|
||||
<div v-else style="position: relative; top: 20%">
|
||||
<NEmpty class="queue-empty" description="暂无人排队" />
|
||||
<div
|
||||
v-else
|
||||
style="position: relative; top: 20%"
|
||||
>
|
||||
<NEmpty
|
||||
class="queue-empty"
|
||||
description="暂无人排队"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="queue-footer" ref="footerRef" v-if="settings.showRequireInfo">
|
||||
<Vue3Marquee :key="key" ref="footerListRef" class="queue-footer-marquee"
|
||||
:pause="footerSize.width < footerListSize.width" :duration="20">
|
||||
<span class="queue-tag" type="prefix">
|
||||
<div
|
||||
v-if="settings.showRequireInfo"
|
||||
ref="footerRef"
|
||||
class="queue-footer"
|
||||
>
|
||||
<Vue3Marquee
|
||||
:key="key"
|
||||
ref="footerListRef"
|
||||
class="queue-footer-marquee"
|
||||
:pause="footerSize.width < footerListSize.width"
|
||||
:duration="20"
|
||||
>
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="prefix"
|
||||
>
|
||||
<div class="queue-tag-key">关键词</div>
|
||||
<div class="queue-tag-value">
|
||||
{{ settings.keyword }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="queue-tag" type="prefix">
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="prefix"
|
||||
>
|
||||
<div class="queue-tag-key">允许</div>
|
||||
<div class="queue-tag-value">
|
||||
{{ settings.allowAllDanmaku ? '所有弹幕' : allowGuardTypes.length > 0 ? allowGuardTypes.join(',') : '无' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="queue-tag" type="gift">
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="gift"
|
||||
>
|
||||
<div class="queue-tag-key">通过礼物</div>
|
||||
<div class="queue-tag-value">
|
||||
{{ settings.allowGift ? '允许' : '不允许' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="queue-tag" type="gift-price">
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="gift-price"
|
||||
>
|
||||
<div class="queue-tag-key">最低价格</div>
|
||||
<div class="queue-tag-value">
|
||||
{{ settings.minGiftPrice ? '> ¥' + settings.minGiftPrice : '任意' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="queue-tag" type="gift-type">
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="gift-type"
|
||||
>
|
||||
<div class="queue-tag-key">礼物名</div>
|
||||
<div class="queue-tag-value">
|
||||
{{ settings.giftNames ? settings.giftNames.join(', ') : '无' }}
|
||||
</div>
|
||||
</span>
|
||||
<span class="queue-tag" type="fan-madel">
|
||||
<span
|
||||
class="queue-tag"
|
||||
type="fan-madel"
|
||||
>
|
||||
<div class="queue-tag-key">粉丝牌</div>
|
||||
<div class="queue-tag-value">
|
||||
{{
|
||||
|
||||
@@ -96,9 +96,12 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="web-fetcher-status" :style="{
|
||||
backgroundColor: webFetcher.isStarted ? '#6dc56d' : '#e34a4a',
|
||||
}"></div>
|
||||
<div
|
||||
class="web-fetcher-status"
|
||||
:style="{
|
||||
backgroundColor: webFetcher.isStarted ? '#6dc56d' : '#e34a4a',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user