迁移婚姻通知弹窗组件
This commit is contained in:
@@ -94,7 +94,16 @@ export {
|
||||
switchMarriageTab,
|
||||
tryDivorce,
|
||||
} from "./chat-room/marriage-status.js";
|
||||
export { appendSystemMessage, bindMarriageModalControls, marriageProposeModal, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js";
|
||||
export {
|
||||
appendSystemMessage,
|
||||
bindMarriageModalControls,
|
||||
marriageAcceptedModal,
|
||||
marriageDivorcedModal,
|
||||
marriageIncomingModal,
|
||||
marriageProposeModal,
|
||||
openProposeModal,
|
||||
openWeddingSetupModal,
|
||||
} from "./chat-room/marriage-modals.js";
|
||||
export { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||
export { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||
export { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||
@@ -266,7 +275,16 @@ import {
|
||||
switchMarriageTab,
|
||||
tryDivorce,
|
||||
} from "./chat-room/marriage-status.js";
|
||||
import { appendSystemMessage, bindMarriageModalControls, marriageProposeModal, openProposeModal, openWeddingSetupModal } from "./chat-room/marriage-modals.js";
|
||||
import {
|
||||
appendSystemMessage,
|
||||
bindMarriageModalControls,
|
||||
marriageAcceptedModal,
|
||||
marriageDivorcedModal,
|
||||
marriageIncomingModal,
|
||||
marriageProposeModal,
|
||||
openProposeModal,
|
||||
openWeddingSetupModal,
|
||||
} from "./chat-room/marriage-modals.js";
|
||||
import { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||
import { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||
import { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||
@@ -531,6 +549,9 @@ if (typeof window !== "undefined") {
|
||||
bindMarriageStatusControls,
|
||||
appendSystemMessage,
|
||||
bindMarriageModalControls,
|
||||
marriageAcceptedModal,
|
||||
marriageDivorcedModal,
|
||||
marriageIncomingModal,
|
||||
marriageProposeModal,
|
||||
closeMarriageStatusModal,
|
||||
fetchMarriedList,
|
||||
@@ -715,6 +736,9 @@ if (typeof window !== "undefined") {
|
||||
window.marriageAction = marriageAction;
|
||||
window.openMarriageStatusModal = openMarriageStatusModal;
|
||||
window.appendSystemMessage = appendSystemMessage;
|
||||
window.marriageAcceptedModal = marriageAcceptedModal;
|
||||
window.marriageDivorcedModal = marriageDivorcedModal;
|
||||
window.marriageIncomingModal = marriageIncomingModal;
|
||||
window.marriageProposeModal = marriageProposeModal;
|
||||
window.openProposeModal = openProposeModal;
|
||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
||||
|
||||
@@ -201,6 +201,176 @@ export function marriageProposeModal() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建收到求婚弹窗 Alpine 数据,处理同意和拒绝求婚。
|
||||
*
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
export function marriageIncomingModal() {
|
||||
return {
|
||||
show: false,
|
||||
proposerName: "",
|
||||
marriageId: null,
|
||||
ringName: "",
|
||||
ringIcon: "💍",
|
||||
expiresAt: "",
|
||||
acting: false,
|
||||
|
||||
open(detail) {
|
||||
this.proposerName = detail.proposer_name || detail.proposer?.username || "";
|
||||
this.marriageId = detail.marriage_id;
|
||||
this.ringName = detail.ring_name || "";
|
||||
this.ringIcon = detail.ring_icon || "💍";
|
||||
this.expiresAt = detail.expires_at || "";
|
||||
this.show = true;
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
},
|
||||
|
||||
async doAccept() {
|
||||
if (this.acting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.acting = true;
|
||||
|
||||
try {
|
||||
const response = await fetch(window.chatContext.marriage.acceptUrl(this.marriageId), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
"X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: window.chatContext.roomId,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
this.close();
|
||||
|
||||
if (data.status !== "success") {
|
||||
window.chatDialog?.alert(data.message || "操作失败", "提示", "#cc4444");
|
||||
}
|
||||
} catch {
|
||||
window.chatDialog?.alert("网络异常", "错误", "#cc4444");
|
||||
}
|
||||
|
||||
this.acting = false;
|
||||
},
|
||||
|
||||
async doReject() {
|
||||
if (this.acting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.acting = true;
|
||||
|
||||
try {
|
||||
const response = await fetch(window.chatContext.marriage.rejectUrl(this.marriageId), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
"X-CSRF-TOKEN": document.querySelector("meta[name=csrf-token]").content,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: window.chatContext.roomId,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
this.close();
|
||||
|
||||
if (data.status !== "success") {
|
||||
window.chatDialog?.alert(data.message || "操作失败", "提示", "#cc4444");
|
||||
} else {
|
||||
window.chatDialog?.alert("已婉拒对方的求婚", "操作完成", "#6b7280");
|
||||
}
|
||||
} catch {
|
||||
window.chatDialog?.alert("网络异常", "错误", "#cc4444");
|
||||
}
|
||||
|
||||
this.acting = false;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建结婚成功公告弹窗 Alpine 数据,并触发婚礼礼花特效。
|
||||
*
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
export function marriageAcceptedModal() {
|
||||
return {
|
||||
show: false,
|
||||
announcement: "",
|
||||
subText: "",
|
||||
marriageId: null,
|
||||
isNewlywed: false,
|
||||
|
||||
open(detail) {
|
||||
this.marriageId = detail.marriage_id;
|
||||
const groomName = detail.user?.username ?? detail.groom_name ?? "??";
|
||||
const brideName = detail.partner?.username ?? detail.bride_name ?? "??";
|
||||
|
||||
this.announcement = `${groomName} 与 ${brideName} 喜结连理!`;
|
||||
this.subText = detail.message || "愿百年好合,白头偕老!";
|
||||
|
||||
// 只有新婚双方本人可以继续打开婚礼设置弹窗。
|
||||
const currentUsername = window.chatContext.username;
|
||||
this.isNewlywed = groomName === currentUsername || brideName === currentUsername;
|
||||
this.show = true;
|
||||
|
||||
window.EffectManager?.play("wedding-fireworks");
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
},
|
||||
|
||||
openWeddingSetup() {
|
||||
window.openWeddingSetupModal?.(this.marriageId);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建离婚公告弹窗 Alpine 数据,并播放雷雨组合特效。
|
||||
*
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
export function marriageDivorcedModal() {
|
||||
return {
|
||||
show: false,
|
||||
announcement: "",
|
||||
subText: "",
|
||||
|
||||
open(detail) {
|
||||
const userName = detail.user_username ?? detail.user?.username ?? "??";
|
||||
const partnerName = detail.partner_username ?? detail.partner?.username ?? "??";
|
||||
|
||||
this.announcement = `${userName} 与 ${partnerName} 已解除婚姻关系`;
|
||||
this.subText = detail.message || "往昔已矣,各自珍重。";
|
||||
this.show = true;
|
||||
|
||||
window.EffectManager?.play("lightning");
|
||||
|
||||
// 雷电结束前后再叠加雨效,保留原本的离婚公告氛围。
|
||||
setTimeout(() => {
|
||||
window.EffectManager?.play("rain");
|
||||
}, 3500);
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 Alpine 组件数据,避免直接访问 Alpine 私有字段。
|
||||
*
|
||||
@@ -401,6 +571,9 @@ function bindMarriageModalBootstrap() {
|
||||
*/
|
||||
export function bindMarriageModalControls() {
|
||||
window.appendSystemMessage = appendSystemMessage;
|
||||
window.marriageAcceptedModal = marriageAcceptedModal;
|
||||
window.marriageDivorcedModal = marriageDivorcedModal;
|
||||
window.marriageIncomingModal = marriageIncomingModal;
|
||||
window.marriageProposeModal = marriageProposeModal;
|
||||
window.openProposeModal = openProposeModal;
|
||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
||||
|
||||
@@ -683,160 +683,6 @@
|
||||
|
||||
{{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}}
|
||||
<script>
|
||||
/**
|
||||
* 收到求婚弹窗组件
|
||||
*/
|
||||
function marriageIncomingModal() {
|
||||
return {
|
||||
show: false,
|
||||
proposerName: '',
|
||||
marriageId: null,
|
||||
ringName: '',
|
||||
ringIcon: '💍',
|
||||
expiresAt: '',
|
||||
acting: false,
|
||||
|
||||
open(detail) {
|
||||
this.proposerName = detail.proposer_name || detail.proposer?.username || '';
|
||||
this.marriageId = detail.marriage_id;
|
||||
this.ringName = detail.ring_name || '';
|
||||
this.ringIcon = detail.ring_icon || '💍';
|
||||
this.expiresAt = detail.expires_at || '';
|
||||
this.show = true;
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
},
|
||||
|
||||
async doAccept() {
|
||||
if (this.acting) return;
|
||||
this.acting = true;
|
||||
try {
|
||||
const res = await fetch(window.chatContext.marriage.acceptUrl(this.marriageId), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: window.chatContext.roomId
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
this.close();
|
||||
if (data.status !== 'success') {
|
||||
window.chatDialog?.alert(data.message || '操作失败', '提示', '#cc4444');
|
||||
}
|
||||
// 结婚成功后会收到 MarriageAccepted 全局广播
|
||||
} catch {
|
||||
window.chatDialog?.alert('网络异常', '错误', '#cc4444');
|
||||
}
|
||||
this.acting = false;
|
||||
},
|
||||
|
||||
async doReject() {
|
||||
if (this.acting) return;
|
||||
this.acting = true;
|
||||
try {
|
||||
const res = await fetch(window.chatContext.marriage.rejectUrl(this.marriageId), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: window.chatContext.roomId
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
this.close();
|
||||
if (data.status !== 'success') {
|
||||
window.chatDialog?.alert(data.message || '操作失败', '提示', '#cc4444');
|
||||
} else {
|
||||
window.chatDialog?.alert('已婉拒对方的求婚', '操作完成', '#6b7280');
|
||||
}
|
||||
} catch {
|
||||
window.chatDialog?.alert('网络异常', '错误', '#cc4444');
|
||||
}
|
||||
this.acting = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 结婚成功弹窗组件(收到全局广播后触发)
|
||||
*/
|
||||
function marriageAcceptedModal() {
|
||||
return {
|
||||
show: false,
|
||||
announcement: '',
|
||||
subText: '',
|
||||
marriageId: null,
|
||||
isNewlywed: false,
|
||||
|
||||
open(detail) {
|
||||
this.marriageId = detail.marriage_id;
|
||||
const groomName = detail.user?.username ?? detail.groom_name ?? '??';
|
||||
const brideName = detail.partner?.username ?? detail.bride_name ?? '??';
|
||||
this.announcement = `${groomName} 与 ${brideName} 喜结连理!`;
|
||||
this.subText = detail.message || '愿百年好合,白头偕老!';
|
||||
// 仅当前用户是新婚双方之一时显示举办婚礼按钮
|
||||
const me = window.chatContext.username;
|
||||
this.isNewlywed = (groomName === me || brideName === me);
|
||||
this.show = true;
|
||||
// 播放婚礼专属双倍礼花特效(全员)
|
||||
if (window.EffectManager) {
|
||||
window.EffectManager.play('wedding-fireworks');
|
||||
}
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
},
|
||||
|
||||
openWeddingSetup() {
|
||||
window.openWeddingSetupModal?.(this.marriageId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 离婚全屏公告弹窗组件(阴郁深色风格,雷雨双特效)
|
||||
*/
|
||||
function marriageDivorcedModal() {
|
||||
return {
|
||||
show: false,
|
||||
announcement: '',
|
||||
subText: '',
|
||||
|
||||
open(detail) {
|
||||
const userName = detail.user_username ?? detail.user?.username ?? '??';
|
||||
const partnerName = detail.partner_username ?? detail.partner?.username ?? '??';
|
||||
this.announcement = `${userName} 与 ${partnerName} 已解除婚姻关系`;
|
||||
this.subText = detail.message || '往昔已矣,各自珍重。';
|
||||
this.show = true;
|
||||
|
||||
// 先播放雷电,再叠加下雨
|
||||
if (window.EffectManager) {
|
||||
window.EffectManager.play('lightning');
|
||||
// 雷电通常持续约3秒,3.5秒后再起下雨(雨声会压住)
|
||||
setTimeout(() => {
|
||||
if (window.EffectManager) {
|
||||
window.EffectManager.play('rain');
|
||||
}
|
||||
}, 3500);
|
||||
}
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起离婚确认弹窗(发起方专用:展示双方结果 + 实时惩罚值)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user