From fd1518db1d5ca95f7e51fb1bef59f02a75425490 Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 9 Oct 2023 22:43:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=94=9F=E6=88=90=E5=99=A8?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E6=94=BE=E5=88=B0iframe=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=BD=B1=E5=93=8D=E5=88=B0=E5=A4=96=E9=9D=A2=E7=BD=91?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/chat/ChatClientTest.js | 3 ++ frontend/src/views/Room.vue | 42 +++++++++++++--- frontend/src/views/StyleGenerator/index.vue | 56 ++++++++++----------- 3 files changed, 66 insertions(+), 35 deletions(-) diff --git a/frontend/src/api/chat/ChatClientTest.js b/frontend/src/api/chat/ChatClientTest.js index 64ae247..ea70265 100644 --- a/frontend/src/api/chat/ChatClientTest.js +++ b/frontend/src/api/chat/ChatClientTest.js @@ -262,6 +262,9 @@ export default class ChatClientTest { } else { sleepTime = randInt(0, 400) } + if (this.timerId) { + window.clearTimeout(this.timerId) + } this.timerId = window.setTimeout(this.onTimeout.bind(this), sleepTime) } diff --git a/frontend/src/views/Room.vue b/frontend/src/views/Room.vue index b307f47..24dcc75 100644 --- a/frontend/src/views/Room.vue +++ b/frontend/src/views/Room.vue @@ -32,11 +32,16 @@ export default { } }, data() { + let customStyleElement = document.createElement('style') + document.head.appendChild(customStyleElement) return { config: chatConfig.deepCloneDefaultConfig(), + chatClient: null, + textEmoticons: [], // 官方的文本表情(后端配置的) pronunciationConverter: null, - textEmoticons: [], // 官方的文本表情 + + customStyleElement, // 仅用于样式生成器中预览样式 } }, computed: { @@ -79,12 +84,18 @@ export default { // 当前窗口不可见,延迟到可见时加载,防止OBS中一次并发太多请求(OBS中浏览器不可见时也会加载网页,除非显式设置) document.addEventListener('visibilitychange', this.onVisibilityChange) } + + window.addEventListener('message', this.onWindowMessage) }, beforeDestroy() { + window.removeEventListener('message', this.onWindowMessage) + document.removeEventListener('visibilitychange', this.onVisibilityChange) if (this.chatClient) { this.chatClient.stop() } + + document.head.removeChild(this.customStyleElement) }, methods: { onVisibilityChange() { @@ -105,6 +116,7 @@ export default { } try { + // 其他初始化就不用等了,就算失败了也不会有很大影响 await initChatClientPromise } catch (e) { this.$message.error({ @@ -199,11 +211,29 @@ export default { this.textEmoticons = await chat.getTextEmoticons() }, - start() { - this.chatClient.start() - }, - stop() { - this.chatClient.stop() + // 处理样式生成器发送的消息 + onWindowMessage(event) { + if (event.origin !== window.location.origin) { + console.warn(`消息origin错误,${event.origin} != ${window.location.origin}`) + return + } + + let { type, data } = event.data + switch (type) { + case 'roomSetCustomStyle': + this.customStyleElement.innerText = data.css + break + case 'roomStartClient': + if (this.chatClient) { + this.chatClient.start() + } + break + case 'roomStopClient': + if (this.chatClient) { + this.chatClient.stop() + } + break + } }, onAddText(data) { diff --git a/frontend/src/views/StyleGenerator/index.vue b/frontend/src/views/StyleGenerator/index.vue index 5f318d7..1c8a12d 100644 --- a/frontend/src/views/StyleGenerator/index.vue +++ b/frontend/src/views/StyleGenerator/index.vue @@ -28,16 +28,16 @@
- +
-
- -
+
@@ -52,17 +52,11 @@ import LineLike from './LineLike' export default { name: 'StyleGenerator', - components: { - Legacy, - LineLike, - Room: () => import('@/views/Room'), - }, + components: { Legacy, LineLike }, data() { - let styleElement = document.createElement('style') - document.head.appendChild(styleElement) // 数据流: // 输入框 --\ - // 子组件 -> subComponentResults -> subComponentResult -> inputResult -> 防抖延迟0.5s后 -> debounceResult -> exampleCss + // 子组件 -> subComponentResults -> subComponentResult -> inputResult -> 防抖延迟0.5s后 -> debounceResult return { // 子组件的结果 subComponentResults: { @@ -75,20 +69,18 @@ export default { // 防抖后延迟变化的结果 debounceResult: '', - styleElement, exampleTop: 0, playAnimation: true, exampleBgLight: false } }, computed: { + exampleRoomUrl() { + return this.$router.resolve({ name: 'test_room', query: { lang: this.$i18n.locale } }).href + }, // 子组件的结果 subComponentResult() { return this.subComponentResults[this.activeTab] - }, - // 应用到预览上的CSS - exampleCss() { - return this.debounceResult.replace(/^body\b/gm, '#fakebody') } }, watch: { @@ -98,9 +90,7 @@ export default { inputResult: _.debounce(function(val) { this.debounceResult = val }, 500), - exampleCss(val) { - this.styleElement.innerText = val - } + debounceResult: 'setExampleRoomCustomCss' }, mounted() { this.debounceResult = this.inputResult = this.subComponentResult @@ -109,8 +99,6 @@ export default { }, beforeDestroy() { this.$parent.$el.removeEventListener('scroll', this.onParentScroll) - - document.head.removeChild(this.styleElement) }, methods: { onParentScroll(event) { @@ -120,13 +108,22 @@ export default { this.exampleTop = event.target.scrollTop } }, - onPlayAnimationChange(value) { - if (value) { - this.$refs.room.start() - } else { - this.$refs.room.stop() - } + + onExampleRoomLoad() { + this.setExampleRoomCustomCss(this.debounceResult) + this.setExampleRoomClientStart(this.playAnimation) + }, + setExampleRoomCustomCss(css) { + this.sendMessageToExampleRoom('roomSetCustomStyle', { css }) }, + setExampleRoomClientStart(isStart) { + this.sendMessageToExampleRoom(isStart ? 'roomStartClient' : 'roomStopClient') + }, + sendMessageToExampleRoom(type, data = null) { + let msg = { type, data } + this.$refs.exampleRoomIframe.contentWindow.postMessage(msg, window.location.origin) + }, + copyResult() { this.$refs.result.select() document.execCommand('Copy') @@ -181,8 +178,9 @@ export default { -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #eee)); } -#fakebody { +#example-room-iframe { outline: 1px #999 dashed; + width: 100%; height: 100%; }