mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-10 20:36:55 +08:00
feat: 添加更新日志功能;优化组件和状态管理;修复部分逻辑错误
This commit is contained in:
@@ -992,7 +992,7 @@
|
||||
<NIcon :component="BarChartOutline" /> {{ webfetcher.sessionEventCount?.toLocaleString() ?? 0 }}
|
||||
</NStatistic>
|
||||
<NStatistic label="已发送">
|
||||
{{ ((webfetcher.bytesSentSession ?? 0) / 1024).toFixed(2) }} KB <!-- Assuming exposed -->
|
||||
{{ ((webfetcher.bytesSentSession ?? 0) / 1024 / 1024).toFixed(2) }} Mb <!-- Assuming exposed -->
|
||||
</NStatistic>
|
||||
</NFlex>
|
||||
</NCard>
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
const webfetcher = useWebFetcher();
|
||||
|
||||
const coverRef = ref();
|
||||
const isHover = ref(false);
|
||||
const roomCover = computed(() => {
|
||||
return isHover.value ? roomInfo.value?.keyframe : roomInfo.value?.user_cover;
|
||||
});
|
||||
const { width, height } = useElementSize(coverRef);
|
||||
|
||||
function logout() {
|
||||
@@ -90,8 +94,8 @@
|
||||
<template #header>
|
||||
<NSpace align="center">
|
||||
直播状态
|
||||
<NTag :type="!accountInfo.streamerInfo?.isStreaming ? 'error' : 'success'">
|
||||
{{ !accountInfo.streamerInfo?.isStreaming ? '未直播' : '直播中' }}
|
||||
<NTag :type="roomInfo?.live_status === 1 ? 'success' : 'error'">
|
||||
{{ roomInfo?.live_status === 1 ? '直播中' : '未直播' }}
|
||||
</NTag>
|
||||
</NSpace>
|
||||
<NText
|
||||
@@ -102,13 +106,13 @@
|
||||
</NText>
|
||||
</template>
|
||||
<div
|
||||
v-if="roomInfo?.user_cover"
|
||||
v-if="roomCover"
|
||||
style="position: relative"
|
||||
>
|
||||
<div style="position: relative; width: 100%; max-width: 500px;">
|
||||
<NImage
|
||||
ref="coverRef"
|
||||
:src="roomInfo?.user_cover"
|
||||
:src="roomCover"
|
||||
style="width: 100%; opacity: 0.5; border-radius: 8px;"
|
||||
referrerpolicy="no-referrer"
|
||||
:img-props="{ referrerpolicy: 'no-referrer', style: { width: '100%' } }"
|
||||
@@ -118,6 +122,8 @@
|
||||
style="position: absolute; z-index: 1; top: 0; width: 100%; background: linear-gradient(to top, rgba(0,0,0,0.8), rgba(0,0,0,0.2), transparent)"
|
||||
:style="{ height: `${height}px`, maxWidth: '500px', cursor: 'pointer' }"
|
||||
@click="openUrl(`https://live.bilibili.com/${accountInfo.biliRoomId}`)"
|
||||
@mouseenter="isHover = true"
|
||||
@mouseleave="isHover = false"
|
||||
/>
|
||||
<NText style="position: absolute; bottom: 12px; left: 16px; z-index: 2; color: white; font-size: 18px">
|
||||
{{ roomInfo?.title }}
|
||||
|
||||
@@ -117,169 +117,160 @@ import { isTauri } from '@/data/constants';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NAlert
|
||||
v-if="!isTauri"
|
||||
type="error"
|
||||
title="错误"
|
||||
<WindowBar />
|
||||
|
||||
<div
|
||||
v-if="!isLoggedIn"
|
||||
class="login-container"
|
||||
>
|
||||
此应用在 Tauri 环境外运行,无法使用
|
||||
</NAlert>
|
||||
<template v-else>
|
||||
<WindowBar />
|
||||
|
||||
<div
|
||||
v-if="!isLoggedIn"
|
||||
class="login-container"
|
||||
<NCard
|
||||
v-if="!isLoadingAccount"
|
||||
:bordered="false"
|
||||
size="large"
|
||||
class="login-card"
|
||||
>
|
||||
<NCard
|
||||
v-if="!isLoadingAccount"
|
||||
:bordered="false"
|
||||
size="large"
|
||||
class="login-card"
|
||||
>
|
||||
<template #header>
|
||||
<div class="login-header">
|
||||
<div class="login-title">
|
||||
登陆
|
||||
</div>
|
||||
<div class="login-subtitle">
|
||||
输入你的 VTsuru Token
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<NSpace
|
||||
vertical
|
||||
size="large"
|
||||
>
|
||||
<NSpace vertical>
|
||||
<div class="token-label-container">
|
||||
<span class="token-label">Token</span>
|
||||
<NTooltip placement="top">
|
||||
<template #trigger>
|
||||
<NA
|
||||
class="token-get-link"
|
||||
@click="openUrl('https://vtsuru.suki.club/manage')"
|
||||
>
|
||||
前往获取
|
||||
</NA>
|
||||
</template>
|
||||
登录后在管理面板主页的个人信息下方
|
||||
</NTooltip>
|
||||
</div>
|
||||
<NInput
|
||||
v-model:value="token"
|
||||
type="password"
|
||||
show-password-on="click"
|
||||
placeholder="请输入Token"
|
||||
@keyup.enter="login"
|
||||
/>
|
||||
</NSpace>
|
||||
|
||||
<NButton
|
||||
block
|
||||
type="primary"
|
||||
:loading="isLoadingAccount"
|
||||
:disabled="isLoadingAccount"
|
||||
@click="login"
|
||||
>
|
||||
<template #header>
|
||||
<div class="login-header">
|
||||
<div class="login-title">
|
||||
登陆
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
</div>
|
||||
<div class="login-subtitle">
|
||||
输入你的 VTsuru Token
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<NSpin
|
||||
v-else
|
||||
<NSpace
|
||||
vertical
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<NLayout
|
||||
v-else
|
||||
has-sider
|
||||
class="main-layout"
|
||||
@vue:mounted="initAll(true)"
|
||||
>
|
||||
<NLayoutSider
|
||||
width="200"
|
||||
bordered
|
||||
class="main-layout-sider"
|
||||
>
|
||||
<div class="sider-content">
|
||||
<div class="sider-header">
|
||||
<NText
|
||||
tag="div"
|
||||
class="app-title"
|
||||
>
|
||||
<span>VTsuru.Client</span>
|
||||
</NText>
|
||||
<NTooltip trigger="hover">
|
||||
<NSpace vertical>
|
||||
<div class="token-label-container">
|
||||
<span class="token-label">Token</span>
|
||||
<NTooltip placement="top">
|
||||
<template #trigger>
|
||||
<NButton
|
||||
quaternary
|
||||
class="fetcher-status-button"
|
||||
:type="webfetcher.state === 'connected' ? 'success' : 'error'"
|
||||
<NA
|
||||
class="token-get-link"
|
||||
@click="openUrl('https://vtsuru.suki.club/manage')"
|
||||
>
|
||||
<CheckmarkCircle
|
||||
v-if="webfetcher.state === 'connected'"
|
||||
class="fetcher-status-icon connected"
|
||||
/>
|
||||
<CloseCircle
|
||||
v-else
|
||||
class="fetcher-status-icon disconnected"
|
||||
/>
|
||||
</NButton>
|
||||
前往获取
|
||||
</NA>
|
||||
</template>
|
||||
<div>
|
||||
<div>EventFetcher 状态</div>
|
||||
<div v-if="webfetcher.state === 'connected'">
|
||||
运行中
|
||||
</div>
|
||||
<div v-else>
|
||||
未运行 / 连接断开
|
||||
</div>
|
||||
</div>
|
||||
登录后在管理面板主页的个人信息下方
|
||||
</NTooltip>
|
||||
</div>
|
||||
|
||||
<NMenu
|
||||
:options="menuOptions"
|
||||
:default-value="'go-back-home'"
|
||||
class="sider-menu"
|
||||
<NInput
|
||||
v-model:value="token"
|
||||
type="password"
|
||||
show-password-on="click"
|
||||
placeholder="请输入Token"
|
||||
@keyup.enter="login"
|
||||
/>
|
||||
</div>
|
||||
</NLayoutSider>
|
||||
</NSpace>
|
||||
|
||||
<NLayoutContent
|
||||
class="main-layout-content"
|
||||
:native-scrollbar="false"
|
||||
:scrollbar-props="{
|
||||
trigger: 'none'
|
||||
}"
|
||||
>
|
||||
<div style="padding: 12px; padding-right: 15px;">
|
||||
<RouterView v-slot="{ Component }">
|
||||
<Transition
|
||||
name="fade-slide"
|
||||
mode="out-in"
|
||||
:appear="true"
|
||||
>
|
||||
<KeepAlive>
|
||||
<Suspense>
|
||||
<component :is="Component" />
|
||||
<template #fallback>
|
||||
<div class="suspense-fallback">
|
||||
加载中...
|
||||
</div>
|
||||
</template>
|
||||
</Suspense>
|
||||
</KeepAlive>
|
||||
</Transition>
|
||||
</RouterView>
|
||||
<NButton
|
||||
block
|
||||
type="primary"
|
||||
:loading="isLoadingAccount"
|
||||
:disabled="isLoadingAccount"
|
||||
@click="login"
|
||||
>
|
||||
登陆
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
|
||||
<NSpin
|
||||
v-else
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<NLayout
|
||||
v-else
|
||||
has-sider
|
||||
class="main-layout"
|
||||
@vue:mounted="initAll(true)"
|
||||
>
|
||||
<NLayoutSider
|
||||
width="200"
|
||||
bordered
|
||||
class="main-layout-sider"
|
||||
>
|
||||
<div class="sider-content">
|
||||
<div class="sider-header">
|
||||
<NText
|
||||
tag="div"
|
||||
class="app-title"
|
||||
>
|
||||
<span>VTsuru.Client</span>
|
||||
</NText>
|
||||
<NTooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<NButton
|
||||
quaternary
|
||||
class="fetcher-status-button"
|
||||
:type="webfetcher.state === 'connected' ? 'success' : 'error'"
|
||||
>
|
||||
<CheckmarkCircle
|
||||
v-if="webfetcher.state === 'connected'"
|
||||
class="fetcher-status-icon connected"
|
||||
/>
|
||||
<CloseCircle
|
||||
v-else
|
||||
class="fetcher-status-icon disconnected"
|
||||
/>
|
||||
</NButton>
|
||||
</template>
|
||||
<div>
|
||||
<div>EventFetcher 状态</div>
|
||||
<div v-if="webfetcher.state === 'connected'">
|
||||
运行中
|
||||
</div>
|
||||
<div v-else>
|
||||
未运行 / 连接断开
|
||||
</div>
|
||||
</div>
|
||||
</NTooltip>
|
||||
</div>
|
||||
</NLayoutContent>
|
||||
</NLayout>
|
||||
</template>
|
||||
|
||||
<NMenu
|
||||
:options="menuOptions"
|
||||
:default-value="'go-back-home'"
|
||||
class="sider-menu"
|
||||
/>
|
||||
</div>
|
||||
</NLayoutSider>
|
||||
|
||||
<NLayoutContent
|
||||
class="main-layout-content"
|
||||
:native-scrollbar="false"
|
||||
:scrollbar-props="{
|
||||
trigger: 'none'
|
||||
}"
|
||||
>
|
||||
<div style="padding: 12px; padding-right: 15px;">
|
||||
<RouterView v-slot="{ Component }">
|
||||
<Transition
|
||||
name="fade-slide"
|
||||
mode="out-in"
|
||||
:appear="true"
|
||||
>
|
||||
<KeepAlive>
|
||||
<Suspense>
|
||||
<component :is="Component" />
|
||||
<template #fallback>
|
||||
<div class="suspense-fallback">
|
||||
加载中...
|
||||
</div>
|
||||
</template>
|
||||
</Suspense>
|
||||
</KeepAlive>
|
||||
</Transition>
|
||||
</RouterView>
|
||||
</div>
|
||||
</NLayoutContent>
|
||||
</NLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -333,6 +333,9 @@ watch(minimizeOnStart, (newValue) => {
|
||||
Tauri 客户端
|
||||
</NButton>
|
||||
</p>
|
||||
<p>
|
||||
反馈: 🐧 873260337
|
||||
</p>
|
||||
<!-- Add more about info -->
|
||||
</NCard>
|
||||
</template>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { info, error } from '@tauri-apps/plugin-log';
|
||||
import { QueryBiliAPI } from './utils'; // 假设 Bili API 工具路径
|
||||
import { BiliRoomInfo, BiliStreamingInfo, FetcherStatisticData } from './models'; // 假设模型路径
|
||||
import { useTauriStore } from '../store/useTauriStore';
|
||||
import { useAccount } from '@/api/account';
|
||||
// import { useAccount } from '@/api/account'; // 如果需要账户信息
|
||||
|
||||
// const accountInfo = useAccount(); // 如果需要
|
||||
@@ -185,10 +186,8 @@ export async function getHistoricalStatistics(days: number = 7): Promise<Fetcher
|
||||
* 更新房间和直播流信息
|
||||
*/
|
||||
async function updateRoomAndStreamingInfo() {
|
||||
// 需要一个房间ID来查询,这个ID可能来自设置、登录信息或固定配置
|
||||
// const roomId = accountInfo.value?.roomid ?? settings.value.roomId; // 示例:获取房间ID
|
||||
const roomId = 21484828; // !!! 示例:这里需要替换成实际获取房间ID的逻辑 !!!
|
||||
if (!roomId) {
|
||||
const account = useAccount();
|
||||
if (!account.value.biliRoomId) {
|
||||
// error("无法获取房间ID以更新直播信息");
|
||||
return;
|
||||
}
|
||||
@@ -196,7 +195,7 @@ async function updateRoomAndStreamingInfo() {
|
||||
try {
|
||||
// 查询房间基本信息
|
||||
const roomRes = await QueryBiliAPI(
|
||||
`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${roomId}`
|
||||
`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${account.value.biliRoomId}`
|
||||
);
|
||||
const json = await roomRes.json();
|
||||
if (json.code === 0) {
|
||||
|
||||
@@ -4,6 +4,18 @@ import { isPermissionGranted, onAction, sendNotification } from "@tauri-apps/plu
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import { CN_HOST } from "@/data/constants";
|
||||
|
||||
export function onReceivedNotification(type: string, data: any) {
|
||||
switch (type) {
|
||||
case 'question-box':
|
||||
|
||||
onReceivedQuestion(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`Unhandled notification type: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function onReceivedQuestion(question: QAInfo) {
|
||||
const setting = useSettings();
|
||||
if (setting.settings.notificationSettings.enableTypes.includes("question-box")) {
|
||||
@@ -20,7 +32,7 @@ export async function onReceivedQuestion(question: QAInfo) {
|
||||
silent: false,
|
||||
extra: { type: 'question-box' },
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user