diff --git a/package-lock.json b/package-lock.json index f35e808f05..12ad1728b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@mdi/js": "^7.4.47", "@sapphi-red/web-noise-suppressor": "^0.3.5", + "@shiguredo/virtual-background": "^2023.2.0", "@traptitech/traq": "^3.17.0-3", "@traptitech/traq-markdown-it": "^6.3.0", "autosize": "^6.0.1", @@ -20,7 +21,9 @@ "firebase": "^11.2.0", "highlight.js": "^11.11.1", "idb-keyval": "^6.2.0", + "livekit-client": "^2.8.0", "mitt": "^3.0.0", + "party-js": "^2.2.0", "skyway-js": "^4.4.5", "text-field-edit": "^4.1.1", "throttle-debounce": "^5.0.2", @@ -1664,6 +1667,11 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3220,6 +3228,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@livekit/mutex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@livekit/mutex/-/mutex-1.1.1.tgz", + "integrity": "sha512-EsshAucklmpuUAfkABPxJNhzj9v2sG7JuzFDL4ML1oJQSV14sqrpTYnsaOudMAw9yOaW53NU3QQTlUQoRs4czw==" + }, + "node_modules/@livekit/protocol": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@livekit/protocol/-/protocol-1.30.0.tgz", + "integrity": "sha512-SDI9ShVKj8N3oOSinr8inaxD3FXgmgoJlqN35uU/Yx1sdoDeQbzAuBFox7bYjM+VhnZ1V22ivIDjAsKr00H+XQ==", + "dependencies": { + "@bufbuild/protobuf": "^1.10.0" + } + }, "node_modules/@mdi/js": { "version": "7.4.47", "resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.4.47.tgz", @@ -3997,6 +4018,14 @@ "resolved": "https://registry.npmjs.org/@sapphi-red/web-noise-suppressor/-/web-noise-suppressor-0.3.5.tgz", "integrity": "sha512-jh3+V9yM+zxLriQexoGm0GatoPaJWjs6ypFIbFYwQp+AoUb55eUXrjKtKQyuC5zShzzeAQUl0M5JzqB7SSrsRA==" }, + "node_modules/@shiguredo/virtual-background": { + "version": "2023.2.0", + "resolved": "https://registry.npmjs.org/@shiguredo/virtual-background/-/virtual-background-2023.2.0.tgz", + "integrity": "sha512-nvJAsf29ThXMN7tEvlvZ45MeIoXW2uoJxvBwsesYInjoSy0RASQr7qxrLMglX2yyztOeYZqJknQBttjJTGH/QA==", + "dependencies": { + "@types/dom-mediacapture-transform": "^0.1.4" + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -4121,12 +4150,25 @@ "integrity": "sha512-o0ZyU3ePp3+KRbhHsY4ogjc+ZQWgVN5h6j8BHW5RII4cFKi6PEKK9QPAcphJVkD0dGpyFnD3VRR0WMvHVjCv9w==", "dev": true }, + "node_modules/@types/dom-mediacapture-transform": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-transform/-/dom-mediacapture-transform-0.1.10.tgz", + "integrity": "sha512-zUxMN2iShu7p3Fz5sqfvLp93qW/3sLs+RwXWWOkMb969hsuoVqUUokqrENjXqTMNmEEcVXKoHuMMbIGcWyrVVA==", + "dependencies": { + "@types/dom-webcodecs": "*" + } + }, "node_modules/@types/dom-screen-wake-lock": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.3.tgz", "integrity": "sha512-3Iten7X3Zgwvk6kh6/NRdwN7WbZ760YgFCsF5AxDifltUQzW1RaW+WRmcVtgwFzLjaNu64H+0MPJ13yRa8g3Dw==", "dev": true }, + "node_modules/@types/dom-webcodecs": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==" + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -8777,6 +8819,22 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/livekit-client": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.8.0.tgz", + "integrity": "sha512-8/IXhacAFYdXMU1wFyc8/MSGCzHr02Hn9T5o3MX19TR03RHSaBKBF2xK8fQFINBmpcYkiMAnQL0P6K3nfcifQA==", + "dependencies": { + "@livekit/mutex": "1.1.1", + "@livekit/protocol": "1.30.0", + "events": "^3.3.0", + "loglevel": "^1.8.0", + "sdp-transform": "^2.14.1", + "ts-debounce": "^4.0.0", + "tslib": "2.8.1", + "typed-emitter": "^2.1.0", + "webrtc-adapter": "^9.0.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -8892,6 +8950,18 @@ "node": ">=8" } }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, "node_modules/long": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", @@ -9412,6 +9482,11 @@ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" }, + "node_modules/party-js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/party-js/-/party-js-2.2.0.tgz", + "integrity": "sha512-50hGuALCpvDTrQLPQ1fgUgxKIWAH28ShVkmeK/3zhO0YJyCqkhrZhQEkWPxDYLvbFJ7YAXyROmFEu35gKpZLtQ==" + }, "node_modules/patch-package": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", @@ -10163,7 +10238,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, + "devOptional": true, "dependencies": { "tslib": "^2.1.0" } @@ -10260,6 +10335,11 @@ "node": ">=v12.22.7" } }, + "node_modules/sdp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", + "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==" + }, "node_modules/sdp-transform": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.2.tgz", @@ -11213,6 +11293,11 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-debounce": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ts-debounce/-/ts-debounce-4.0.0.tgz", + "integrity": "sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==" + }, "node_modules/ts-pattern": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.6.1.tgz", @@ -11360,6 +11445,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "optionalDependencies": { + "rxjs": "*" + } + }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", @@ -12987,6 +13080,18 @@ "node": ">=12" } }, + "node_modules/webrtc-adapter": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz", + "integrity": "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==", + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", diff --git a/package.json b/package.json index 14289a448f..27cfe22ca8 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "@mdi/js": "^7.4.47", "@sapphi-red/web-noise-suppressor": "^0.3.5", + "@shiguredo/virtual-background": "^2023.2.0", "@traptitech/traq": "^3.17.0-3", "@traptitech/traq-markdown-it": "^6.3.0", "autosize": "^6.0.1", @@ -37,7 +38,9 @@ "firebase": "^11.2.0", "highlight.js": "^11.11.1", "idb-keyval": "^6.2.0", + "livekit-client": "^2.8.0", "mitt": "^3.0.0", + "party-js": "^2.2.0", "skyway-js": "^4.4.5", "text-field-edit": "^4.1.1", "throttle-debounce": "^5.0.2", @@ -51,8 +54,8 @@ "zod": "^3.24.1" }, "devDependencies": { - "@stylistic/eslint-plugin-ts": "^2.13.0", "@pinia/testing": "^0.1.6", + "@stylistic/eslint-plugin-ts": "^2.13.0", "@types/autosize": "^4.0.3", "@types/dom-screen-wake-lock": "^1.0.3", "@types/katex": "^0.16.7", @@ -63,9 +66,9 @@ "@types/throttle-debounce": "^5.0.2", "@types/turndown": "^5.0.5", "@types/vue-select": "^3.16.8", + "@types/webappsec-credential-management": "^0.6.9", "@typescript-eslint/eslint-plugin": "^8.20.0", "@typescript-eslint/parser": "^8.20.0", - "@types/webappsec-credential-management": "^0.6.9", "@typescript/lib-dom": "npm:@types/web@^0.0.72", "@vitejs/plugin-vue": "^5.2.1", "@vitest/coverage-v8": "^2.1.8", @@ -73,14 +76,14 @@ "autoprefixer": "^10.4.20", "axios": "^1.7.9", "browserslist": "^4.24.4", + "cypress": "^13.17.0", + "esbuild": "^0.24.2", + "esbuild-plugin-browserslist": "^0.15.0", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-cypress": "^4.1.0", "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-vue": "^9.32.0", - "cypress": "^13.17.0", - "esbuild": "^0.24.2", - "esbuild-plugin-browserslist": "^0.15.0", "fonteditor-core": "^2.4.1", "jsdom": "^26.0.0", "patch-package": "^8.0.0", diff --git a/src/App.vue b/src/App.vue index f3a67b06cb..ce16092de2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -17,14 +17,15 @@ import useHtmlDataset from '/@/composables/document/useHtmlDataset' import { useThemeVariables } from '/@/composables/document/useThemeVariables' import { useResponsiveStore } from '/@/store/ui/responsive' import { useBrowserSettings } from '/@/store/app/browserSettings' -import { useAppRtcStore } from '/@/store/app/rtc' import { useTts } from '/@/store/app/tts' import { useThemeSettings } from '/@/store/app/themeSettings' import useDocumentTitle from '/@/composables/document/useDocumentTitle' const useQallConfirmer = () => { - const { isCurrentDevice } = useAppRtcStore() window.addEventListener('beforeunload', event => { + // TODO: Qall + // ここは適切な変数を置く + const isCurrentDevice = computed(() => false) if (isCurrentDevice.value) { const unloadMessage = 'Qall中ですが本当に終了しますか?' event.preventDefault() diff --git a/src/assets/icons/add_reaction.svg b/src/assets/icons/add_reaction.svg new file mode 100644 index 0000000000..f93c6d661f --- /dev/null +++ b/src/assets/icons/add_reaction.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/call_end.svg b/src/assets/icons/call_end.svg new file mode 100644 index 0000000000..f70c5d3a3a --- /dev/null +++ b/src/assets/icons/call_end.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/group_qall.svg b/src/assets/icons/group_qall.svg new file mode 100644 index 0000000000..903365b189 --- /dev/null +++ b/src/assets/icons/group_qall.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/mic.svg b/src/assets/icons/mic.svg new file mode 100644 index 0000000000..ac0583091f --- /dev/null +++ b/src/assets/icons/mic.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/icons/mic_off.svg b/src/assets/icons/mic_off.svg new file mode 100644 index 0000000000..1d544dd91f --- /dev/null +++ b/src/assets/icons/mic_off.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/screen-share.svg b/src/assets/icons/screen-share.svg new file mode 100644 index 0000000000..d3d66c0b50 --- /dev/null +++ b/src/assets/icons/screen-share.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/sound_detection_loud_sound.svg b/src/assets/icons/sound_detection_loud_sound.svg new file mode 100644 index 0000000000..b506f23f79 --- /dev/null +++ b/src/assets/icons/sound_detection_loud_sound.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/stop-screen-share.svg b/src/assets/icons/stop-screen-share.svg new file mode 100644 index 0000000000..6949cc3ce0 --- /dev/null +++ b/src/assets/icons/stop-screen-share.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/videocam.svg b/src/assets/icons/videocam.svg new file mode 100644 index 0000000000..c267aa9bf4 --- /dev/null +++ b/src/assets/icons/videocam.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/icons/videocam_off.svg b/src/assets/icons/videocam_off.svg new file mode 100644 index 0000000000..e93196c843 --- /dev/null +++ b/src/assets/icons/videocam_off.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/mdi.ts b/src/assets/mdi.ts index 2130c677b9..05e7af93f6 100644 --- a/src/assets/mdi.ts +++ b/src/assets/mdi.ts @@ -24,18 +24,23 @@ import { mdiEmail, mdiTag, mdiPlus, + mdiPlusCircle, mdiMagnify, mdiHistory, mdiDownload, mdiEmoticonOutline, mdiCog, mdiAccount, + mdiAccountMultiple, + mdiAccountMinus, mdiCogs, mdiBrightness6, mdiPencilOutline, mdiToggleSwitchOff, mdiToggleSwitch, mdiChevronDoubleLeft, + mdiChevronDoubleUp, + mdiChevronDoubleDown, mdiChevronLeft, mdiChevronRight, mdiBookmark, @@ -80,7 +85,11 @@ import { mdiFormatTitle, mdiCloseCircle, mdiNotebook, - mdiDelete + mdiDelete, + mdiVideo, + mdiVideoOff, + mdiCommentTextMultipleOutline, + mdiCommentOffOutline } from '@mdi/js' interface MdiIconsMapping { @@ -117,10 +126,13 @@ const mdi: MdiIconsMapping = { tags: mdiTagMultiple, email: mdiEmail, plus: mdiPlus, + 'plus-circle': mdiPlusCircle, download: mdiDownload, 'emoticon-outline': mdiEmoticonOutline, cog: mdiCog, account: mdiAccount, + 'account-multiple': mdiAccountMultiple, + 'account-minus': mdiAccountMinus, cogs: mdiCogs, 'brightness-6': mdiBrightness6, pencil: mdiPencil, @@ -128,6 +140,8 @@ const mdi: MdiIconsMapping = { 'toggle-switch-off': mdiToggleSwitchOff, 'toggle-switch-on': mdiToggleSwitch, 'chevron-double': mdiChevronDoubleLeft, + 'chevron-double-up': mdiChevronDoubleUp, + 'chevron-double-down': mdiChevronDoubleDown, 'chevron-left': mdiChevronLeft, 'chevron-right': mdiChevronRight, 'chevron-up': mdiChevronUp, @@ -169,7 +183,11 @@ const mdi: MdiIconsMapping = { stop: mdiStop, crown: mdiCrown, 'format-title': mdiFormatTitle, - delete: mdiDelete + delete: mdiDelete, + video: mdiVideo, + 'video-off': mdiVideoOff, + 'comment-outline': mdiCommentTextMultipleOutline, + 'comment-off-outline': mdiCommentOffOutline } export default mdi diff --git a/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderToolsList.vue b/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderToolsList.vue index 09b79d83ea..e7fe77bc34 100644 --- a/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderToolsList.vue +++ b/src/components/Main/MainView/ChannelView/ChannelHeader/ChannelHeaderToolsList.vue @@ -2,15 +2,15 @@