迁移婚姻通知弹窗组件
This commit is contained in:
@@ -94,7 +94,16 @@ export {
|
|||||||
switchMarriageTab,
|
switchMarriageTab,
|
||||||
tryDivorce,
|
tryDivorce,
|
||||||
} from "./chat-room/marriage-status.js";
|
} 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 { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||||
export { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
export { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||||
export { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
export { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||||
@@ -266,7 +275,16 @@ import {
|
|||||||
switchMarriageTab,
|
switchMarriageTab,
|
||||||
tryDivorce,
|
tryDivorce,
|
||||||
} from "./chat-room/marriage-status.js";
|
} 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 { bindToolbarControls, runFeatureShortcut, runToolbarAction } from "./chat-room/toolbar.js";
|
||||||
import { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
import { bindUserCardControls, userCardComponent } from "./chat-room/user-card.js";
|
||||||
import { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
import { bindUserTargetActions, openUserCard, switchTarget } from "./chat-room/user-target-actions.js";
|
||||||
@@ -531,6 +549,9 @@ if (typeof window !== "undefined") {
|
|||||||
bindMarriageStatusControls,
|
bindMarriageStatusControls,
|
||||||
appendSystemMessage,
|
appendSystemMessage,
|
||||||
bindMarriageModalControls,
|
bindMarriageModalControls,
|
||||||
|
marriageAcceptedModal,
|
||||||
|
marriageDivorcedModal,
|
||||||
|
marriageIncomingModal,
|
||||||
marriageProposeModal,
|
marriageProposeModal,
|
||||||
closeMarriageStatusModal,
|
closeMarriageStatusModal,
|
||||||
fetchMarriedList,
|
fetchMarriedList,
|
||||||
@@ -715,6 +736,9 @@ if (typeof window !== "undefined") {
|
|||||||
window.marriageAction = marriageAction;
|
window.marriageAction = marriageAction;
|
||||||
window.openMarriageStatusModal = openMarriageStatusModal;
|
window.openMarriageStatusModal = openMarriageStatusModal;
|
||||||
window.appendSystemMessage = appendSystemMessage;
|
window.appendSystemMessage = appendSystemMessage;
|
||||||
|
window.marriageAcceptedModal = marriageAcceptedModal;
|
||||||
|
window.marriageDivorcedModal = marriageDivorcedModal;
|
||||||
|
window.marriageIncomingModal = marriageIncomingModal;
|
||||||
window.marriageProposeModal = marriageProposeModal;
|
window.marriageProposeModal = marriageProposeModal;
|
||||||
window.openProposeModal = openProposeModal;
|
window.openProposeModal = openProposeModal;
|
||||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
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 私有字段。
|
* 读取 Alpine 组件数据,避免直接访问 Alpine 私有字段。
|
||||||
*
|
*
|
||||||
@@ -401,6 +571,9 @@ function bindMarriageModalBootstrap() {
|
|||||||
*/
|
*/
|
||||||
export function bindMarriageModalControls() {
|
export function bindMarriageModalControls() {
|
||||||
window.appendSystemMessage = appendSystemMessage;
|
window.appendSystemMessage = appendSystemMessage;
|
||||||
|
window.marriageAcceptedModal = marriageAcceptedModal;
|
||||||
|
window.marriageDivorcedModal = marriageDivorcedModal;
|
||||||
|
window.marriageIncomingModal = marriageIncomingModal;
|
||||||
window.marriageProposeModal = marriageProposeModal;
|
window.marriageProposeModal = marriageProposeModal;
|
||||||
window.openProposeModal = openProposeModal;
|
window.openProposeModal = openProposeModal;
|
||||||
window.openWeddingSetupModal = openWeddingSetupModal;
|
window.openWeddingSetupModal = openWeddingSetupModal;
|
||||||
|
|||||||
@@ -683,160 +683,6 @@
|
|||||||
|
|
||||||
{{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}}
|
{{-- ═══════════ Alpine.js 组件脚本 ═══════════ --}}
|
||||||
<script>
|
<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