diff --git a/src/client/ClientSettings.vue b/src/client/ClientSettings.vue
index 367b80c..3014c81 100644
--- a/src/client/ClientSettings.vue
+++ b/src/client/ClientSettings.vue
@@ -240,7 +240,7 @@ import { invoke } from '@tauri-apps/api/core';
:bordered="false"
>
- 暂未完成
+ 未完全完成
@@ -262,6 +262,14 @@ import { invoke } from '@tauri-apps/api/core';
+
+
+
+
+
import { isPermissionGranted, onAction, sendNotification } from '@tauri-apps/plugin-notification';
+ import { NSwitch } from 'naive-ui';
+import { useSettings } from './store/useSettings';
+import { onReceivedQuestion } from './data/notification';
+import { QAInfo } from '@/api/api-models';
+ const setting = useSettings()
async function testNotification() {
- let permissionGranted = await isPermissionGranted();
- if (permissionGranted) {
- sendNotification({
- title: "测试通知",
- body: "这是一个测试通知",
- silent: false,
- extra: { type: 'test' },
- });
- onAction((event) => {
- console.log('Notification clicked:', event);
- });
- }
+ onReceivedQuestion({
+ id: 1,
+ question: {
+ message: '这是一条测试问题',
+ },
+ tag: '测试标签',
+ sender: { name: '测试用户', id: 1, isBiliAuthed: false },
+ isPublic: true,
+ } as QAInfo);
}
@@ -26,6 +28,12 @@ async function testNotification() {
>
测试通知
+
+
+
\ No newline at end of file
diff --git a/src/client/data/initialize.ts b/src/client/data/initialize.ts
index b43ecd1..2f44092 100644
--- a/src/client/data/initialize.ts
+++ b/src/client/data/initialize.ts
@@ -29,20 +29,9 @@ export async function initAll(isOnBoot: boolean) {
if (clientInited.value) {
return;
}
- if (isOnBoot) {
- if (setting.settings.bootAsMinimized && !isDev) {
- const appWindow = getCurrentWindow();
- appWindow.hide();
- sendNotification({
- title: "VTsuru.Client",
- body: '已启动并最小化到托盘',
- silent: false,
- extra: { type: 'question-box' },
- });
- }
- }
- let permissionGranted = await isPermissionGranted();
checkUpdate();
+ const appWindow = getCurrentWindow();
+ let permissionGranted = await isPermissionGranted();
// If not we need to request it
if (!permissionGranted) {
@@ -51,7 +40,16 @@ export async function initAll(isOnBoot: boolean) {
if (permissionGranted) {
info('Notification permission granted');
}
+ }
+ if (isOnBoot) {
+ if (setting.settings.bootAsMinimized && !isDev && await appWindow.isVisible()) {
+ appWindow.hide();
+ sendNotification({
+ title: "VTsuru.Client",
+ body: '已启动并最小化到托盘'
+ });
+ }
}
initNotificationHandler();
const detach = await attachConsole();
@@ -64,7 +62,7 @@ export async function initAll(isOnBoot: boolean) {
initInfo();
info('[init] 开始更新数据');
- if (isLoggedIn && accountInfo.value.isBiliVerified) {
+ if (isLoggedIn && accountInfo.value.isBiliVerified && !setting.settings.dev_disableDanmakuClient) {
const danmakuInitNoticeRef = window.$notification.info({
title: '正在初始化弹幕客户端...',
closable: false
@@ -96,7 +94,6 @@ export async function initAll(isOnBoot: boolean) {
],
});
const iconData = await (await fetch('https://oss.suki.club/vtsuru/icon.ico')).arrayBuffer();
- const appWindow = getCurrentWindow();
const options: TrayIconOptions = {
// here you can add a tray menu, title, tooltip, event handler, etc
menu: menu,
diff --git a/src/client/data/notification.ts b/src/client/data/notification.ts
index 5e54ae6..3a5b909 100644
--- a/src/client/data/notification.ts
+++ b/src/client/data/notification.ts
@@ -1,16 +1,28 @@
-import { QAInfo } from "@/api/api-models";
+import { QAInfo, ResponsePointGoodModel, ResponsePointOrder2OwnerModel } from "@/api/api-models";
import { useSettings } from "../store/useSettings";
-import { isPermissionGranted, onAction, sendNotification } from "@tauri-apps/plugin-notification";
+import { isPermissionGranted, onAction, Options, sendNotification } from "@tauri-apps/plugin-notification";
import { openUrl } from "@tauri-apps/plugin-opener";
import { CN_HOST } from "@/data/constants";
+import { NButton, NFlex } from "naive-ui";
+import QuestionItem from "@/components/QuestionItem.vue";
-export function onReceivedNotification(type: string, data: any) {
+export async function trySendNotification(option: Options) {
+ let permissionGranted = await isPermissionGranted();
+ if (permissionGranted) {
+ sendNotification(option);
+ }
+}
+
+export function onReceivedNotification(type: string, json: string) {
+ console.log(`接收到通知: ${type}`, json);
+ const data = JSON.parse(json);
switch (type) {
case 'question-box':
-
onReceivedQuestion(data);
break;
-
+ case 'goods-buy':
+ onGoodsBuy(data);
+ break;
default:
console.warn(`Unhandled notification type: ${type}`);
}
@@ -20,20 +32,57 @@ export async function onReceivedQuestion(question: QAInfo) {
const setting = useSettings();
if (setting.settings.notificationSettings.enableTypes.includes("question-box")) {
window.$notification.info({
- title: "收到提问",
- description: '收到来自 [' + question.sender.name || '匿名用户' + '] 的提问',
- duration: 5,
+ title: "提问箱",
+ description: '收到来自 [' + (question.sender.name || '匿名用户') + '] 的提问',
+ duration: 0,
+ action: () => h(NFlex, {}, () => [
+ h(NButton, {
+ text: true, type: 'info', onClick: () => {
+ window.$modal.create({
+ title: '快速查看',
+ preset: 'card',
+ style: { maxWidth: '80vw' },
+ content: () => h(QuestionItem, { item: question }),
+ });
+ }
+ }, () => '快速查看'),
+ h(NButton, {
+ text: true, type: 'primary', onClick: () => {
+ openUrl(`${CN_HOST}manage/question-box`);
+ }
+ }, () => '查看详情'),
+ ])
+ });
+ trySendNotification({
+ title: "提问箱",
+ body: '收到来自 [' + (question.sender.name || '匿名用户') + '] 的提问',
+ extra: { type: 'question-box' },
});
- let permissionGranted = await isPermissionGranted();
- if (permissionGranted) {
- sendNotification({
- title: "收到提问",
- body: '来自 [' + question.sender.name || '匿名用户' + '] 的提问',
- silent: false,
- extra: { type: 'question-box' },
- });
-
- }
}
+}
+export function onGoodsBuy(info: {
+ data: ResponsePointOrder2OwnerModel,
+ goods: ResponsePointGoodModel
+}) {
+ const setting = useSettings();
+ const order = info.data;
+ const goods = info.goods;
+ if (setting.settings.notificationSettings.enableTypes.includes("goods-buy")) {
+ window.$notification.info({
+ title: "礼物兑换",
+ description: `${order.customer.name} 兑换了你的 [${goods.name}],数量: ${order.count},总价: ${order.point} 元`,
+ duration: 0,
+ action: () => h(NButton, {
+ text: true, type: 'primary', onClick: () => {
+ openUrl(`${CN_HOST}manage/goods-buy`);
+ }
+ }, () => '查看详情'),
+ });
+ trySendNotification({
+ title: "礼物兑换",
+ body: `${order.customer.name} 兑换了你的 [${goods.name}],数量: ${order.count},总价: ${order.point} 元`,
+ extra: { type: 'goods-buy' },
+ });
+ }
}
\ No newline at end of file
diff --git a/src/client/store/useSettings.ts b/src/client/store/useSettings.ts
index 3a0065d..26a5c7d 100644
--- a/src/client/store/useSettings.ts
+++ b/src/client/store/useSettings.ts
@@ -1,6 +1,6 @@
import { useTauriStore } from './useTauriStore';
-export type NotificationType = 'question-box' | 'danmaku';
+export type NotificationType = 'question-box' | 'danmaku' | 'goods-buy';
export type NotificationSettings = {
enableTypes: NotificationType[];
};
@@ -14,6 +14,8 @@ export type VTsuruClientSettings = {
enableNotification: boolean;
notificationSettings: NotificationSettings;
+
+ dev_disableDanmakuClient: boolean;
};
export const useSettings = defineStore('settings', () => {
@@ -29,6 +31,8 @@ export const useSettings = defineStore('settings', () => {
notificationSettings: {
enableTypes: ['question-box', 'danmaku'],
},
+
+ dev_disableDanmakuClient: false,
};
const settings = ref(Object.assign({}, defaultSettings));