From f8fb84971441eb5248f84361e2f41beeb321518d Mon Sep 17 00:00:00 2001 From: lkddi Date: Sat, 25 Apr 2026 14:04:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E8=81=8A=E5=A4=A9=E5=AE=A4?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E7=8A=B6=E6=80=81=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/chat-room.js | 4 + resources/js/chat-room/initial-state.js | 143 ++++++++++++++++++++++++ resources/views/chat/frame.blade.php | 96 ++-------------- 3 files changed, 158 insertions(+), 85 deletions(-) create mode 100644 resources/js/chat-room/initial-state.js diff --git a/resources/js/chat-room.js b/resources/js/chat-room.js index 5f34b4b..2d673bb 100644 --- a/resources/js/chat-room.js +++ b/resources/js/chat-room.js @@ -42,6 +42,7 @@ export { bindGameHallControls } from "./chat-room/game-hall.js"; export { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js"; export { bindGamePanelControls } from "./chat-room/game-panels.js"; export { bindHolidayModalControls, openHolidayRunFromSystemMessage } from "./chat-room/holiday-modal.js"; +export { bindChatInitialStateControls } from "./chat-room/initial-state.js"; export { bankAction, bankLoadInfo, @@ -125,6 +126,7 @@ import { bindGameHallControls } from "./chat-room/game-hall.js"; import { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js"; import { bindGamePanelControls } from "./chat-room/game-panels.js"; import { bindHolidayModalControls, openHolidayRunFromSystemMessage } from "./chat-room/holiday-modal.js"; +import { bindChatInitialStateControls } from "./chat-room/initial-state.js"; import { bankAction, bankLoadInfo, @@ -221,6 +223,7 @@ if (typeof window !== "undefined") { bindGamePanelControls, bindHolidayModalControls, openHolidayRunFromSystemMessage, + bindChatInitialStateControls, loadAdminCurrentLossCoverEvent, openAdminBaccaratLossCoverModal, submitBaccaratLossCoverEvent, @@ -329,6 +332,7 @@ if (typeof window !== "undefined") { bindGameBootstrapControls(); bindGamePanelControls(); bindHolidayModalControls(); + bindChatInitialStateControls(); bindBankControls(); bindFishingControls(); bindMarriageStatusControls(); diff --git a/resources/js/chat-room/initial-state.js b/resources/js/chat-room/initial-state.js new file mode 100644 index 0000000..7890a6e --- /dev/null +++ b/resources/js/chat-room/initial-state.js @@ -0,0 +1,143 @@ +// 聊天室页面初始状态恢复,负责首屏历史消息、入场特效和挂起婚姻事件。 + +/** + * DOM 就绪后执行回调。 + * + * @param {Function} callback + * @returns {void} + */ +function onDomReady(callback) { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", callback, { once: true }); + return; + } + + callback(); +} + +/** + * 追加一条聊天消息,等待核心聊天脚本暴露 appendMessage。 + * + * @param {object} message + * @returns {void} + */ +function appendInitialMessage(message) { + if (typeof window.appendMessage === "function") { + window.appendMessage(message); + } +} + +/** + * 恢复页面初始历史消息。 + * + * @param {object} initialState + * @returns {void} + */ +function restoreHistoryMessages(initialState) { + const messages = Array.isArray(initialState.historyMessages) ? initialState.historyMessages : []; + if (messages.length === 0) { + return; + } + + const clearId = Number.parseInt(localStorage.getItem(initialState.localClearStorageKey || "") || "0", 10); + + messages.forEach((message) => { + // 本地清屏后,只恢复清屏点之后的新消息。 + if (Number(message.id || 0) > clearId) { + appendInitialMessage(message); + } + }); +} + +/** + * 追加页面入场欢迎消息。 + * + * @param {object} initialState + * @returns {void} + */ +function appendWelcomeMessage(initialState) { + if (!initialState.welcomeMessage) { + return; + } + + window.setTimeout(() => appendInitialMessage(initialState.welcomeMessage), 220); +} + +/** + * 播放页面入场特效。 + * + * @param {object} initialState + * @returns {void} + */ +function playEntryEffect(initialState) { + if (!initialState.entryEffect) { + return; + } + + window.setTimeout(() => { + window.EffectManager?.play?.(initialState.entryEffect); + }, 1000); +} + +/** + * 显示会员进出场横幅。 + * + * @param {object} initialState + * @returns {void} + */ +function showInitialPresenceBanner(initialState) { + if (!initialState.presenceTheme) { + return; + } + + window.setTimeout(() => { + window.showVipPresenceBanner?.(initialState.presenceTheme); + }, 700); +} + +/** + * 派发挂起的求婚或离婚请求事件。 + * + * @param {object} initialState + * @returns {void} + */ +function dispatchPendingMarriageEvents(initialState) { + if (!initialState.pendingProposal && !initialState.pendingDivorce) { + return; + } + + window.setTimeout(() => { + if (initialState.pendingProposal) { + window.dispatchEvent(new CustomEvent("chat:marriage-proposed", { + detail: initialState.pendingProposal, + })); + } + + if (initialState.pendingDivorce) { + window.dispatchEvent(new CustomEvent("chat:divorce-requested", { + detail: initialState.pendingDivorce, + })); + } + }, 800); +} + +/** + * 绑定聊天室页面初始状态恢复。 + * + * @returns {void} + */ +export function bindChatInitialStateControls() { + if (typeof window === "undefined") { + return; + } + + onDomReady(() => { + const initialState = window.chatContext?.initialState || {}; + + restoreHistoryMessages(initialState); + appendWelcomeMessage(initialState); + playEntryEffect(initialState); + showInitialPresenceBanner(initialState); + dispatchPendingMarriageEvents(initialState); + }); +} diff --git a/resources/views/chat/frame.blade.php b/resources/views/chat/frame.blade.php index b3c0b5a..21f0e0f 100644 --- a/resources/views/chat/frame.blade.php +++ b/resources/views/chat/frame.blade.php @@ -124,7 +124,16 @@ envelopeStatusUrl: (id) => `/wedding/${id}/envelope-status`, }, earnRewardUrl: "{{ route('earn.video_reward') }}", - chatImageRetentionDays: 3 + chatImageRetentionDays: 3, + initialState: { + historyMessages: @json($historyMessages ?? []), + localClearStorageKey: "local_clear_msg_id_{{ $room->id }}", + welcomeMessage: @json($initialWelcomeMessage ?? null), + entryEffect: @json($newbieEffect ?: ($initialPresenceTheme['presence_effect'] ?? ($weekEffect ?? null))), + presenceTheme: @json($initialPresenceTheme ?? null), + pendingProposal: @json($pendingProposal ?? null), + pendingDivorce: @json($pendingDivorce ?? null), + } }; @vite(['resources/css/app.css', 'resources/js/app.js', 'resources/js/chat.js']) @@ -236,90 +245,7 @@ {{-- 辅助与全局事件组件 --}} @include('chat.partials.ai-chatbot') @include('chat.partials.system-events') - {{-- 页面初始加载时,渲染自带的历史记录(解决入场欢迎语错过断网的问题) --}} - @if (!empty($historyMessages)) - - @endif - @if (!empty($initialWelcomeMessage)) - - @endif - @if (!empty($newbieEffect) || !empty($weekEffect) || !empty($initialPresenceTheme['presence_effect'])) - - @endif - @if (!empty($initialPresenceTheme)) - - @endif - - {{-- 页面初始加载时,若存在挂起的求婚 / 离婚请求,则弹窗 --}} - @if (!empty($pendingProposal) || !empty($pendingDivorce)) - - @endif + {{-- 初始历史消息、入场欢迎、进场特效、会员横幅和挂起婚姻事件已迁移到 resources/js/chat-room/initial-state.js --}}