diff --git a/.editorconfig b/.editorconfig index 59a6505..c6c70cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -[*.{js,jsx,ts,tsx,vue}] +[*.{js,jsx,ts,tsx,vue,vine.ts}] indent_style = space indent_size = 2 end_of_line = lf diff --git a/bun.lockb b/bun.lockb index 508439b..2d44731 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 2e3f4b4..9e76056 100644 --- a/package.json +++ b/package.json @@ -11,32 +11,33 @@ }, "dependencies": { "@antfu/ni": "^24.3.0", + "@guolao/vue-monaco-editor": "^1.5.5", "@hyperdx/browser": "^0.21.2", "@hyperdx/cli": "^0.1.0", "@microsoft/signalr": "^8.0.7", "@microsoft/signalr-protocol-msgpack": "^8.0.7", "@mixer/postmessage-rpc": "^1.1.4", "@oneidentity/zstd-js": "^1.0.3", - "@tauri-apps/api": "^2.4.0", + "@tauri-apps/api": "^2.5.0", "@tauri-apps/plugin-autostart": "^2.3.0", - "@tauri-apps/plugin-http": "^2.4.2", - "@tauri-apps/plugin-log": "^2.3.1", + "@tauri-apps/plugin-http": "^2.4.3", + "@tauri-apps/plugin-log": "^2.4.0", "@tauri-apps/plugin-notification": "^2.2.2", "@tauri-apps/plugin-opener": "^2.2.6", "@tauri-apps/plugin-os": "^2.2.1", "@tauri-apps/plugin-process": "^2.2.1", "@tauri-apps/plugin-store": "^2.2.0", - "@tauri-apps/plugin-updater": "^2.7.0", + "@tauri-apps/plugin-updater": "^2.7.1", "@types/crypto-js": "^4.2.2", "@types/md5": "^2.3.5", - "@typescript-eslint/eslint-plugin": "^8.27.0", + "@typescript-eslint/eslint-plugin": "^8.31.0", "@vicons/fluent": "^0.13.0", "@vitejs/plugin-basic-ssl": "^2.0.0", "@vitejs/plugin-vue": "^5.2.3", "@vue/cli": "^5.0.8", - "@vueuse/core": "^13.0.0", + "@vueuse/core": "^13.1.0", "@vueuse/integrations": "^13.1.0", - "@vueuse/router": "^13.0.0", + "@vueuse/router": "^13.1.0", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.12", "bilibili-live-ws": "^6.3.1", @@ -46,32 +47,32 @@ "easy-speech": "^2.4.0", "echarts": "^5.6.0", "eslint-plugin-import": "^2.31.0", - "eslint-plugin-oxlint": "^0.16.2", - "eslint-plugin-prettier": "^5.2.4", - "fast-xml-parser": "^5.0.9", + "eslint-plugin-oxlint": "^0.16.7", + "eslint-plugin-prettier": "^5.2.6", + "fast-xml-parser": "^5.2.1", "file-saver": "^2.0.5", "grapheme-splitter": "^1.0.4", "html2canvas": "^1.4.1", - "idb-keyval": "^6", + "idb-keyval": "^6.2.1", "linqts": "^2.0.0", "md5": "^2.3.0", "mitt": "^3.0.1", "monaco-editor": "^0.52.2", "music-metadata-browser": "^2.5.11", "nanoid": "^5.1.5", - "oxlint": "^0.16.2", + "oxlint": "^0.16.7", "peerjs": "^1.5.4", - "pinia": "^3.0.1", + "pinia": "^3.0.2", "prettier": "^3.5.3", "qrcode.vue": "^3.6.0", "queue-typescript": "^1.0.1", - "unplugin-auto-import": "^19.1.1", - "unplugin-vue-components": "^28.4.1", + "unplugin-auto-import": "^19.1.2", + "unplugin-vue-components": "^28.5.0", "unplugin-vue-markdown": "^28.3.1", "uuid": "^11.1.0", - "vite": "6.2.2", + "vite": "6.3.3", "vite-plugin-monaco-editor": "^1.1.0", - "vite-plugin-oxlint": "^1.3.0", + "vite-plugin-oxlint": "^1.3.1", "vite-svg-loader": "^5.1.0", "vue": "3.5.13", "vue-echarts": "^7.0.3", @@ -81,28 +82,28 @@ "vue3-aplayer": "^1.7.3", "vue3-marquee": "^4.2.2", "vueuc": "^0.4.64", - "worker-timers": "^8.0.19", + "worker-timers": "^8.0.20", "xlsx": "^0.18.5" }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", - "@types/bun": "^1.2.5", + "@types/bun": "^1.2.10", "@types/eslint": "^9.6.1", "@types/file-saver": "^2.0.7", "@types/obs-studio": "^2.17.2", "@types/uuid": "^10.0.0", - "@typescript-eslint/parser": "^8.27.0", + "@typescript-eslint/parser": "^8.31.0", "@vicons/ionicons5": "^0.13.0", "@vitejs/plugin-vue-jsx": "^4.1.2", "@vue-vine/eslint-config": "^0.2.19", "@vue/eslint-config-typescript": "^14.5.0", - "eslint": "^9.23.0", - "eslint-config-prettier": "^10.1.1", + "eslint": "^9.25.1", + "eslint-config-prettier": "^10.1.2", "eslint-plugin-vue": "^10.0.0", - "knip": "^5.50.4", + "knip": "^5.50.5", "naive-ui": "^2.41.0", "stylus": "^0.64.0", "typescript": "^5.8.3", - "vue-vine": "^0.3.19" + "vue-vine": "^0.3.21" } } diff --git a/src/App.vue b/src/App.vue index 56594f9..98087e5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -124,7 +124,7 @@ :root { font-feature-settings: 'liga' 1, 'calt' 1; --vtsuru-header-height: 50px; - --vtsuru-content-padding: 16px; + --vtsuru-content-padding: 12px; } @supports (font-variation-settings: normal) { diff --git a/src/api/account.ts b/src/api/account.ts index 44220aa..a02fbac 100644 --- a/src/api/account.ts +++ b/src/api/account.ts @@ -254,6 +254,22 @@ export async function UploadConfig(name: string, data: unknown) { } return false; } +export async function GetConfigHash(name: string) { + try { + const resp = await QueryGetAPI(VTSURU_API_URL + 'get-config-hash', { + name: name + }); + if (resp.code == 200) { + return resp.data; + } else { + console.error(`获取配置文件hash失败: ` + resp.message); + return null; + } + } catch (err) { + console.error(`获取配置文件hash失败: ` + err); + return null; + } +} export async function EnableFunction(func: FunctionTypes) { if (ACCOUNT.value) { if (ACCOUNT.value.settings.enableFunctions.includes(func)) { diff --git a/src/api/api-models.ts b/src/api/api-models.ts index 76b1557..3a1bf2f 100644 --- a/src/api/api-models.ts +++ b/src/api/api-models.ts @@ -717,6 +717,7 @@ export interface BiliAuthBaseModel { export interface BiliAuthModel extends BiliAuthBaseModel { address?: AddressInfo[] token: string + guardInfo: Record } export interface ResponsePointUserModel { point: number diff --git a/src/assets/css/youtube/yt-html.css b/src/assets/css/youtube/yt-html.css index 75dc6fc..870b4c9 100644 --- a/src/assets/css/youtube/yt-html.css +++ b/src/assets/css/youtube/yt-html.css @@ -1,362 +1,366 @@ -html:not(.style-scope) { - --yt-live-chat-background-color: hsl(0, 0%, 100%); - --yt-live-chat-action-panel-background-color: hsla(0, 0%, 93.3%, .4); - --yt-live-chat-action-panel-background-color-transparent: hsla(0, 0%, 97%, .8); - --yt-live-chat-mode-change-background-color: hsla(0, 0%, 93.3%, .4); - --yt-live-chat-primary-text-color: hsl(0, 0%, 6.7%); - --yt-live-chat-secondary-text-color: hsla(0, 0%, 6.7%, .6); - --yt-live-chat-tertiary-text-color: hsla(0, 0%, 6.7%, .4); - --yt-live-chat-text-input-field-inactive-underline-color: #b8b8b8; - --yt-live-chat-text-input-field-placeholder-color: hsla(0, 0%, 6.7%, .6); - --yt-live-chat-icon-button-color: hsla(0, 0%, 6.7%, .4); - --yt-live-chat-enabled-send-button-color: #4285f4; - --yt-live-chat-disabled-icon-button-color: hsla(0, 0%, 6.7%, .2); - --yt-live-chat-picker-button-color: hsla(0, 0%, 6.7%, .4); - --yt-live-chat-picker-button-active-color: hsla(0, 0%, 6.7%, .8); - --yt-live-chat-picker-button-disabled-color: var(--yt-live-chat-disabled-icon-button-color); - --yt-live-chat-picker-button-hover-color: hsla(0, 0%, 6.7%, .6); - --yt-live-chat-mention-background-color: #ff5722; - --yt-live-chat-mention-text-color: hsl(0, 0%, 100%); - --yt-live-chat-deleted-message-color: rgba(0, 0, 0, .5); - --yt-live-chat-deleted-message-bar-color: rgba(11, 11, 11, .2); - --yt-live-chat-disabled-button-background-color: hsl(0, 0%, 93.3%); - --yt-live-chat-disabled-button-text-color: hsla(0, 0%, 6.7%, .4); - --yt-live-chat-sub-panel-background-color: hsl(0, 0%, 93.3%); - --yt-live-chat-sub-panel-background-color-transparent: hsla(0, 0%, 93%, .7); - --yt-live-chat-header-background-color: hsla(0, 0%, 93.3%, .4); - --yt-live-chat-header-button-color: hsl(0, 0%, 6.7%); - --yt-live-chat-error-message-color: hsl(10, 51%, 49%); - --yt-live-chat-reconnect-message-color: hsla(0, 0%, 7%, 0.2); - --yt-live-chat-moderator-color: hsl(225, 84%, 66%); - --yt-live-chat-owner-color: hsl(40, 76%, 55%); - --yt-live-chat-author-chip-owner-text-color: rgba(0,0,0,0.87); - --yt-live-chat-author-chip-verified-background-color: #CCCCCC; - --yt-live-chat-author-chip-verified-text-color: #606060; - --yt-live-chat-message-highlight-background-color: #f8f8f8; - --yt-live-chat-sponsor-color: #107516; - --yt-live-chat-overlay-color: hsla(0, 0%, 0%, 0.6); - --yt-live-chat-dialog-background-color: hsl(0, 0%, 100%); - --yt-live-chat-dialog-text-color: hsla(0, 0%, 6.7%, .6); - --yt-live-chat-poll-choice-text-color: var(--yt-spec-text-secondary); - --yt-live-chat-poll-choice-border-color: var(--yt-spec-10-percent-layer); - --yt-live-chat-poll-choice-vote-bar-background-color: hsla(0, 0%, 93.3%, .8); - --yt-live-chat-poll-choice-vote-bar-background-color-selected: #F2F8FF; - --yt-live-chat-poll-choice-color-selected: #065FD4; - --yt-live-chat-moderation-mode-hover-background-color: hsla(0, 0%, 6.7%, .2); - --yt-live-chat-additional-inline-action-button-color: hsl(0, 0%, 100%); - --yt-live-chat-additional-inline-action-button-background-color: hsla(0, 0%, 26%, 0.8); - --yt-live-chat-additional-inline-action-button-background-color-hover: hsla(0, 0%, 26%, 1.0); - --yt-formatted-string-emoji-size: 24px; - --yt-live-chat-emoji-size: 24px; - --yt-live-chat-text-input-field-suggestion-background-color: hsl(0, 0%, 100%); - --yt-live-chat-text-input-field-suggestion-background-color-hover: #eee; - --yt-live-chat-text-input-field-suggestion-text-color: #666; - --yt-live-chat-text-input-field-suggestion-text-color-hover: #333; - --yt-live-chat-ticker-arrow-background: hsl(0, 0%, 97.3%); - --yt-emoji-picker-category-background-color: var(--yt-live-chat-action-panel-background-color-transparent); - --yt-emoji-picker-category-color: var(--yt-live-chat-secondary-text-color); - --yt-emoji-picker-category-button-color: var(--yt-live-chat-picker-button-color); - --yt-emoji-picker-search-background-color: hsla(0, 0%, 100%, .6); - --yt-emoji-picker-search-color: hsla(0, 0%, 6.7%, .8); - --yt-emoji-picker-search-placeholder-color: hsla(0, 0%, 6.7%, .6); - --yt-live-chat-slider-active-color: #2196f3; - --yt-live-chat-slider-container-color: #c8c8c8; - --yt-live-chat-slider-markers-color: #505050; - --yt-live-chat-toast-background-color: hsl(0, 0%, 20%); - --yt-live-chat-toast-text-color: hsl(0, 0%, 100%); - --yt-live-chat-automod-button-background-color: hsl(0, 0%, 93.3%); - --yt-live-chat-automod-button-background-color-hover: hsla(0, 0%, 6.7%, .2); - --yt-live-chat-countdown-opacity: 0.3; - --yt-live-chat-shimmer-background-color: rgba(136, 136, 136, 0.2); - --yt-live-chat-shimmer-linear-gradient: linear-gradient(0deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 65%); - --yt-live-chat-vem-background-color: hsl(0, 0%, 93.3%); - --yt-live-chat-upsell-dialog-renderer-button-padding: 10px 16px; - --yt-live-chat-product-picker-icon-color: rgba(17, 17, 17, 0.6); - --yt-live-chat-product-picker-hover-color: rgba(17, 17, 16, 0.1); - --yt-live-chat-product-picker-disabled-icon-color: rgba(17, 17, 17, 0.4); - --yt-pdg-paid-stickers-tab-selection-bar-color: #065FD4; - --yt-pdg-paid-stickers-author-name-font-size: 13px; - --yt-pdg-paid-stickers-margin-left: 38px; -} +@layer yt { -html:not(.style-scope) { - --layout_-_display: flex; - ; + html:not(.style-scope) { + --yt-live-chat-background-color: hsl(0, 0%, 100%); + --yt-live-chat-action-panel-background-color: hsla(0, 0%, 93.3%, .4); + --yt-live-chat-action-panel-background-color-transparent: hsla(0, 0%, 97%, .8); + --yt-live-chat-mode-change-background-color: hsla(0, 0%, 93.3%, .4); + --yt-live-chat-primary-text-color: hsl(0, 0%, 6.7%); + --yt-live-chat-secondary-text-color: hsla(0, 0%, 6.7%, .6); + --yt-live-chat-tertiary-text-color: hsla(0, 0%, 6.7%, .4); + --yt-live-chat-text-input-field-inactive-underline-color: #b8b8b8; + --yt-live-chat-text-input-field-placeholder-color: hsla(0, 0%, 6.7%, .6); + --yt-live-chat-icon-button-color: hsla(0, 0%, 6.7%, .4); + --yt-live-chat-enabled-send-button-color: #4285f4; + --yt-live-chat-disabled-icon-button-color: hsla(0, 0%, 6.7%, .2); + --yt-live-chat-picker-button-color: hsla(0, 0%, 6.7%, .4); + --yt-live-chat-picker-button-active-color: hsla(0, 0%, 6.7%, .8); + --yt-live-chat-picker-button-disabled-color: var(--yt-live-chat-disabled-icon-button-color); + --yt-live-chat-picker-button-hover-color: hsla(0, 0%, 6.7%, .6); + --yt-live-chat-mention-background-color: #ff5722; + --yt-live-chat-mention-text-color: hsl(0, 0%, 100%); + --yt-live-chat-deleted-message-color: rgba(0, 0, 0, .5); + --yt-live-chat-deleted-message-bar-color: rgba(11, 11, 11, .2); + --yt-live-chat-disabled-button-background-color: hsl(0, 0%, 93.3%); + --yt-live-chat-disabled-button-text-color: hsla(0, 0%, 6.7%, .4); + --yt-live-chat-sub-panel-background-color: hsl(0, 0%, 93.3%); + --yt-live-chat-sub-panel-background-color-transparent: hsla(0, 0%, 93%, .7); + --yt-live-chat-header-background-color: hsla(0, 0%, 93.3%, .4); + --yt-live-chat-header-button-color: hsl(0, 0%, 6.7%); + --yt-live-chat-error-message-color: hsl(10, 51%, 49%); + --yt-live-chat-reconnect-message-color: hsla(0, 0%, 7%, 0.2); + --yt-live-chat-moderator-color: hsl(225, 84%, 66%); + --yt-live-chat-owner-color: hsl(40, 76%, 55%); + --yt-live-chat-author-chip-owner-text-color: rgba(0, 0, 0, 0.87); + --yt-live-chat-author-chip-verified-background-color: #CCCCCC; + --yt-live-chat-author-chip-verified-text-color: #606060; + --yt-live-chat-message-highlight-background-color: #f8f8f8; + --yt-live-chat-sponsor-color: #107516; + --yt-live-chat-overlay-color: hsla(0, 0%, 0%, 0.6); + --yt-live-chat-dialog-background-color: hsl(0, 0%, 100%); + --yt-live-chat-dialog-text-color: hsla(0, 0%, 6.7%, .6); + --yt-live-chat-poll-choice-text-color: var(--yt-spec-text-secondary); + --yt-live-chat-poll-choice-border-color: var(--yt-spec-10-percent-layer); + --yt-live-chat-poll-choice-vote-bar-background-color: hsla(0, 0%, 93.3%, .8); + --yt-live-chat-poll-choice-vote-bar-background-color-selected: #F2F8FF; + --yt-live-chat-poll-choice-color-selected: #065FD4; + --yt-live-chat-moderation-mode-hover-background-color: hsla(0, 0%, 6.7%, .2); + --yt-live-chat-additional-inline-action-button-color: hsl(0, 0%, 100%); + --yt-live-chat-additional-inline-action-button-background-color: hsla(0, 0%, 26%, 0.8); + --yt-live-chat-additional-inline-action-button-background-color-hover: hsla(0, 0%, 26%, 1.0); + --yt-formatted-string-emoji-size: 24px; + --yt-live-chat-emoji-size: 24px; + --yt-live-chat-text-input-field-suggestion-background-color: hsl(0, 0%, 100%); + --yt-live-chat-text-input-field-suggestion-background-color-hover: #eee; + --yt-live-chat-text-input-field-suggestion-text-color: #666; + --yt-live-chat-text-input-field-suggestion-text-color-hover: #333; + --yt-live-chat-ticker-arrow-background: hsl(0, 0%, 97.3%); + --yt-emoji-picker-category-background-color: var(--yt-live-chat-action-panel-background-color-transparent); + --yt-emoji-picker-category-color: var(--yt-live-chat-secondary-text-color); + --yt-emoji-picker-category-button-color: var(--yt-live-chat-picker-button-color); + --yt-emoji-picker-search-background-color: hsla(0, 0%, 100%, .6); + --yt-emoji-picker-search-color: hsla(0, 0%, 6.7%, .8); + --yt-emoji-picker-search-placeholder-color: hsla(0, 0%, 6.7%, .6); + --yt-live-chat-slider-active-color: #2196f3; + --yt-live-chat-slider-container-color: #c8c8c8; + --yt-live-chat-slider-markers-color: #505050; + --yt-live-chat-toast-background-color: hsl(0, 0%, 20%); + --yt-live-chat-toast-text-color: hsl(0, 0%, 100%); + --yt-live-chat-automod-button-background-color: hsl(0, 0%, 93.3%); + --yt-live-chat-automod-button-background-color-hover: hsla(0, 0%, 6.7%, .2); + --yt-live-chat-countdown-opacity: 0.3; + --yt-live-chat-shimmer-background-color: rgba(136, 136, 136, 0.2); + --yt-live-chat-shimmer-linear-gradient: linear-gradient(0deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 65%); + --yt-live-chat-vem-background-color: hsl(0, 0%, 93.3%); + --yt-live-chat-upsell-dialog-renderer-button-padding: 10px 16px; + --yt-live-chat-product-picker-icon-color: rgba(17, 17, 17, 0.6); + --yt-live-chat-product-picker-hover-color: rgba(17, 17, 16, 0.1); + --yt-live-chat-product-picker-disabled-icon-color: rgba(17, 17, 17, 0.4); + --yt-pdg-paid-stickers-tab-selection-bar-color: #065FD4; + --yt-pdg-paid-stickers-author-name-font-size: 13px; + --yt-pdg-paid-stickers-margin-left: 38px; + } - --layout-inline_-_display: inline-flex; - ; + html:not(.style-scope) { + --layout_-_display: flex; + ; - --layout-horizontal_-_display: var(--layout_-_display); - --layout-horizontal_-_-ms-flex-direction: row; - --layout-horizontal_-_-webkit-flex-direction: row; - --layout-horizontal_-_flex-direction: row; - ; + --layout-inline_-_display: inline-flex; + ; - --layout-horizontal-reverse_-_display: var(--layout_-_display); - --layout-horizontal-reverse_-_-ms-flex-direction: row-reverse; - --layout-horizontal-reverse_-_-webkit-flex-direction: row-reverse; - --layout-horizontal-reverse_-_flex-direction: row-reverse; - ; + --layout-horizontal_-_display: var(--layout_-_display); + --layout-horizontal_-_-ms-flex-direction: row; + --layout-horizontal_-_-webkit-flex-direction: row; + --layout-horizontal_-_flex-direction: row; + ; - --layout-vertical_-_display: var(--layout_-_display); - --layout-vertical_-_-ms-flex-direction: column; - --layout-vertical_-_-webkit-flex-direction: column; - --layout-vertical_-_flex-direction: column; - ; + --layout-horizontal-reverse_-_display: var(--layout_-_display); + --layout-horizontal-reverse_-_-ms-flex-direction: row-reverse; + --layout-horizontal-reverse_-_-webkit-flex-direction: row-reverse; + --layout-horizontal-reverse_-_flex-direction: row-reverse; + ; - --layout-vertical-reverse_-_display: var(--layout_-_display); - --layout-vertical-reverse_-_-ms-flex-direction: column-reverse; - --layout-vertical-reverse_-_-webkit-flex-direction: column-reverse; - --layout-vertical-reverse_-_flex-direction: column-reverse; - ; + --layout-vertical_-_display: var(--layout_-_display); + --layout-vertical_-_-ms-flex-direction: column; + --layout-vertical_-_-webkit-flex-direction: column; + --layout-vertical_-_flex-direction: column; + ; - --layout-wrap_-_-ms-flex-wrap: wrap; - --layout-wrap_-_-webkit-flex-wrap: wrap; - --layout-wrap_-_flex-wrap: wrap; - ; + --layout-vertical-reverse_-_display: var(--layout_-_display); + --layout-vertical-reverse_-_-ms-flex-direction: column-reverse; + --layout-vertical-reverse_-_-webkit-flex-direction: column-reverse; + --layout-vertical-reverse_-_flex-direction: column-reverse; + ; - --layout-wrap-reverse_-_-ms-flex-wrap: wrap-reverse; - --layout-wrap-reverse_-_-webkit-flex-wrap: wrap-reverse; - --layout-wrap-reverse_-_flex-wrap: wrap-reverse; - ; + --layout-wrap_-_-ms-flex-wrap: wrap; + --layout-wrap_-_-webkit-flex-wrap: wrap; + --layout-wrap_-_flex-wrap: wrap; + ; - --layout-flex-auto_-_-ms-flex: 1 1 auto; - --layout-flex-auto_-_-webkit-flex: 1 1 auto; - --layout-flex-auto_-_flex: 1 1 auto; - ; + --layout-wrap-reverse_-_-ms-flex-wrap: wrap-reverse; + --layout-wrap-reverse_-_-webkit-flex-wrap: wrap-reverse; + --layout-wrap-reverse_-_flex-wrap: wrap-reverse; + ; - --layout-flex-none_-_-ms-flex: none; - --layout-flex-none_-_-webkit-flex: none; - --layout-flex-none_-_flex: none; - ; + --layout-flex-auto_-_-ms-flex: 1 1 auto; + --layout-flex-auto_-_-webkit-flex: 1 1 auto; + --layout-flex-auto_-_flex: 1 1 auto; + ; - --layout-flex_-_-ms-flex: 1 1 0.000000001px; - --layout-flex_-_-webkit-flex: 1; - --layout-flex_-_flex: 1; - --layout-flex_-_-webkit-flex-basis: 0.000000001px; - --layout-flex_-_flex-basis: 0.000000001px; - ; + --layout-flex-none_-_-ms-flex: none; + --layout-flex-none_-_-webkit-flex: none; + --layout-flex-none_-_flex: none; + ; - --layout-flex-2_-_-ms-flex: 2; - --layout-flex-2_-_-webkit-flex: 2; - --layout-flex-2_-_flex: 2; - ; + --layout-flex_-_-ms-flex: 1 1 0.000000001px; + --layout-flex_-_-webkit-flex: 1; + --layout-flex_-_flex: 1; + --layout-flex_-_-webkit-flex-basis: 0.000000001px; + --layout-flex_-_flex-basis: 0.000000001px; + ; - --layout-flex-3_-_-ms-flex: 3; - --layout-flex-3_-_-webkit-flex: 3; - --layout-flex-3_-_flex: 3; - ; + --layout-flex-2_-_-ms-flex: 2; + --layout-flex-2_-_-webkit-flex: 2; + --layout-flex-2_-_flex: 2; + ; - --layout-flex-4_-_-ms-flex: 4; - --layout-flex-4_-_-webkit-flex: 4; - --layout-flex-4_-_flex: 4; - ; + --layout-flex-3_-_-ms-flex: 3; + --layout-flex-3_-_-webkit-flex: 3; + --layout-flex-3_-_flex: 3; + ; - --layout-flex-5_-_-ms-flex: 5; - --layout-flex-5_-_-webkit-flex: 5; - --layout-flex-5_-_flex: 5; - ; + --layout-flex-4_-_-ms-flex: 4; + --layout-flex-4_-_-webkit-flex: 4; + --layout-flex-4_-_flex: 4; + ; - --layout-flex-6_-_-ms-flex: 6; - --layout-flex-6_-_-webkit-flex: 6; - --layout-flex-6_-_flex: 6; - ; + --layout-flex-5_-_-ms-flex: 5; + --layout-flex-5_-_-webkit-flex: 5; + --layout-flex-5_-_flex: 5; + ; - --layout-flex-7_-_-ms-flex: 7; - --layout-flex-7_-_-webkit-flex: 7; - --layout-flex-7_-_flex: 7; - ; + --layout-flex-6_-_-ms-flex: 6; + --layout-flex-6_-_-webkit-flex: 6; + --layout-flex-6_-_flex: 6; + ; - --layout-flex-8_-_-ms-flex: 8; - --layout-flex-8_-_-webkit-flex: 8; - --layout-flex-8_-_flex: 8; - ; + --layout-flex-7_-_-ms-flex: 7; + --layout-flex-7_-_-webkit-flex: 7; + --layout-flex-7_-_flex: 7; + ; - --layout-flex-9_-_-ms-flex: 9; - --layout-flex-9_-_-webkit-flex: 9; - --layout-flex-9_-_flex: 9; - ; + --layout-flex-8_-_-ms-flex: 8; + --layout-flex-8_-_-webkit-flex: 8; + --layout-flex-8_-_flex: 8; + ; - --layout-flex-10_-_-ms-flex: 10; - --layout-flex-10_-_-webkit-flex: 10; - --layout-flex-10_-_flex: 10; - ; + --layout-flex-9_-_-ms-flex: 9; + --layout-flex-9_-_-webkit-flex: 9; + --layout-flex-9_-_flex: 9; + ; - --layout-flex-11_-_-ms-flex: 11; - --layout-flex-11_-_-webkit-flex: 11; - --layout-flex-11_-_flex: 11; - ; + --layout-flex-10_-_-ms-flex: 10; + --layout-flex-10_-_-webkit-flex: 10; + --layout-flex-10_-_flex: 10; + ; - --layout-flex-12_-_-ms-flex: 12; - --layout-flex-12_-_-webkit-flex: 12; - --layout-flex-12_-_flex: 12; - ; + --layout-flex-11_-_-ms-flex: 11; + --layout-flex-11_-_-webkit-flex: 11; + --layout-flex-11_-_flex: 11; + ; + + --layout-flex-12_-_-ms-flex: 12; + --layout-flex-12_-_-webkit-flex: 12; + --layout-flex-12_-_flex: 12; + ; - --layout-start_-_-ms-flex-align: start; - --layout-start_-_-webkit-align-items: flex-start; - --layout-start_-_align-items: flex-start; - ; + --layout-start_-_-ms-flex-align: start; + --layout-start_-_-webkit-align-items: flex-start; + --layout-start_-_align-items: flex-start; + ; - --layout-center_-_-ms-flex-align: center; - --layout-center_-_-webkit-align-items: center; - --layout-center_-_align-items: center; - ; + --layout-center_-_-ms-flex-align: center; + --layout-center_-_-webkit-align-items: center; + --layout-center_-_align-items: center; + ; - --layout-end_-_-ms-flex-align: end; - --layout-end_-_-webkit-align-items: flex-end; - --layout-end_-_align-items: flex-end; - ; + --layout-end_-_-ms-flex-align: end; + --layout-end_-_-webkit-align-items: flex-end; + --layout-end_-_align-items: flex-end; + ; - --layout-baseline_-_-ms-flex-align: baseline; - --layout-baseline_-_-webkit-align-items: baseline; - --layout-baseline_-_align-items: baseline; - ; + --layout-baseline_-_-ms-flex-align: baseline; + --layout-baseline_-_-webkit-align-items: baseline; + --layout-baseline_-_align-items: baseline; + ; - --layout-start-justified_-_-ms-flex-pack: start; - --layout-start-justified_-_-webkit-justify-content: flex-start; - --layout-start-justified_-_justify-content: flex-start; - ; + --layout-start-justified_-_-ms-flex-pack: start; + --layout-start-justified_-_-webkit-justify-content: flex-start; + --layout-start-justified_-_justify-content: flex-start; + ; - --layout-center-justified_-_-ms-flex-pack: center; - --layout-center-justified_-_-webkit-justify-content: center; - --layout-center-justified_-_justify-content: center; - ; + --layout-center-justified_-_-ms-flex-pack: center; + --layout-center-justified_-_-webkit-justify-content: center; + --layout-center-justified_-_justify-content: center; + ; - --layout-end-justified_-_-ms-flex-pack: end; - --layout-end-justified_-_-webkit-justify-content: flex-end; - --layout-end-justified_-_justify-content: flex-end; - ; + --layout-end-justified_-_-ms-flex-pack: end; + --layout-end-justified_-_-webkit-justify-content: flex-end; + --layout-end-justified_-_justify-content: flex-end; + ; - --layout-around-justified_-_-ms-flex-pack: distribute; - --layout-around-justified_-_-webkit-justify-content: space-around; - --layout-around-justified_-_justify-content: space-around; - ; + --layout-around-justified_-_-ms-flex-pack: distribute; + --layout-around-justified_-_-webkit-justify-content: space-around; + --layout-around-justified_-_justify-content: space-around; + ; - --layout-justified_-_-ms-flex-pack: justify; - --layout-justified_-_-webkit-justify-content: space-between; - --layout-justified_-_justify-content: space-between; - ; + --layout-justified_-_-ms-flex-pack: justify; + --layout-justified_-_-webkit-justify-content: space-between; + --layout-justified_-_justify-content: space-between; + ; - --layout-center-center_-_-ms-flex-align: var(--layout-center_-_-ms-flex-align); - --layout-center-center_-_-webkit-align-items: var(--layout-center_-_-webkit-align-items); - --layout-center-center_-_align-items: var(--layout-center_-_align-items); - --layout-center-center_-_-ms-flex-pack: var(--layout-center-justified_-_-ms-flex-pack); - --layout-center-center_-_-webkit-justify-content: var(--layout-center-justified_-_-webkit-justify-content); - --layout-center-center_-_justify-content: var(--layout-center-justified_-_justify-content); - ; + --layout-center-center_-_-ms-flex-align: var(--layout-center_-_-ms-flex-align); + --layout-center-center_-_-webkit-align-items: var(--layout-center_-_-webkit-align-items); + --layout-center-center_-_align-items: var(--layout-center_-_align-items); + --layout-center-center_-_-ms-flex-pack: var(--layout-center-justified_-_-ms-flex-pack); + --layout-center-center_-_-webkit-justify-content: var(--layout-center-justified_-_-webkit-justify-content); + --layout-center-center_-_justify-content: var(--layout-center-justified_-_justify-content); + ; - --layout-self-start_-_-ms-align-self: flex-start; - --layout-self-start_-_-webkit-align-self: flex-start; - --layout-self-start_-_align-self: flex-start; - ; + --layout-self-start_-_-ms-align-self: flex-start; + --layout-self-start_-_-webkit-align-self: flex-start; + --layout-self-start_-_align-self: flex-start; + ; - --layout-self-center_-_-ms-align-self: center; - --layout-self-center_-_-webkit-align-self: center; - --layout-self-center_-_align-self: center; - ; + --layout-self-center_-_-ms-align-self: center; + --layout-self-center_-_-webkit-align-self: center; + --layout-self-center_-_align-self: center; + ; - --layout-self-end_-_-ms-align-self: flex-end; - --layout-self-end_-_-webkit-align-self: flex-end; - --layout-self-end_-_align-self: flex-end; - ; + --layout-self-end_-_-ms-align-self: flex-end; + --layout-self-end_-_-webkit-align-self: flex-end; + --layout-self-end_-_align-self: flex-end; + ; - --layout-self-stretch_-_-ms-align-self: stretch; - --layout-self-stretch_-_-webkit-align-self: stretch; - --layout-self-stretch_-_align-self: stretch; - ; + --layout-self-stretch_-_-ms-align-self: stretch; + --layout-self-stretch_-_-webkit-align-self: stretch; + --layout-self-stretch_-_align-self: stretch; + ; - --layout-self-baseline_-_-ms-align-self: baseline; - --layout-self-baseline_-_-webkit-align-self: baseline; - --layout-self-baseline_-_align-self: baseline; - ; + --layout-self-baseline_-_-ms-align-self: baseline; + --layout-self-baseline_-_-webkit-align-self: baseline; + --layout-self-baseline_-_align-self: baseline; + ; - --layout-start-aligned_-_-ms-flex-line-pack: start; - --layout-start-aligned_-_-ms-align-content: flex-start; - --layout-start-aligned_-_-webkit-align-content: flex-start; - --layout-start-aligned_-_align-content: flex-start; - ; + --layout-start-aligned_-_-ms-flex-line-pack: start; + --layout-start-aligned_-_-ms-align-content: flex-start; + --layout-start-aligned_-_-webkit-align-content: flex-start; + --layout-start-aligned_-_align-content: flex-start; + ; - --layout-end-aligned_-_-ms-flex-line-pack: end; - --layout-end-aligned_-_-ms-align-content: flex-end; - --layout-end-aligned_-_-webkit-align-content: flex-end; - --layout-end-aligned_-_align-content: flex-end; - ; + --layout-end-aligned_-_-ms-flex-line-pack: end; + --layout-end-aligned_-_-ms-align-content: flex-end; + --layout-end-aligned_-_-webkit-align-content: flex-end; + --layout-end-aligned_-_align-content: flex-end; + ; - --layout-center-aligned_-_-ms-flex-line-pack: center; - --layout-center-aligned_-_-ms-align-content: center; - --layout-center-aligned_-_-webkit-align-content: center; - --layout-center-aligned_-_align-content: center; - ; + --layout-center-aligned_-_-ms-flex-line-pack: center; + --layout-center-aligned_-_-ms-align-content: center; + --layout-center-aligned_-_-webkit-align-content: center; + --layout-center-aligned_-_align-content: center; + ; - --layout-between-aligned_-_-ms-flex-line-pack: justify; - --layout-between-aligned_-_-ms-align-content: space-between; - --layout-between-aligned_-_-webkit-align-content: space-between; - --layout-between-aligned_-_align-content: space-between; - ; + --layout-between-aligned_-_-ms-flex-line-pack: justify; + --layout-between-aligned_-_-ms-align-content: space-between; + --layout-between-aligned_-_-webkit-align-content: space-between; + --layout-between-aligned_-_align-content: space-between; + ; - --layout-around-aligned_-_-ms-flex-line-pack: distribute; - --layout-around-aligned_-_-ms-align-content: space-around; - --layout-around-aligned_-_-webkit-align-content: space-around; - --layout-around-aligned_-_align-content: space-around; - ; + --layout-around-aligned_-_-ms-flex-line-pack: distribute; + --layout-around-aligned_-_-ms-align-content: space-around; + --layout-around-aligned_-_-webkit-align-content: space-around; + --layout-around-aligned_-_align-content: space-around; + ; - --layout-block_-_display: block; - ; + --layout-block_-_display: block; + ; - --layout-invisible_-_visibility: hidden !important; - ; + --layout-invisible_-_visibility: hidden !important; + ; - --layout-relative_-_position: relative; - ; + --layout-relative_-_position: relative; + ; - --layout-fit_-_position: absolute; - --layout-fit_-_top: 0; - --layout-fit_-_right: 0; - --layout-fit_-_bottom: 0; - --layout-fit_-_left: 0; - ; + --layout-fit_-_position: absolute; + --layout-fit_-_top: 0; + --layout-fit_-_right: 0; + --layout-fit_-_bottom: 0; + --layout-fit_-_left: 0; + ; - --layout-scroll_-_-webkit-overflow-scrolling: touch; - --layout-scroll_-_overflow: auto; - ; + --layout-scroll_-_-webkit-overflow-scrolling: touch; + --layout-scroll_-_overflow: auto; + ; - --layout-fullbleed_-_margin: 0; - --layout-fullbleed_-_height: 100vh; - ; + --layout-fullbleed_-_margin: 0; + --layout-fullbleed_-_height: 100vh; + ; - --layout-fixed-top_-_position: fixed; - --layout-fixed-top_-_top: 0; - --layout-fixed-top_-_left: 0; - --layout-fixed-top_-_right: 0; - ; + --layout-fixed-top_-_position: fixed; + --layout-fixed-top_-_top: 0; + --layout-fixed-top_-_left: 0; + --layout-fixed-top_-_right: 0; + ; - --layout-fixed-right_-_position: fixed; - --layout-fixed-right_-_top: 0; - --layout-fixed-right_-_right: 0; - --layout-fixed-right_-_bottom: 0; - ; + --layout-fixed-right_-_position: fixed; + --layout-fixed-right_-_top: 0; + --layout-fixed-right_-_right: 0; + --layout-fixed-right_-_bottom: 0; + ; - --layout-fixed-bottom_-_position: fixed; - --layout-fixed-bottom_-_right: 0; - --layout-fixed-bottom_-_bottom: 0; - --layout-fixed-bottom_-_left: 0; - ; + --layout-fixed-bottom_-_position: fixed; + --layout-fixed-bottom_-_right: 0; + --layout-fixed-bottom_-_bottom: 0; + --layout-fixed-bottom_-_left: 0; + ; - --layout-fixed-left_-_position: fixed; - --layout-fixed-left_-_top: 0; - --layout-fixed-left_-_bottom: 0; - --layout-fixed-left_-_left: 0; - ; -} + --layout-fixed-left_-_position: fixed; + --layout-fixed-left_-_top: 0; + --layout-fixed-left_-_bottom: 0; + --layout-fixed-left_-_left: 0; + ; + } + +} \ No newline at end of file diff --git a/src/client/ClientAutoAction.vue b/src/client/ClientAutoAction.vue index dff7921..0581697 100644 --- a/src/client/ClientAutoAction.vue +++ b/src/client/ClientAutoAction.vue @@ -508,8 +508,26 @@ onMounted(() => { v-for="(label, type) in typeMap" :key="type" :name="type" - :tab="label" > + boolean; // 自定义过滤器 + enabledTriggerTypes?: Ref> // 触发类型启用状态 } ): AutoActionItem[] { return actions.filter(action => { @@ -38,6 +39,11 @@ export function filterValidActions( return false; } + // 检查触发类型是否启用 + if (options?.enabledTriggerTypes && !options.enabledTriggerTypes.value[triggerType]) { + return false; + } + // 直播状态过滤 if (action.triggerConfig.onlyDuringLive && !isLive.value) { return false; @@ -146,6 +152,38 @@ export function processTemplate( } } +// 辅助函数:发送弹幕并记录日志 +async function sendAndLogDanmaku( + sendHandler: (roomId: number, message: string) => Promise, + action: AutoActionItem, + roomId: number, + message: string +): Promise { + try { + const success = await sendHandler(roomId, message); + logDanmakuHistory( + action.id, + action.name || '未命名操作', + message, + roomId, + success, + success ? undefined : '发送失败' + ).catch(err => console.error('记录弹幕历史失败:', err)); + return success; + } catch (err) { + console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err); + logDanmakuHistory( + action.id, + action.name || '未命名操作', + message, + roomId, + false, + err instanceof Error ? err.toString() : String(err) // 确保err是字符串 + ).catch(e => console.error('记录弹幕历史失败:', e)); + return false; + } +} + /** * 执行操作的通用函数 * @param actions 过滤后的操作列表 @@ -220,61 +258,13 @@ export function executeActions( // 更新冷却时间 runtimeState.lastExecutionTime[action.id] = Date.now(); + const sendAction = () => sendAndLogDanmaku(handlers.sendLiveDanmaku!, action, roomId, message); + // 延迟发送 if (action.actionConfig.delaySeconds && action.actionConfig.delaySeconds > 0) { - setTimeout(() => { - handlers.sendLiveDanmaku!(roomId, message) - .then(success => { - // 记录弹幕发送历史 - logDanmakuHistory( - action.id, - action.name || '未命名操作', - message, - roomId, - success, - success ? undefined : '发送失败' - ).catch(err => console.error('记录弹幕历史失败:', err)); - return success; - }) - .catch(err => { - console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err); - // 记录失败的发送 - logDanmakuHistory( - action.id, - action.name || '未命名操作', - message, - roomId, - false, - err.toString() - ).catch(e => console.error('记录弹幕历史失败:', e)); - }); - }, action.actionConfig.delaySeconds * 1000); + setTimeout(sendAction, action.actionConfig.delaySeconds * 1000); } else { - handlers.sendLiveDanmaku(roomId, message) - .then(success => { - // 记录弹幕发送历史 - logDanmakuHistory( - action.id, - action.name || '未命名操作', - message, - roomId, - success, - success ? undefined : '发送失败' - ).catch(err => console.error('记录弹幕历史失败:', err)); - return success; - }) - .catch(err => { - console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err); - // 记录失败的发送 - logDanmakuHistory( - action.id, - action.name || '未命名操作', - message, - roomId, - false, - err.toString() - ).catch(e => console.error('记录弹幕历史失败:', e)); - }); + sendAction(); } } } else { @@ -321,7 +311,7 @@ export function executeActions( msg, uid, false, - err.toString() + err instanceof Error ? err.toString() : String(err) // 确保err是字符串 ).catch(e => console.error('记录私信历史失败:', e)); return false; // 明确返回 false 表示失败 }); diff --git a/src/client/store/useAutoAction.ts b/src/client/store/useAutoAction.ts index ba89343..9c9d6c4 100644 --- a/src/client/store/useAutoAction.ts +++ b/src/client/store/useAutoAction.ts @@ -28,19 +28,21 @@ import { createDefaultRuntimeState } from './autoAction/utils'; import { evaluateTemplateExpressions } from './autoAction/expressionEvaluator'; +// 导入 actionUtils 工具函数 +import { filterValidActions, checkUserFilters, checkCooldown, processTemplate, executeActions } from './autoAction/actionUtils'; // 导入 nanoid 用于生成唯一 ID import { nanoid } from 'nanoid'; // 导入开发环境判断标志 import { isDev } from '@/data/constants.js'; // 导入所有自动操作子模块 -import { useGiftThank } from './autoAction/modules/giftThank.js'; -import { useGuardPm } from './autoAction/modules/guardPm.js'; -import { useFollowThank } from './autoAction/modules/followThank.js'; -import { useEntryWelcome } from './autoAction/modules/entryWelcome.js'; -import { useAutoReply } from './autoAction/modules/autoReply.js'; -import { useScheduledDanmaku } from './autoAction/modules/scheduledDanmaku.js'; -import { useSuperChatThank } from './autoAction/modules/superChatThank.js'; +import { useGiftThank } from './autoAction/modules/giftThank'; +import { useGuardPm } from './autoAction/modules/guardPm'; +import { useFollowThank } from './autoAction/modules/followThank'; +import { useEntryWelcome } from './autoAction/modules/entryWelcome'; +import { useAutoReply } from './autoAction/modules/autoReply'; +import { useScheduledDanmaku } from './autoAction/modules/scheduledDanmaku'; +import { useSuperChatThank } from './autoAction/modules/superChatThank'; // 定义名为 'autoAction' 的 Pinia store export const useAutoAction = defineStore('autoAction', () => { @@ -540,38 +542,6 @@ export const useAutoAction = defineStore('autoAction', () => { // 定时检查天选状态 (每5分钟) const tianXuanTimer = setInterval(checkTianXuanStatus, 5 * 60 * 1000); - /** - * 判断是否应处理某个操作项 (基于事件和配置) - * @param action 操作项配置 - * @param event 可选的事件数据 - * @returns 是否应该处理 - */ - function shouldProcessAction(action: AutoActionItem, event?: EventModel | null): boolean { - if (!action.enabled) return false; // 未启用则跳过 - if (!enabledTriggerTypes.value[action.triggerType]) return false; // 触发类型未启用则跳过 - - // 检查模板是否为空 (添加新的检查) - if (!action.template || action.template.trim() === '') { - console.warn(`[AutoAction] 跳过操作 "${action.name}":未设置有效模板`); - return false; - } - - // 根据配置检查条件 - if (action.triggerConfig.onlyDuringLive && !isLive.value) return false; // 仅直播时 - if (action.triggerConfig.ignoreTianXuan && isTianXuanActive.value) return false; // 忽略天选时 - // 用户过滤条件 - if (event && action.triggerConfig.userFilterEnabled) { - if (action.triggerConfig.requireMedal && !event.fans_medal_wearing_status) return false; // 要求粉丝牌 - if (action.triggerConfig.requireCaptain && event.guard_level === GuardLevel.None) return false; // 要求舰长 - } - // 逻辑表达式判断 - if (action.logicalExpression && event) { - const context = buildExecutionContext(event, roomId.value, action.triggerType); - if (!evaluateExpression(action.logicalExpression, context)) return false; // 表达式不满足 - } - return true; // 所有条件满足 - } - /** * 处理接收到的事件 * @param event 事件数据 @@ -579,10 +549,8 @@ export const useAutoAction = defineStore('autoAction', () => { */ function processEvent(event: EventModel, triggerType: TriggerType) { if (!roomId.value) return; // 房间 ID 无效则跳过 - // 检查触发类型是否启用 if (!enabledTriggerTypes.value[triggerType]) return; - // 根据触发类型调用相应模块的处理函数 switch (triggerType) { case TriggerType.DANMAKU: diff --git a/src/components/MonacoEditorComponent.vue b/src/components/MonacoEditorComponent.vue index 5988668..7e65f81 100644 --- a/src/components/MonacoEditorComponent.vue +++ b/src/components/MonacoEditorComponent.vue @@ -2,12 +2,13 @@
\ No newline at end of file diff --git a/src/components/RegisterAndLogin.vue b/src/components/RegisterAndLogin.vue index e859b78..6e3d065 100644 --- a/src/components/RegisterAndLogin.vue +++ b/src/components/RegisterAndLogin.vue @@ -167,9 +167,7 @@ function onLoginButtonClick() { refreshDate: Date.now() } message.success(`成功登陆为 ${data?.data.account.name}`) - setTimeout(() => { - location.reload() - }, 1000) + location.reload() } else { message.error(data.message) } diff --git a/src/data/Initializer.ts b/src/data/Initializer.ts index 465ac3c..d45104a 100644 --- a/src/data/Initializer.ts +++ b/src/data/Initializer.ts @@ -94,43 +94,38 @@ function InitVersionCheck() { currentVersion = keepCheckData.data localStorage.setItem('Version', currentVersion) console.log(`[vtsuru] 发现新版本: ${currentVersion}`) - - const url = new URL(window.location.href) - const path = url.pathname - - if (!path.startsWith('/obs')) { - if (isTauri()) { - location.reload(); - } - else { - const n = notification.info({ - title: '发现新的版本更新', - content: '是否现在刷新?', - meta: () => h(NText, { depth: 3 }, () => currentVersion), - action: () => - h(NFlex, null, () => [ - h( - NButton, - { - text: true, - type: 'primary', - onClick: () => location.reload(), - size: 'small', - }, - { default: () => '刷新' }, - ), - h( - NButton, - { - text: true, - onClick: () => n.destroy(), - size: 'small', - }, - { default: () => '稍后' }, - ), - ]), - }) - } + + if (window.$route.meta.forceReload || isTauri()) { + location.reload() + } + else { + const n = notification.info({ + title: '发现新的版本更新', + content: '是否现在刷新?', + meta: () => h(NText, { depth: 3 }, () => currentVersion), + action: () => + h(NFlex, null, () => [ + h( + NButton, + { + text: true, + type: 'primary', + onClick: () => location.reload(), + size: 'small', + }, + { default: () => '刷新' }, + ), + h( + NButton, + { + text: true, + onClick: () => n.destroy(), + size: 'small', + }, + { default: () => '稍后' }, + ), + ]), + }) } } }, diff --git a/src/data/UpdateNote.ts b/src/data/UpdateNote.ts index b86fb87..bdcdee0 100644 --- a/src/data/UpdateNote.ts +++ b/src/data/UpdateNote.ts @@ -4,6 +4,26 @@ import { VNode } from "vue"; import { FETCH_API } from "./constants"; export const updateNotes: updateNoteType[] = [ + { + ver: 5, + date: '2025.4.24', + items: [ + { + type: 'new', + title: '新增弹幕姬管理页面', + content: [ + [ + '弹幕姬现在可用,兼容 blivechat 样式', + () => h(NImage, { src: 'https://pan.suki.club/d/vtsuru/imgur/3c5a6f68-1aa4-4b96-a25e-dba2581ac898.png', width: 300 }), + ], + [ + '大部分功能都和 blivechat 一致, 不过目前还无法提供本地文件访问, 部分css中需要使用图片等本地资源样式的需要等 EventFetcher 更新相关功能后才能使用\r\n', + '配置上传之后会自动同步到obs中' + ] + ], + }, + ] + }, { ver: 4, date: '2025.4.22', diff --git a/src/data/constants.ts b/src/data/constants.ts index 38ef389..b1066cd 100644 --- a/src/data/constants.ts +++ b/src/data/constants.ts @@ -118,3 +118,301 @@ export const IndexTemplateMap: TemplateMapType = { component: DefaultIndexTemplateVue } }; + +export const defaultDanmujiCss = `@import url("https://fonts.googleapis.com/css?family=Changa%20One"); +@import url("https://fonts.googleapis.com/css?family=Imprima"); + +/* Transparent background */ +yt-live-chat-renderer { + background-color: transparent !important; +} + +yt-live-chat-ticker-renderer { + background-color: transparent !important; + box-shadow: none !important; +} + +yt-live-chat-author-chip #author-name { + background-color: transparent !important; +} + +yt-live-chat-item-list-renderer #item-scroller { + overflow: hidden !important; +} + +yt-live-chat-interact-message-renderer #content, +yt-live-chat-text-message-renderer #content, +yt-live-chat-membership-item-renderer #content { + overflow: visible !important; +} + +/* Hide header and input */ +yt-live-chat-header-renderer, +yt-live-chat-message-input-renderer { + display: none !important; +} + +/* Hide unimportant messages */ +yt-live-chat-interact-message-renderer[is-deleted], +yt-live-chat-text-message-renderer[is-deleted], +yt-live-chat-membership-item-renderer[is-deleted] { + display: none !important; +} + +yt-live-chat-mode-change-message-renderer, +yt-live-chat-viewer-engagement-message-renderer, +yt-live-chat-restricted-participation-renderer { + display: none !important; +} + +yt-live-chat-text-message-renderer a, +yt-live-chat-membership-item-renderer a { + text-decoration: none !important; +} + +/* Global Setting */ +yt-live-chat-renderer { + +} +#item-scroller { + +} + +/* Reduce side padding */ +yt-live-chat-interact-message-renderer, +yt-live-chat-text-message-renderer { + padding-left: 4px !important; + padding-right: 4px !important; +} + +/* Outlines */ +yt-live-chat-renderer * { + text-shadow: -2px -2px #000000, -2px -1px #000000, -2px 0px #000000, -2px 1px #000000, -2px 2px #000000, -1px -2px #000000, -1px -1px #000000, -1px 0px #000000, -1px 1px #000000, -1px 2px #000000, 0px -2px #000000, 0px -1px #000000, 0px 0px #000000, 0px 1px #000000, 0px 2px #000000, 1px -2px #000000, 1px -1px #000000, 1px 0px #000000, 1px 1px #000000, 1px 2px #000000, 2px -2px #000000, 2px -1px #000000, 2px 0px #000000, 2px 1px #000000, 2px 2px #000000; + font-family: "Imprima", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 18px !important; + line-height: 20px !important; +} + +/* Avatars */ +yt-live-chat-interact-message-renderer #author-photo, +yt-live-chat-interact-message-renderer #author-photo img, +yt-live-chat-text-message-renderer #author-photo, +yt-live-chat-text-message-renderer #author-photo img, +yt-live-chat-paid-message-renderer #author-photo, +yt-live-chat-paid-message-renderer #author-photo img, +yt-live-chat-membership-item-renderer #author-photo, +yt-live-chat-membership-item-renderer #author-photo img { + + width: 24px !important; + height: 24px !important; + border-radius: 24px !important; + margin-right: 6px !important; +} + +/* Channel names */ +yt-live-chat-interact-message-renderer #content #author-name, +yt-live-chat-text-message-renderer #content #author-name { + +} +yt-live-chat-interact-message-renderer #author-name[type="owner"], +yt-live-chat-interact-message-renderer yt-live-chat-author-badge-renderer[type="owner"], +yt-live-chat-text-message-renderer #author-name[type="owner"], +yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="owner"] { + color: #ffd600 !important; +} +yt-live-chat-interact-message-renderer #author-name[type="moderator"], +yt-live-chat-interact-message-renderer yt-live-chat-author-badge-renderer[type="moderator"], +yt-live-chat-text-message-renderer #author-name[type="moderator"], +yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="moderator"] { + color: #5e84f1 !important; +} +yt-live-chat-interact-message-renderer #author-name[type="member"], +yt-live-chat-interact-message-renderer yt-live-chat-author-badge-renderer[type="member"], +yt-live-chat-text-message-renderer #author-name[type="member"], +yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="member"] { + color: #0f9d58 !important; +} + +yt-live-chat-interact-message-renderer #author-name, +yt-live-chat-text-message-renderer #author-name { + + color: #cccccc !important; + font-family: "Changa One", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 20px !important; + line-height: 20px !important; +} + +/* Show colon */ +yt-live-chat-text-message-renderer #author-name::after { + content: ":"; + margin-left: 2px; +} + +/* Hide badges */ +yt-live-chat-interact-message-renderer #chat-badges, +yt-live-chat-text-message-renderer #chat-badges { + + vertical-align: text-top !important; +} +img.yt-live-chat-author-badge-renderer, yt-icon.yt-live-chat-author-badge-renderer { + width: 20px; + height: 20px; +} + +/* Medal */ +yt-live-chat-author-medal-renderer { + display: none; + +} +yt-live-chat-author-medal-renderer[is-fan-group] { + display: flex; +} +#medal-name.yt-live-chat-author-medal-renderer { + + font-size: 14px !important; + line-height: 14px !important; +} + +#medal-level.yt-live-chat-author-medal-renderer { + + font-size: 14px !important; + line-height: 14px !important; +} + + +/* Messages */ +yt-live-chat-interact-message-renderer #message, +yt-live-chat-interact-message-renderer #message *, +yt-live-chat-text-message-renderer #message, +yt-live-chat-text-message-renderer #message * { + color: #ffffff !important; + font-family: "Imprima", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 18px !important; + line-height: 18px !important; +} + +yt-live-chat-text-message-renderer #image-and-message { + display: inline !important; + overflow: visible !important; +} + + + + +yt-live-chat-text-message-renderer #message { + display: inline !important; + overflow: visible !important; +} + +yt-live-chat-text-message-renderer #image-and-message .emoji { + width: auto !important; + height: 48px !important; +} + +#image-and-message img[display="block"] { + border-radius: 4px; +} + +#image-and-message img[display="inline"] { + position: relative; + top: 3px; + border-radius: 0px; +} + +/* Timestamps */ + + + +/* Background colors */ +body { + overflow: hidden; + background-color: rgba(0, 0, 0, 0); +} + +yt-live-chat-text-message-renderer, +yt-live-chat-text-message-renderer[is-highlighted] { + background-color: rgba(204, 204, 204, 0) !important; +} + +yt-live-chat-text-message-renderer[author-type="owner"], +yt-live-chat-text-message-renderer[author-type="owner"][is-highlighted] { + background-color: rgba(255, 214, 0, 0) !important; +} + +yt-live-chat-text-message-renderer[author-type="moderator"], +yt-live-chat-text-message-renderer[author-type="moderator"][is-highlighted] { + background-color: rgba(94, 132, 241, 0) !important; +} + +yt-live-chat-text-message-renderer[author-type="member"], +yt-live-chat-text-message-renderer[author-type="member"][is-highlighted] { + background-color: rgba(15, 157, 88, 0) !important; +} + +/* SuperChat/Fan Funding Messages */ +yt-live-chat-paid-message-renderer { + margin: 4px 0 !important; +} + +yt-live-chat-paid-message-renderer #author-name, +yt-live-chat-paid-message-renderer #author-name *, +yt-live-chat-membership-item-renderer #header-content-inner-column, +yt-live-chat-membership-item-renderer #header-content-inner-column * { + color: #ffffff !important; + font-family: "Changa One", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 20px !important; + line-height: 20px !important; +} + +yt-live-chat-paid-message-renderer #purchase-amount, +yt-live-chat-paid-message-renderer #purchase-amount *, +yt-live-chat-membership-item-renderer #header-subtext, +yt-live-chat-membership-item-renderer #header-subtext * { + color: #ffffff !important; + font-family: "Imprima", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 18px !important; + line-height: 18px !important; +} + +yt-live-chat-paid-message-renderer #content, +yt-live-chat-paid-message-renderer #content * { + color: #ffffff !important; + font-family: "Imprima", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; + font-size: 18px !important; + line-height: 18px !important; +} + +yt-live-chat-membership-item-renderer #card, +yt-live-chat-membership-item-renderer #header { + background-color: #0f9d58 !important; + margin: 4px 0 !important; +} + +yt-live-chat-ticker-renderer { + display: none !important; +} + +/* SuperChat Ticker */ +yt-live-chat-ticker-paid-message-item-renderer, +yt-live-chat-ticker-paid-message-item-renderer *, +yt-live-chat-ticker-sponsor-item-renderer, +yt-live-chat-ticker-sponsor-item-renderer * { + color: #ffffff !important; + font-family: "Imprima", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", SimHei, Arial, sans-serif; +} + + + +/* Animation */ +@keyframes anim { + +} + +yt-live-chat-interact-message-renderer, +yt-live-chat-text-message-renderer, +yt-live-chat-membership-item-renderer, +yt-live-chat-paid-message-renderer { + animation: anim 0ms; + animation-fill-mode: both; +} +` \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 4b8a42c..5406b5b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,18 @@ import App from './App.vue'; import { InitVTsuru } from './data/Initializer'; import emitter from './mitt'; import router from './router'; +import { loader } from '@guolao/vue-monaco-editor' + +loader.config({ + paths: { + vs: 'https://cdn.jsdelivr.net/npm/monaco-editor/min/vs' + }, + 'vs/nls': { + availableLanguages: { + '*': 'zh-cn' + } + } +}) const pinia = createPinia() export const getPinia = () => pinia diff --git a/src/router/client.ts b/src/router/client.ts index 5484951..923ab60 100644 --- a/src/router/client.ts +++ b/src/router/client.ts @@ -8,6 +8,7 @@ export default { component: () => import('@/client/ClientIndex.vue'), meta: { title: '首页', + forceReload: true, } }, { @@ -16,6 +17,7 @@ export default { component: () => import('@/client/ClientFetcher.vue'), meta: { title: 'EventFetcher', + forceReload: true, } }, { @@ -24,6 +26,7 @@ export default { component: () => import('@/client/ClientSettings.vue'), meta: { title: '设置', + forceReload: true, } }, { @@ -32,6 +35,7 @@ export default { component: () => import('@/client/DanmakuWindowManager.vue'), meta: { title: '弹幕窗口管理', + forceReload: true, } }, { @@ -40,6 +44,7 @@ export default { component: () => import('@/client/ClientAutoAction.vue'), meta: { title: '自动操作管理', + forceReload: true, } }, { @@ -55,6 +60,7 @@ export default { component: () => import('@/client/ClientTest.vue'), meta: { title: '测试', + forceReload: true, } }, ] diff --git a/src/router/manage.ts b/src/router/manage.ts index 5ba7508..b9d01f7 100644 --- a/src/router/manage.ts +++ b/src/router/manage.ts @@ -138,7 +138,7 @@ export default //管理页面 name: 'manage-danmuji', component: () => import('@/views/manage/DanmujiManageView.vue'), meta: { - title: '点歌', + title: '弹幕姬', keepAlive: true, danmaku: true, isNew: true diff --git a/src/router/obs.ts b/src/router/obs.ts index 6a909fd..44104a0 100644 --- a/src/router/obs.ts +++ b/src/router/obs.ts @@ -7,7 +7,8 @@ export default { name: 'obs-live-lottery', component: () => import('@/views/obs/LiveLotteryOBS.vue'), meta: { - title: '直播抽奖' + title: '直播抽奖', + forceReload: true, } }, { @@ -16,7 +17,8 @@ export default { alias: 'song-request', component: () => import('@/views/obs/LiveRequestOBS.vue'), meta: { - title: '弹幕点播' + title: '弹幕点播', + forceReload: true, } }, { @@ -24,7 +26,8 @@ export default { name: 'obs-live-request-today', component: () => import('@/views/obs/LiveRequestProcessedOBS.vue'), meta: { - title: '弹幕点播-今日' + title: '弹幕点播-今日', + forceReload: true, } }, { @@ -32,7 +35,8 @@ export default { name: 'obs-queue', component: () => import('@/views/obs/QueueOBS.vue'), meta: { - title: '弹幕排队' + title: '弹幕排队', + forceReload: true, } }, { @@ -40,7 +44,8 @@ export default { name: 'obs-music-request', component: () => import('@/views/obs/MusicRequestOBS.vue'), meta: { - title: '弹幕排队 (播放' + title: '弹幕排队 (播放列表)', + forceReload: true, } }, { @@ -48,7 +53,8 @@ export default { name: 'obs-question-display', component: () => import('@/views/obs/QuestionDisplayOBS.vue'), meta: { - title: '棉花糖展示' + title: '棉花糖展示', + forceReload: true, } }, { @@ -56,7 +62,8 @@ export default { name: 'obs-web-fetcher', component: () => import('@/views/obs/WebFetcherOBS.vue'), meta: { - title: '弹幕收集器 (OBS版' + title: '弹幕收集器 (OBS版)', + forceReload: true, } }, { @@ -64,7 +71,8 @@ export default { name: 'obs-danmuji', component: () => import('@/views/obs/DanmujiOBS.vue'), meta: { - title: '弹幕机' + title: '弹幕姬', + forceReload: true, } } ] diff --git a/src/router/singlePage.ts b/src/router/singlePage.ts index 1078a0f..dd3bc31 100644 --- a/src/router/singlePage.ts +++ b/src/router/singlePage.ts @@ -21,7 +21,8 @@ export default [ component: () => import('@/client/ClientDanmakuWindow.vue'), meta: { title: '弹幕窗口', - ignoreLogin: true + ignoreLogin: true, + forceReload: true, } } ] diff --git a/src/views/BiliAuthView.vue b/src/views/BiliAuthView.vue index 4426ccc..028714a 100644 --- a/src/views/BiliAuthView.vue +++ b/src/views/BiliAuthView.vue @@ -243,7 +243,7 @@ onMounted(async () => { style="width: 100%" > - 你已完成验证! 请妥善保存你的登陆链接, 请勿让其他人获取. 丢失后可以再次通过认证流程获得 + 你已完成验证! 请妥善保存你的登陆链接, 请勿让其他人获取. 丢失后可以再次通过认证流程获得. 把这个链接复制到浏览器打开即可登录 你的登陆链接为: diff --git a/src/views/ManageLayout.vue b/src/views/ManageLayout.vue index e4bef15..a0aaccb 100644 --- a/src/views/ManageLayout.vue +++ b/src/views/ManageLayout.vue @@ -84,246 +84,255 @@ watch(aplayer, () => { // 邮箱验证相关 const canResendEmail = ref(false) +const isBiliVerified = computed(() => accountInfo.value?.isBiliVerified) // 图标渲染函数 - 用于菜单项 const renderIcon = (icon: any) => () => h(NIcon, null, { default: () => h(icon) }) // 菜单配置 -const menuOptions = [ - { - label: () => h(RouterLink, { to: { name: 'manage-history' } }, { default: () => '历史' }), - key: 'manage-history', - disabled: accountInfo.value?.isEmailVerified === false, - icon: renderIcon(AnalyticsSharp), - }, - { - label: () => h(RouterLink, { to: { name: 'manage-live' } }, { default: () => '直播记录' }), - key: 'manage-live', - disabled: accountInfo.value?.isEmailVerified === false, - icon: renderIcon(Live24Filled), - }, - { - label: () => h(RouterLink, { to: { name: 'manage-analyze' } }, { default: () => '直播数据' }), - key: 'manage-analyze', - disabled: accountInfo.value?.isEmailVerified === false, - icon: renderIcon(Eye), - }, - { - label: () => h(RouterLink, { to: { name: 'manage-event' } }, { default: () => '舰长和SC' }), - key: 'manage-event', - disabled: accountInfo.value?.isEmailVerified === false, - icon: renderIcon(VehicleShip24Filled), - }, - { - label: () => h(RouterLink, { to: { name: 'manage-point' } }, { default: () => '积分和礼物' }), - key: 'manage-point', - disabled: accountInfo.value?.isEmailVerified === false, - icon: renderIcon(BookCoins20Filled), - }, - { - label: () => h(RouterLink, { to: { name: 'manage-schedule' } }, { default: () => '日程' }), - key: 'manage-schedule', - icon: renderIcon(CalendarClock24Filled), - disabled: accountInfo.value?.isEmailVerified === false, - }, - { - label: () => h(RouterLink, { to: { name: 'manage-songList' } }, { default: () => '歌单' }), - key: 'manage-songList', - icon: renderIcon(MusicalNote), - disabled: accountInfo.value?.isEmailVerified === false, - }, - { - label: () => h(RouterLink, { to: { name: 'manage-questionBox' } }, { default: () => '棉花糖 (提问箱' }), - key: 'manage-questionBox', - icon: renderIcon(Chatbox), - disabled: accountInfo.value?.isEmailVerified === false, - }, - { - label: () => h(RouterLink, { to: { name: 'manage-videoCollect' } }, { default: () => '视频征集' }), - key: 'manage-videoCollect', - icon: renderIcon(VideoAdd20Filled), - disabled: accountInfo.value?.isEmailVerified === false, - }, - { - label: () => h(RouterLink, { to: { name: 'manage-lottery' } }, { default: () => '动态抽奖' }), - key: 'manage-lottery', - icon: renderIcon(Lottery24Filled), - }, - { - label: () => h( - NTooltip, - {}, - { - trigger: () => h( - NText, - () => [ - '弹幕相关', - h( +const menuOptions = computed(() => { + return [ + { + label: () => h(RouterLink, { to: { name: 'manage-history' } }, { default: () => '历史' }), + key: 'manage-history', + disabled: accountInfo.value?.isEmailVerified === false, + icon: renderIcon(AnalyticsSharp), + }, + { + label: () => h(RouterLink, { to: { name: 'manage-live' } }, { default: () => '直播记录' }), + key: 'manage-live', + disabled: accountInfo.value?.isEmailVerified === false, + icon: renderIcon(Live24Filled), + }, + { + label: () => h(RouterLink, { to: { name: 'manage-analyze' } }, { default: () => '直播数据' }), + key: 'manage-analyze', + disabled: accountInfo.value?.isEmailVerified === false, + icon: renderIcon(Eye), + }, + { + label: () => h(RouterLink, { to: { name: 'manage-event' } }, { default: () => '舰长和SC' }), + key: 'manage-event', + disabled: accountInfo.value?.isEmailVerified === false, + icon: renderIcon(VehicleShip24Filled), + }, + { + label: () => h(RouterLink, { to: { name: 'manage-point' } }, { default: () => '积分和礼物' }), + key: 'manage-point', + disabled: accountInfo.value?.isEmailVerified === false, + icon: renderIcon(BookCoins20Filled), + }, + { + label: () => h(RouterLink, { to: { name: 'manage-schedule' } }, { default: () => '日程' }), + key: 'manage-schedule', + icon: renderIcon(CalendarClock24Filled), + disabled: accountInfo.value?.isEmailVerified === false, + }, + { + label: () => h(RouterLink, { to: { name: 'manage-songList' } }, { default: () => '歌单' }), + key: 'manage-songList', + icon: renderIcon(MusicalNote), + disabled: accountInfo.value?.isEmailVerified === false, + }, + { + label: () => h(RouterLink, { to: { name: 'manage-questionBox' } }, { default: () => '棉花糖 (提问箱' }), + key: 'manage-questionBox', + icon: renderIcon(Chatbox), + disabled: accountInfo.value?.isEmailVerified === false, + }, + { + label: () => h(RouterLink, { to: { name: 'manage-videoCollect' } }, { default: () => '视频征集' }), + key: 'manage-videoCollect', + icon: renderIcon(VideoAdd20Filled), + disabled: accountInfo.value?.isEmailVerified === false, + }, + { + label: () => h(RouterLink, { to: { name: 'manage-lottery' } }, { default: () => '动态抽奖' }), + key: 'manage-lottery', + icon: renderIcon(Lottery24Filled), + }, + { + label: () => h( + NTooltip, + {}, + { + trigger: () => h( + NText, + () => [ + '弹幕相关', + h( + NTooltip, + { style: 'padding: 0;' }, + { + trigger: () => h(NIcon, { component: Info24Filled }), + default: () => h( + NAlert, + { + type: 'warning', + size: 'small', + title: '可用性警告', + style: 'max-width: 600px;', + }, + () => h('div', {}, [ + ' 当浏览器在后台运行时, 定时器和 Websocket 连接将受到严格限制, 这会导致弹幕接收功能无法正常工作 (详见', + h( + NButton, + { + text: true, + tag: 'a', + href: 'https://developer.chrome.com/blog/background_tabs/', + target: '_blank', + type: 'info', + }, + () => '此文章', + ), + '), 虽然本站已经针对此问题做出了处理, 一般情况下即使掉线了也会重连, 不过还是有可能会遗漏事件', + h('br'), + '为避免这种情况, 建议注册本站账后使用', + h( + NButton, + { + type: 'primary', + text: true, + size: 'small', + tag: 'a', + href: 'https://www.wolai.com/fje5wLtcrDoZcb9rk2zrFs', + target: '_blank', + }, + () => 'VtsuruEventFetcher', + ), + ', 否则请在使用功能时尽量保持网页在前台运行, 同时关闭浏览器的 页面休眠/内存节省 功能', + h('br'), + 'Chrome: ', + h( + NButton, + { + type: 'info', + text: true, + size: 'small', + tag: 'a', + href: 'https://support.google.com/chrome/answer/12929150?hl=zh-Hans#zippy=%2C%E5%BC%80%E5%90%AF%E6%88%96%E5%85%B3%E9%97%AD%E7%9C%81%E5%86%85%E5%AD%98%E6%A8%A1%E5%BC%8F%2C%E8%AE%A9%E7%89%B9%E5%AE%9A%E7%BD%91%E7%AB%99%E4%BF%9D%E6%8C%81%E6%B4%BB%E5%8A%A8%E7%8A%B6%E6%80%81', + target: '_blank', + }, + () => '让特定网站保持活动状态', + ), + ', Edge: ', + h( + NButton, + { + type: 'info', + text: true, + size: 'small', + tag: 'a', + href: 'https://support.microsoft.com/zh-cn/topic/%E4%BA%86%E8%A7%A3-microsoft-edge-%E4%B8%AD%E7%9A%84%E6%80%A7%E8%83%BD%E5%8A%9F%E8%83%BD-7b36f363-2119-448a-8de6-375cfd88ab25', + target: '_blank', + }, + () => '永远不想进入睡眠状态的网站', + ), + ]), + ), + }, + ), + ] + ), + default: () => isBiliVerified.value + ? '需要使用直播弹幕的功能' + : '你尚未进行 Bilibili 认证, 请前往面板进行绑定', + }, + ), + key: 'manage-danmaku', + icon: renderIcon(Chat24Filled), + disabled: accountInfo.value?.isEmailVerified === false || !isBiliVerified.value, + children: [ + { + label: () => !isBiliVerified.value ? '弹幕机' : h( + NBadge, + { value: '新', offset: [15, 12], type: 'info' }, + () => h( NTooltip, - { style: 'padding: 0;' }, + {}, { - trigger: () => h(NIcon, { component: Info24Filled }), - default: () => h( - NAlert, - { - type: 'warning', - size: 'small', - title: '可用性警告', - style: 'max-width: 600px;', - }, - () => h('div', {}, [ - ' 当浏览器在后台运行时, 定时器和 Websocket 连接将受到严格限制, 这会导致弹幕接收功能无法正常工作 (详见', - h( - NButton, - { - text: true, - tag: 'a', - href: 'https://developer.chrome.com/blog/background_tabs/', - target: '_blank', - type: 'info', - }, - () => '此文章', - ), - '), 虽然本站已经针对此问题做出了处理, 一般情况下即使掉线了也会重连, 不过还是有可能会遗漏事件', - h('br'), - '为避免这种情况, 建议注册本站账后使用', - h( - NButton, - { - type: 'primary', - text: true, - size: 'small', - tag: 'a', - href: 'https://www.wolai.com/fje5wLtcrDoZcb9rk2zrFs', - target: '_blank', - }, - () => 'VtsuruEventFetcher', - ), - ', 否则请在使用功能时尽量保持网页在前台运行, 同时关闭浏览器的 页面休眠/内存节省 功能', - h('br'), - 'Chrome: ', - h( - NButton, - { - type: 'info', - text: true, - size: 'small', - tag: 'a', - href: 'https://support.google.com/chrome/answer/12929150?hl=zh-Hans#zippy=%2C%E5%BC%80%E5%90%AF%E6%88%96%E5%85%B3%E9%97%AD%E7%9C%81%E5%86%85%E5%AD%98%E6%A8%A1%E5%BC%8F%2C%E8%AE%A9%E7%89%B9%E5%AE%9A%E7%BD%91%E7%AB%99%E4%BF%9D%E6%8C%81%E6%B4%BB%E5%8A%A8%E7%8A%B6%E6%80%81', - target: '_blank', - }, - () => '让特定网站保持活动状态', - ), - ', Edge: ', - h( - NButton, - { - type: 'info', - text: true, - size: 'small', - tag: 'a', - href: 'https://support.microsoft.com/zh-cn/topic/%E4%BA%86%E8%A7%A3-microsoft-edge-%E4%B8%AD%E7%9A%84%E6%80%A7%E8%83%BD%E5%8A%9F%E8%83%BD-7b36f363-2119-448a-8de6-375cfd88ab25', - target: '_blank', - }, - () => '永远不想进入睡眠状态的网站', - ), - ]), + trigger: () => h( + RouterLink, + { to: { name: 'manage-danmuji' } }, + { default: () => '弹幕机' }, ), - }, - ), - ] - ), - default: () => accountInfo.value?.isBiliVerified - ? '需要使用直播弹幕的功能' - : '你尚未进行 Bilibili 认证, 请前往面板进行绑定', - }, - ), - key: 'manage-danmaku', - icon: renderIcon(Chat24Filled), - disabled: accountInfo.value?.isEmailVerified === false, - children: [ - { - label: () => h( - NBadge, - { value: '新', offset: [15, 12], type: 'info' }, - () => h( + default: () => '兼容 blivechat 样式 (其实就是直接用的 blivechat 组件', + } + ) + ), + key: 'manage-danmuji', + disabled: !isBiliVerified.value, + icon: renderIcon(Lottery24Filled), + }, + { + label: () => !isBiliVerified.value ? '抽奖' : h( + RouterLink, + { to: { name: 'manage-liveLottery' } }, + { default: () => '抽奖' }, + ), + key: 'manage-liveLottery', + icon: renderIcon(Lottery24Filled), + disabled: !isBiliVerified.value, + }, + { + label: () => !isBiliVerified.value ? '点播' : h( NTooltip, {}, { trigger: () => h( RouterLink, - { to: { name: 'manage-danmuji' } }, - { default: () => '弹幕机' }, + { to: { name: 'manage-liveRequest' } }, + { default: () => '点播' }, ), - default: () => '兼容 blivechat 样式 (其实就是直接用的 blivechat 组件', - } - ) - ), - key: 'manage-danmuji', - icon: renderIcon(Lottery24Filled), - }, - { - label: () => h( - RouterLink, - { to: { name: 'manage-liveLottery' } }, - { default: () => '抽奖' }, - ), - key: 'manage-liveLottery', - icon: renderIcon(Lottery24Filled), - }, - { - label: () => h( - NTooltip, - {}, - { - trigger: () => h( - RouterLink, - { to: { name: 'manage-liveRequest' } }, - { default: () => '点播' }, - ), - default: () => '歌势之类用的, 可以用来点歌或者跳舞什么的', - }, - ), - key: 'manage-liveRequest', - icon: renderIcon(MusicalNote), - }, - { - label: () => h( - NTooltip, - {}, - { - trigger: () => h( - RouterLink, - { to: { name: 'manage-musicRequest' } }, - { default: () => '点歌' }, - ), - default: () => '就是传统的点歌机, 发弹幕后播放指定的歌曲', - }, - ), - key: 'manage-musicRequest', - icon: renderIcon(MusicalNote), - }, - { - label: () => h( - RouterLink, - { to: { name: 'manage-liveQueue' } }, - { default: () => '排队' }, - ), - key: 'manage-liveQueue', - icon: renderIcon(PeopleQueue24Filled), - }, - { - label: () => h( - RouterLink, - { to: { name: 'manage-speech' } }, - { default: () => '读弹幕' }, - ), - key: 'manage-speech', - icon: renderIcon(TabletSpeaker24Filled), - }, - ], - }, -] + default: () => '歌势之类用的, 可以用来点歌或者跳舞什么的', + }, + ), + key: 'manage-liveRequest', + icon: renderIcon(MusicalNote), + disabled: !isBiliVerified.value, + }, + { + label: () => !isBiliVerified.value ? '点歌' : h( + NTooltip, + {}, + { + trigger: () => h( + RouterLink, + { to: { name: 'manage-musicRequest' } }, + { default: () => '点歌' }, + ), + default: () => '就是传统的点歌机, 发弹幕后播放指定的歌曲', + }, + ), + key: 'manage-musicRequest', + icon: renderIcon(MusicalNote), + disabled: !isBiliVerified.value, + }, + { + label: () => !isBiliVerified.value ? '排队' : h( + RouterLink, + { to: { name: 'manage-liveQueue' } }, + { default: () => '排队' }, + ), + key: 'manage-liveQueue', + icon: renderIcon(PeopleQueue24Filled), + disabled: !isBiliVerified.value, + }, + { + label: () => !isBiliVerified.value ? '读弹幕' : h( + RouterLink, + { to: { name: 'manage-speech' } }, + { default: () => '读弹幕' }, + ), + key: 'manage-speech', + icon: renderIcon(TabletSpeaker24Filled), + disabled: !isBiliVerified.value, + }, + ], + }, + ] +}) // 重发验证邮件 async function resendEmail() { @@ -385,7 +394,7 @@ onMounted(() => {