Files
IM-web-new/dist/js/app.1158390e.js
T
2026-10-10 21:20:27 +07:00

9928 lines
512 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 4677:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144);
/* harmony import */ var _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3727);
/* harmony import */ var _components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9531);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926);
/* harmony default export */ __webpack_exports__.A = ({
__name: 'App',
setup(__props) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)();
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
session.restore();
});
return (_ctx, _cache) => {
return !(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(session).isAuthenticated ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, {
key: 0
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
key: 1
}));
};
}
});
/***/ }),
/***/ 2511:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144);
/* harmony import */ var _sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8328);
/* harmony import */ var _sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(371);
/* harmony import */ var _sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(578);
/* harmony import */ var _chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7014);
/* harmony import */ var _contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3351);
/* harmony import */ var _favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(163);
/* harmony import */ var _favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9123);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7566);
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1414);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9045);
const _hoisted_1 = {
class: "app-shell"
};
/* harmony default export */ __webpack_exports__.A = ({
__name: 'ChatShell',
setup(__props) {
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_9__/* .useConversationStore */ .w)();
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_10__/* .useNavigationStore */ .l)();
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_11__/* .useContactStore */ .p)();
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
conversations.refreshRemoteConversations();
contacts.refreshContacts();
});
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createVNode */ .bF)(_sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
key: 0
})) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A, {
key: 1
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A, {
key: 2
})), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A, {
key: 3
})) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A, {
key: 4
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A, {
key: 5
}))]);
};
}
});
/***/ }),
/***/ 8607:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2387);
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2789);
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2169);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(926);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5051);
const _hoisted_1 = {
class: "login-page"
};
const _hoisted_2 = {
class: "login-panel"
};
const _hoisted_3 = {
class: "brand-lockup"
};
const _hoisted_4 = ["src", "alt"];
const _hoisted_5 = {
class: "login-tabs register-tabs",
style: {
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))'
}
};
const _hoisted_6 = ["disabled"];
const _hoisted_7 = ["src"];
const _hoisted_8 = {
key: 1
};
const _hoisted_9 = {
key: 0,
class: "qr-scan-user"
};
const _hoisted_10 = ["src"];
const _hoisted_11 = {
key: 1
};
const _hoisted_12 = {
class: "qr-login-status"
};
const _hoisted_13 = ["disabled"];
const _hoisted_14 = ["autocomplete", "inputmode", "placeholder"];
const _hoisted_15 = ["disabled"];
const _hoisted_16 = {
key: 2,
class: "form-error"
};
const _hoisted_17 = {
key: 3,
class: "form-info"
};
const _hoisted_18 = {
class: "login-tabs register-tabs",
style: {
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))'
}
};
const _hoisted_19 = ["autocomplete", "inputmode", "placeholder"];
const _hoisted_20 = {
key: 0
};
const _hoisted_21 = {
class: "code-row"
};
const _hoisted_22 = ["disabled"];
const _hoisted_23 = ["disabled"];
const _hoisted_24 = {
key: 1,
class: "form-error"
};
const _hoisted_25 = {
key: 2,
class: "form-info"
};
const QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/';
const defaultPlatformLogo = '/favicon.ico';
/* harmony default export */ __webpack_exports__.A = ({
__name: 'LoginView',
setup(__props) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_8__/* .useSessionStore */ .B)();
const view = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('login');
const loginMode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('phone');
const loginAccount = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const loginPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(1);
const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .reactive */ .Kh)({
number: '',
code: '',
password: '',
confirmPassword: '',
invitationCode: ''
});
const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(false);
const info = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('idle');
const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
let qrGeneration = 0;
let qrExpireTimer = null;
const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.appName;
const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformName);
const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformLogo);
const canSubmitLogin = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => loginAccount.value.length >= 3 && loginPassword.value.length >= 1);
const canRequestEmailCode = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => registerType.value === 2 && /\S+@\S+\.\S+/.test(registerForm.number));
const canSubmitRegister = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
if (registerForm.password.length < 1 || registerForm.password !== registerForm.confirmPassword) {
return false;
}
if (registerType.value === 2) {
return canRequestEmailCode.value && registerForm.code.length >= 1;
}
return registerForm.number.length >= 5;
});
const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => String(qrUserName.value || 'U').slice(0, 1).toUpperCase());
const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
if (session.connecting || qrStatus.value === 'confirmed') {
return '正在进入';
}
if (qrStatus.value === 'loading') {
return '正在生成二维码';
}
if (qrStatus.value === 'scanned') {
return qrUserName.value ? `${qrUserName.value} 已扫码` : '已扫码,待确认';
}
if (qrStatus.value === 'expired') {
return '二维码已过期';
}
if (qrStatus.value === 'error') {
return '二维码加载失败';
}
return '扫码登录';
});
const qrStatusText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
if (session.connecting || qrStatus.value === 'confirmed') {
return '登录信息已确认,正在建立连接';
}
if (qrStatus.value === 'loading') {
return '正在创建扫码登录会话';
}
if (qrStatus.value === 'scanned') {
return '请在手机 App 上确认登录';
}
if (qrStatus.value === 'expired') {
return '请刷新二维码后重新扫码';
}
if (qrStatus.value === 'error') {
return '请稍后重试';
}
return '使用已登录的手机 App 扫描二维码';
});
const qrRefreshText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
if (qrStatus.value === 'loading') {
return '生成中...';
}
if (qrStatus.value === 'expired' || qrStatus.value === 'error') {
return '重新生成二维码';
}
return '刷新二维码';
});
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onMounted */ .sV)(() => {
loadPlatformConfig();
});
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onBeforeUnmount */ .xo)(() => {
stopQrLogin();
});
function clearFormMessage() {
session.error = '';
info.value = '';
}
function setLoginMode(mode) {
loginMode.value = mode;
loginAccount.value = '';
loginPassword.value = '';
clearFormMessage();
if (mode === 'qr') {
startQrLogin();
return;
}
stopQrLogin();
}
async function submitLogin() {
clearFormMessage();
const type = loginMode.value === 'email' ? 2 : 1;
await session.loginWithPassword(loginAccount.value, loginPassword.value, type);
}
function switchRegisterType(type) {
registerType.value = type;
registerForm.number = '';
registerForm.code = '';
registerForm.password = '';
registerForm.confirmPassword = '';
registerForm.invitationCode = '';
clearFormMessage();
}
async function requestEmailCode() {
clearFormMessage();
sendingCode.value = true;
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.requestAuthCode(registerForm.number);
info.value = '邮箱验证码已发送,请在当前注册表单中填写后继续。';
} catch (error) {
session.error = error.message || '验证码发送失败';
} finally {
sendingCode.value = false;
}
}
async function submitRegister() {
clearFormMessage();
if (registerForm.password !== registerForm.confirmPassword) {
session.error = '两次输入的密码不一致';
return;
}
const result = await session.register({
type: registerType.value,
number: registerForm.number,
code: registerType.value === 2 ? registerForm.code : '',
password: registerForm.password,
invitationCode: registerForm.invitationCode
});
if (result) {
info.value = '注册成功,正在进入系统。';
}
}
function openRegister() {
clearFormMessage();
stopQrLogin();
view.value = 'register';
}
function backToLogin() {
clearFormMessage();
loginMode.value = 'phone';
stopQrLogin();
view.value = 'login';
}
function resetQrState() {
qrStatus.value = 'idle';
qrCodeImage.value = '';
qrSessionToken.value = '';
qrUserName.value = '';
qrUserPortrait.value = '';
}
function clearQrExpireTimer() {
if (qrExpireTimer) {
window.clearTimeout(qrExpireTimer);
qrExpireTimer = null;
}
}
function stopQrLogin() {
qrGeneration += 1;
clearQrExpireTimer();
resetQrState();
}
function refreshQrLogin() {
startQrLogin(true);
}
async function startQrLogin(force = false) {
if (loginMode.value !== 'qr') {
return;
}
if (!force && qrSessionToken.value && qrCodeImage.value && !['expired', 'error'].includes(qrStatus.value)) {
return;
}
qrGeneration += 1;
const generation = qrGeneration;
clearQrExpireTimer();
clearFormMessage();
qrStatus.value = 'loading';
qrCodeImage.value = '';
qrSessionToken.value = '';
qrUserName.value = '';
qrUserPortrait.value = '';
try {
const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.createPcSession();
if (generation !== qrGeneration || loginMode.value !== 'qr') {
return;
}
const token = String(pcSession.token || '');
if (!token) {
throw new Error('服务端没有返回扫码 token');
}
qrSessionToken.value = token;
qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default().getQrBase64(QR_CODE_PREFIX_PC_SESSION + token);
qrStatus.value = 'waiting';
const expireMs = Math.max(30000, Math.min(Number(pcSession.expired || 300000), 300000));
qrExpireTimer = window.setTimeout(() => {
if (generation === qrGeneration && qrStatus.value !== 'confirmed' && !session.isAuthenticated) {
qrStatus.value = 'expired';
}
}, expireMs);
pollQrLogin(generation, token);
} catch (error) {
if (generation !== qrGeneration) {
return;
}
qrStatus.value = 'error';
session.error = error.message || '二维码加载失败';
}
}
async function pollQrLogin(generation, token) {
try {
while (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
const payload = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.loginWithPcSession(token);
if (generation !== qrGeneration || loginMode.value !== 'qr') {
return;
}
const code = Number(payload.code);
const data = payload.data || payload.result || {};
const status = Number(data.status);
if (code === 0 && data.imToken) {
qrStatus.value = 'confirmed';
clearQrExpireTimer();
await session.completePcSessionLogin(data);
return;
}
if (code === 20042 || status === 1 || status === 3) {
qrStatus.value = 'scanned';
qrUserName.value = data.userName || data.displayName || qrUserName.value;
qrUserPortrait.value = data.portrait || qrUserPortrait.value;
await delay(1000);
continue;
}
if (status === 0 || code === 13) {
qrStatus.value = 'waiting';
await delay(1000);
continue;
}
if (status === 4) {
qrStatus.value = 'expired';
session.error = payload.message || '扫码登录已取消';
return;
}
if (payload.message) {
throw new Error(payload.message);
}
await delay(1000);
}
} catch (error) {
if (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
qrStatus.value = 'error';
session.error = error.message || '扫码登录失败';
}
}
}
function delay(ms) {
return new Promise(resolve => window.setTimeout(resolve, ms));
}
async function loadPlatformConfig() {
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.platformConfigApi, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '平台配置加载失败');
}
const config = response.data?.result || {};
const name = String(config.platformName || '').trim();
const logo = String(config.logoUrl || config.logo || '').trim();
const version = String(config.version || '').trim();
platformName.value = name || defaultPlatformName;
platformLogo.value = resolveBrandLogo(logo, version);
} catch (error) {
platformName.value = defaultPlatformName;
platformLogo.value = defaultPlatformLogo;
}
applyDocumentBrand();
}
function resolveBrandLogo(value, version = '') {
const logo = String(value || '').trim();
if (!logo) {
return defaultPlatformLogo;
}
if (/^(https?:|data:|blob:)/i.test(logo)) {
return appendBrandVersion(logo, version);
}
if (logo.startsWith('//')) {
return appendBrandVersion(`${window.location.protocol}${logo}`, version);
}
const base = logo.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer}/`;
return appendBrandVersion(new URL(logo, base).toString(), version);
}
function appendBrandVersion(url, version) {
if (!version || /^(data:|blob:)/i.test(url)) {
return url;
}
const parsed = new URL(url, window.location.href);
parsed.searchParams.set('v', version);
return parsed.toString();
}
function applyDocumentBrand() {
if (typeof document === 'undefined') {
return;
}
document.title = platformName.value || defaultPlatformName;
let icon = document.querySelector('link[rel="icon"]');
if (!icon) {
icon = document.createElement('link');
icon.setAttribute('rel', 'icon');
document.head.appendChild(icon);
}
icon.setAttribute('href', platformLogo.value || defaultPlatformLogo);
}
function handleBrandLogoError() {
if (platformLogo.value !== defaultPlatformLogo) {
platformLogo.value = defaultPlatformLogo;
applyDocumentBrand();
}
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("section", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", {
class: "brand-mark",
src: platformLogo.value,
alt: `${platformName.value} logo`,
onError: handleBrandLogoError
}, null, 40, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h1", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(platformName.value), 1)])]), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
key: 0,
class: "login-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitLogin, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
active: loginMode.value === 'qr'
}),
onClick: _cache[0] || (_cache[0] = $event => setLoginMode('qr'))
}, "扫码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
active: loginMode.value === 'phone'
}),
onClick: _cache[1] || (_cache[1] = $event => setLoginMode('phone'))
}, "手机号", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
active: loginMode.value === 'email'
}),
onClick: _cache[2] || (_cache[2] = $event => setLoginMode('email'))
}, "邮箱", 2)]), loginMode.value === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
key: 0
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["qr-login-card", {
scanned: qrStatus.value === 'scanned',
expired: qrStatus.value === 'expired',
error: qrStatus.value === 'error'
}])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "qr-code-button",
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
onClick: refreshQrLogin
}, [qrCodeImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
key: 0,
src: qrCodeImage.value,
alt: "扫码登录二维码"
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatus.value === 'loading' ? '生成中' : '点击刷新'), 1))], 8, _hoisted_6), qrStatus.value === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_9, [qrUserPortrait.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
key: 0,
src: qrUserPortrait.value,
alt: ""
}, null, 8, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrUserInitial.value), 1))])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-action",
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
onClick: refreshQrLogin
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrRefreshText.value), 9, _hoisted_13)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(loginMode.value === 'phone' ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => loginAccount.value = $event),
autocomplete: loginMode.value === 'phone' ? 'username' : 'email',
inputmode: loginMode.value === 'phone' ? 'tel' : 'email',
placeholder: loginMode.value === 'phone' ? '请输入手机号' : '请输入邮箱'
}, null, 8, _hoisted_14), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginAccount.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => loginPassword.value = $event),
autocomplete: "current-password",
type: "password",
placeholder: "请输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginPassword.value]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
class: "primary-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitLogin.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '登录中...' : '登录'), 9, _hoisted_15)], 64)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
key: 1,
class: "login-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitRegister, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
active: registerType.value === 1
}),
onClick: _cache[5] || (_cache[5] = $event => switchRegisterType(1))
}, "手机号注册", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
active: registerType.value === 2
}),
onClick: _cache[6] || (_cache[6] = $event => switchRegisterType(2))
}, "邮箱注册", 2)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(registerType.value === 1 ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[7] || (_cache[7] = $event => registerForm.number = $event),
autocomplete: registerType.value === 1 ? 'tel' : 'email',
inputmode: registerType.value === 1 ? 'tel' : 'email',
placeholder: registerType.value === 1 ? '请输入手机号' : '请输入邮箱'
}, null, 8, _hoisted_19), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.number, void 0, {
trim: true
}]])]), registerType.value === 2 ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("label", _hoisted_20, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邮箱验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[8] || (_cache[8] = $event => registerForm.code = $event),
autocomplete: "one-time-code",
inputmode: "numeric",
placeholder: "请输入邮箱验证码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.code, void 0, {
trim: true
}]]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "code-action",
disabled: sendingCode.value || !canRequestEmailCode.value,
onClick: requestEmailCode
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_22)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => registerForm.password = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "确认密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => registerForm.confirmPassword = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请再次输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邀请码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[11] || (_cache[11] = $event => registerForm.invitationCode = $event),
autocomplete: "off",
placeholder: "没有可留空"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.invitationCode, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
class: "primary-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitRegister.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '注册中...' : '注册并登录'), 9, _hoisted_23), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
key: 2,
class: "ghost-action",
type: "button",
onClick: openRegister
}, " 新用户注册 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
key: 3,
class: "ghost-action",
type: "button",
onClick: backToLogin
}, " 返回登录 "))])]);
};
}
});
/***/ }),
/***/ 7562:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5187);
/* harmony import */ var _MessageList_vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(9847);
/* harmony import */ var _MessageComposer_vue__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(1653);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(5051);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(7566);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(9045);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(926);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(446);
const _hoisted_1 = {
class: "chat-header"
};
const _hoisted_2 = ["src"];
const _hoisted_3 = {
key: 1,
class: "chat-title-avatar"
};
const _hoisted_4 = {
class: "chat-title-copy"
};
const _hoisted_5 = ["src"];
const _hoisted_6 = {
key: 1,
class: "chat-title-avatar"
};
const _hoisted_7 = {
class: "chat-title-copy"
};
const _hoisted_8 = {
key: 2
};
const _hoisted_9 = {
class: "header-actions chat-header-actions"
};
const _hoisted_10 = {
key: 0,
class: "empty-chat"
};
const _hoisted_11 = {
class: "pinned-message-preview"
};
const _hoisted_12 = ["src"];
const _hoisted_13 = {
key: 3,
class: "selection-toolbar"
};
const _hoisted_14 = {
class: "forward-dialog"
};
const _hoisted_15 = ["onClick"];
const _hoisted_16 = {
class: "conversation-avatar"
};
const _hoisted_17 = {
type: "submit"
};
const _hoisted_18 = {
class: "group-dialog message-detail-dialog"
};
const _hoisted_19 = {
key: 0,
class: "group-loading"
};
const _hoisted_20 = {
class: "group-profile message-detail-meta"
};
const _hoisted_21 = {
key: 0
};
const _hoisted_22 = {
key: 0,
class: "inline-save-status error"
};
const _hoisted_23 = {
class: "message-detail-summary"
};
const _hoisted_24 = {
class: "message-detail-groups"
};
const _hoisted_25 = {
class: "message-detail-section"
};
const _hoisted_26 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_27 = ["src"];
const _hoisted_28 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_29 = {
class: "message-detail-member-main"
};
const _hoisted_30 = {
class: "message-detail-member-time"
};
const _hoisted_31 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_32 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_33 = {
class: "message-detail-section"
};
const _hoisted_34 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_35 = ["src"];
const _hoisted_36 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_37 = {
class: "message-detail-member-main"
};
const _hoisted_38 = {
class: "message-detail-member-time"
};
const _hoisted_39 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_40 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_41 = {
class: "message-detail-section"
};
const _hoisted_42 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_43 = ["src"];
const _hoisted_44 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_45 = {
class: "message-detail-member-main"
};
const _hoisted_46 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_47 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_48 = {
class: "group-dialog single-profile-dialog"
};
const _hoisted_49 = {
class: "single-profile-summary"
};
const _hoisted_50 = ["src"];
const _hoisted_51 = {
key: 1,
class: "profile-avatar"
};
const _hoisted_52 = {
class: "group-profile"
};
const _hoisted_53 = {
key: 0
};
const _hoisted_54 = {
class: "single-profile-footer"
};
const _hoisted_55 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_56 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_57 = ["disabled"];
const _hoisted_58 = ["disabled"];
const _hoisted_59 = {
key: 0,
class: "group-dialog"
};
const _hoisted_60 = {
key: 0,
class: "group-loading"
};
const _hoisted_61 = {
key: 1,
class: "group-profile"
};
const _hoisted_62 = ["disabled"];
const _hoisted_63 = ["disabled"];
const _hoisted_64 = ["disabled"];
const _hoisted_65 = {
key: 1,
class: "group-dialog"
};
const _hoisted_66 = {
key: 0,
class: "group-loading"
};
const _hoisted_67 = {
key: 1,
class: "group-member-list"
};
const _hoisted_68 = ["src"];
const _hoisted_69 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_70 = {
key: 0,
class: "contact-picker-empty"
};
const _hoisted_71 = ["disabled"];
const _hoisted_72 = {
key: 3,
class: "group-dialog"
};
const _hoisted_73 = {
key: 0,
class: "group-loading"
};
const _hoisted_74 = {
key: 1,
class: "group-member-list"
};
const _hoisted_75 = ["onClick"];
const _hoisted_76 = ["src"];
const _hoisted_77 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_78 = {
key: 0,
class: "contact-picker-empty"
};
const _hoisted_79 = ["disabled"];
const _hoisted_80 = {
key: 4,
class: "group-dialog group-management-dialog"
};
const _hoisted_81 = {
class: "group-management-tabs"
};
const _hoisted_82 = {
key: 0,
class: "group-loading"
};
const _hoisted_83 = {
key: 1,
class: "group-manage-section"
};
const _hoisted_84 = {
class: "group-member-list"
};
const _hoisted_85 = ["checked", "onChange"];
const _hoisted_86 = ["src"];
const _hoisted_87 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_88 = {
key: 0,
class: "contact-picker-empty"
};
const _hoisted_89 = {
key: 2,
class: "group-manage-section"
};
const _hoisted_90 = {
key: 3,
class: "group-manage-section"
};
const _hoisted_91 = {
class: "group-member-list"
};
const _hoisted_92 = ["checked", "onChange"];
const _hoisted_93 = ["src"];
const _hoisted_94 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_95 = {
key: 0,
class: "contact-picker-empty"
};
const _hoisted_96 = ["disabled"];
const _hoisted_97 = {
key: 4,
class: "group-manage-section"
};
const _hoisted_98 = {
key: 0,
class: "mute-time-grid"
};
const _hoisted_99 = {
key: 1,
class: "mute-time-grid"
};
const _hoisted_100 = {
class: "mute-save-footer"
};
const _hoisted_101 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_102 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_103 = ["disabled"];
/* harmony default export */ __webpack_exports__.A = ({
__name: 'ChatPanel',
setup(__props) {
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_19__/* .useConversationStore */ .w)();
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_20__/* .useContactStore */ .p)();
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_21__/* .useSessionStore */ .B)();
const activeConversation = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => conversations.activeConversation);
const pinnedMessageIsImage = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
const message = conversations.activePinnedMessage;
return message?.attachment?.url && (message.type === 'image' || message.attachment.type === 'image');
});
const pinnedMessageText = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
const message = conversations.activePinnedMessage;
if (!message) return '';
const text = String(message.text || '').trim();
if (text && text !== '[消息]') return text;
const attachment = message.attachment || {};
if (message.type === 'image' || attachment.type === 'image') return attachment.name || '图片';
if (message.type === 'video' || attachment.type === 'video') return attachment.name || '视频';
if (attachment.url) return attachment.name || '文件';
return '[消息]';
});
const groupMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
const singleProfileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
const singleAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const singleProfileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
const singleProfileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const singleProfileError = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const groupPanel = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const groupBusy = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
const groupDetail = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(null);
const groupMembers = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
const groupAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const manageSection = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const selectedAdminIds = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
const selectedKickIds = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
const transferTargetId = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)({
name: '',
announcement: '',
welcomeText: ''
});
const muteDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)({
mode: 'off',
scheduleType: 'once',
startsAtLocal: '',
endsAtLocal: '',
dailyStart: '09:00',
dailyEnd: '18:00'
});
const muteSaveNotice = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const muteSaveError = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
const singlePeerId = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
if (!activeConversation.value || isGroupConversation.value) {
return '';
}
return String(activeConversation.value.target || activeConversation.value.raw?.target || activeConversation.value.id?.replace(/^single-/, '') || '');
});
const singleContact = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
const peerId = singlePeerId.value;
if (!peerId) {
return null;
}
return contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || null;
});
const singleProfile = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
const contact = singleContact.value;
const conversation = activeConversation.value || {};
const rawUser = contact?.rawUser || {};
const displayName = contact?.alias || rawUser.displayName || rawUser.name || contact?.title || conversation.title || singlePeerId.value || '未知用户';
const rawName = rawUser.displayName || rawUser.name || contact?.title || conversation.title || '';
return {
uid: singlePeerId.value,
userId: rawUser.name || conversation.raw?.userId || singlePeerId.value,
displayName,
rawName,
mobile: rawUser.mobile || conversation.raw?.mobile || '',
address: rawUser.address || conversation.raw?.address || '',
portrait: contact?.portrait || conversation.portrait || '',
avatarText: String(displayName || '?').slice(0, 1).toUpperCase(),
alias: contact?.alias || ''
};
});
const groupDisplayId = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return String(groupDetail.value?.groupId || activeConversation.value?.raw?.groupId || activeConversation.value?.raw?.target || activeConversation.value?.target || activeConversation.value?.id?.replace(/^group-/, '') || '-');
});
const isGroupConversation = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return ['group', 'channel'].includes(activeConversation.value?.type) || activeConversation.value?.raw?.type === 'group';
});
const currentGroupRole = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return groupDetail.value?.myRole || activeConversation.value?.role || activeConversation.value?.raw?.role || '';
});
const isGroupOwner = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => currentGroupRole.value === 'owner');
const canManageGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => ['owner', 'admin'].includes(currentGroupRole.value));
const adminCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => groupMembers.value.filter(member => member.role !== 'owner'));
const transferableMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => groupMembers.value.filter(member => member.role !== 'owner'));
const messageDetail = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => conversations.messageDetail || null);
const messageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => messageDetail.value?.group || null);
const isMessageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return messageDetail.value?.conversationType === 'group' || Boolean(messageDetail.value?.group);
});
const messageDetailCounts = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return messageDetailGroup.value?.counts || {
read: 0,
unread: 0,
undelivered: 0,
total: 0
};
});
const kickCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
return groupMembers.value.filter(member => {
if (member.uid === session.userId || member.role === 'owner') {
return false;
}
if (currentGroupRole.value === 'admin') {
return member.role === 'member';
}
return currentGroupRole.value === 'owner';
});
});
const statusText = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
if (activeConversation.value?.type === 'channel' && !conversations.canSendActiveConversation) {
return '公告群,仅管理员可发言';
}
return session.connectionStatusText || (session.connected ? '已连接' : '未连接');
});
function formatDetailTime(value) {
const timestamp = Number(value || 0);
if (!timestamp) {
return '暂无';
}
return new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
}).format(timestamp);
}
function detailMemberName(member) {
return member?.name || member?.displayName || member?.rawName || member?.uid || '-';
}
function detailMemberAvatar(member) {
return String(detailMemberName(member) || '?').slice(0, 1).toUpperCase();
}
function detailRoleLabel(role) {
if (role === 'owner') {
return '群主';
}
if (role === 'admin') {
return '管理员';
}
return '';
}
function closeGroupMenu() {
groupMenuOpen.value = false;
}
function toggleGroupMenu() {
if (!isGroupConversation.value) {
return;
}
groupMenuOpen.value = !groupMenuOpen.value;
}
async function openSingleProfile() {
if (!activeConversation.value || isGroupConversation.value) {
return;
}
closeGroupMenu();
singleProfileNotice.value = '';
singleProfileError.value = '';
singleAliasDraft.value = singleProfile.value.alias || '';
singleProfileOpen.value = true;
contacts.refreshContacts().then(() => {
if (singleProfileOpen.value) {
singleAliasDraft.value = singleProfile.value.alias || '';
}
}).catch(() => {});
}
function closeSingleProfile() {
if (singleProfileSaving.value) {
return;
}
singleProfileOpen.value = false;
singleProfileNotice.value = '';
singleProfileError.value = '';
}
async function saveSingleAlias() {
const peerId = singleProfile.value.uid;
if (!peerId || singleProfileSaving.value) {
return;
}
singleProfileSaving.value = true;
singleProfileNotice.value = '';
singleProfileError.value = '';
try {
const ok = await contacts.updateContactAlias(peerId, singleAliasDraft.value);
if (!ok) {
singleProfileError.value = contacts.actionError || '备注名修改失败';
return;
}
await contacts.refreshContacts({
force: true
}).catch(() => {});
const refreshedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || singleContact.value;
const nextTitle = refreshedContact?.title || singleAliasDraft.value || singleProfile.value.rawName || singleProfile.value.displayName || peerId;
conversations.upsertConversation({
...activeConversation.value,
title: nextTitle,
portrait: refreshedContact?.portrait || activeConversation.value?.portrait || '',
avatarText: String(nextTitle || '?').slice(0, 1).toUpperCase(),
raw: {
...(activeConversation.value?.raw || {}),
target: peerId,
mobile: refreshedContact?.rawUser?.mobile || activeConversation.value?.raw?.mobile || '',
address: refreshedContact?.rawUser?.address || activeConversation.value?.raw?.address || '',
alias: refreshedContact?.alias || singleAliasDraft.value
}
});
singleAliasDraft.value = refreshedContact?.alias || singleAliasDraft.value;
singleProfileNotice.value = '备注名已保存';
} catch (error) {
singleProfileError.value = error.message || '备注名修改失败';
} finally {
singleProfileSaving.value = false;
}
}
function handleSenderProfileUpdated() {
contacts.refreshContacts({
force: true
}).catch(() => {});
conversations.syncActiveMessages({
allowReadReceipt: true
});
if (groupPanel.value === 'members') {
loadGroupMembers();
}
}
function closeGroupPanel() {
groupPanel.value = '';
groupBusy.value = false;
clearMuteSaveFeedback();
}
async function loadGroupDetail() {
if (!session.userId || !activeConversation.value?.target) {
return null;
}
groupBusy.value = true;
try {
groupDetail.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.getGroupDetail(session.userId, activeConversation.value.target);
return groupDetail.value;
} catch (error) {
conversations.setActionError(error.message || '群资料加载失败');
return null;
} finally {
groupBusy.value = false;
}
}
async function openGroupOverview() {
if (!isGroupConversation.value) {
return;
}
closeGroupMenu();
groupPanel.value = 'overview';
await loadGroupDetail();
}
async function openGroupMembers() {
closeGroupMenu();
groupPanel.value = 'members';
await loadGroupMembers();
}
async function loadGroupMembers() {
groupBusy.value = true;
try {
groupMembers.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.getGroupMembers(session.userId, activeConversation.value.target);
selectedAdminIds.value = groupMembers.value.filter(member => member.role === 'admin').map(member => member.uid);
return groupMembers.value;
} catch (error) {
conversations.setActionError(error.message || '群员加载失败');
return [];
} finally {
groupBusy.value = false;
}
}
async function openGroupAlias() {
closeGroupMenu();
groupPanel.value = 'alias';
const detail = await loadGroupDetail();
groupAliasDraft.value = detail?.myAlias || '';
}
function msToLocalInput(value) {
const timestamp = Number(value || 0);
if (!timestamp) {
return '';
}
const date = new Date(timestamp);
const local = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
return local.toISOString().slice(0, 16);
}
function localInputToMs(value) {
return value ? new Date(value).getTime() : 0;
}
function prepareManagementDrafts() {
clearMuteSaveFeedback();
profileDraft.value = {
name: groupDetail.value?.name || activeConversation.value?.title || '',
announcement: groupDetail.value?.announcement || '',
welcomeText: groupDetail.value?.welcomeText || ''
};
const setting = groupDetail.value?.muteSetting || {};
muteDraft.value = {
mode: setting.mode || 'off',
scheduleType: setting.scheduleType || 'once',
startsAtLocal: msToLocalInput(setting.startsAtMs),
endsAtLocal: msToLocalInput(setting.endsAtMs),
dailyStart: setting.dailyStart || '09:00',
dailyEnd: setting.dailyEnd || '18:00'
};
}
function clearMuteSaveFeedback() {
muteSaveNotice.value = '';
muteSaveError.value = '';
}
async function openGroupManage() {
if (!canManageGroup.value) {
return;
}
closeGroupMenu();
groupPanel.value = 'manage';
manageSection.value = isGroupOwner.value ? 'admins' : 'profile';
await loadGroupDetail();
prepareManagementDrafts();
await loadGroupMembers();
}
async function openTransferGroup() {
groupPanel.value = 'transfer';
transferTargetId.value = '';
await loadGroupMembers();
}
async function saveGroupAlias() {
if (!activeConversation.value?.target || groupBusy.value) {
return;
}
groupBusy.value = true;
try {
const alias = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupAlias(session.userId, activeConversation.value.target, groupAliasDraft.value);
groupDetail.value = {
...(groupDetail.value || {}),
myAlias: alias
};
conversations.setActionNotice('本群昵称已保存');
closeGroupPanel();
} catch (error) {
conversations.setActionError(error.message || '本群昵称保存失败');
} finally {
groupBusy.value = false;
}
}
function toggleAdmin(userId) {
const selected = new Set(selectedAdminIds.value);
if (selected.has(userId)) {
selected.delete(userId);
} else {
selected.add(userId);
}
selectedAdminIds.value = Array.from(selected);
}
function toggleKick(userId) {
const selected = new Set(selectedKickIds.value);
if (selected.has(userId)) {
selected.delete(userId);
} else {
selected.add(userId);
}
selectedKickIds.value = Array.from(selected);
}
async function saveGroupAdmins() {
if (!activeConversation.value?.target || groupBusy.value) {
return;
}
groupBusy.value = true;
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.setGroupAdmins(session.userId, activeConversation.value.target, selectedAdminIds.value);
groupMembers.value = groupMembers.value.map(member => {
if (member.role === 'owner') {
return member;
}
return {
...member,
role: selectedAdminIds.value.includes(member.uid) ? 'admin' : 'member'
};
});
conversations.setActionNotice('管理员已更新');
} catch (error) {
conversations.setActionError(error.message || '管理员设置失败');
} finally {
groupBusy.value = false;
}
}
async function saveGroupProfile() {
if (!activeConversation.value?.target || groupBusy.value) {
return;
}
groupBusy.value = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupProfile(session.userId, activeConversation.value.target, profileDraft.value);
groupDetail.value = {
...(groupDetail.value || {}),
name: result.name,
announcement: result.announcement,
welcomeText: result.welcomeText
};
conversations.upsertConversation({
...activeConversation.value,
title: result.name,
avatarText: String(result.name || '?').slice(0, 1).toUpperCase(),
updatedAt: Number(result.updatedAt || Date.now())
});
conversations.setActionNotice('群资料已保存');
} catch (error) {
conversations.setActionError(error.message || '群资料保存失败');
} finally {
groupBusy.value = false;
}
}
async function kickSelectedMembers() {
if (!selectedKickIds.value.length || groupBusy.value) {
return;
}
if (!window.confirm('确认将所选成员移出群组?')) {
return;
}
groupBusy.value = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.kickGroupMembers(session.userId, activeConversation.value.target, selectedKickIds.value);
const removed = new Set(result.removedIds || selectedKickIds.value);
groupMembers.value = groupMembers.value.filter(member => !removed.has(member.uid));
selectedKickIds.value = [];
conversations.setActionNotice('已移出群组');
} catch (error) {
conversations.setActionError(error.message || '踢人失败');
} finally {
groupBusy.value = false;
}
}
async function saveMuteSetting() {
if (!activeConversation.value?.target || groupBusy.value) {
return;
}
clearMuteSaveFeedback();
groupBusy.value = true;
try {
const setting = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupMuteSetting(session.userId, activeConversation.value.target, {
mode: muteDraft.value.mode,
scheduleType: muteDraft.value.scheduleType,
startsAtMs: localInputToMs(muteDraft.value.startsAtLocal),
endsAtMs: localInputToMs(muteDraft.value.endsAtLocal),
dailyStart: muteDraft.value.dailyStart,
dailyEnd: muteDraft.value.dailyEnd
});
groupDetail.value = {
...(groupDetail.value || {}),
muteSetting: setting
};
muteSaveNotice.value = '禁言设置已保存';
} catch (error) {
muteSaveError.value = error.message || '禁言设置保存失败';
} finally {
groupBusy.value = false;
}
}
async function leaveCurrentGroup() {
if (!activeConversation.value || groupBusy.value) {
return;
}
if (!window.confirm('确认退出该群组?')) {
return;
}
groupBusy.value = true;
const ok = await conversations.leaveGroup(activeConversation.value);
groupBusy.value = false;
if (ok) {
closeGroupPanel();
}
}
async function dismissCurrentGroup() {
if (!activeConversation.value || groupBusy.value) {
return;
}
if (!window.confirm('确认解散该群组?所有成员都将不可继续使用该群。')) {
return;
}
groupBusy.value = true;
const ok = await conversations.dismissGroup(activeConversation.value);
groupBusy.value = false;
if (ok) {
closeGroupPanel();
}
}
async function transferCurrentGroup() {
if (!activeConversation.value?.target || !transferTargetId.value || groupBusy.value) {
return;
}
if (!window.confirm('确认将群主转让给该成员?')) {
return;
}
groupBusy.value = true;
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.transferGroup(session.userId, activeConversation.value.target, transferTargetId.value);
groupDetail.value = {
...(groupDetail.value || {}),
myRole: 'member'
};
activeConversation.value.role = 'member';
if (activeConversation.value.raw) {
activeConversation.value.raw.role = 'member';
}
conversations.setActionNotice('群组已转让');
closeGroupPanel();
conversations.refreshRemoteConversations();
} catch (error) {
conversations.setActionError(error.message || '转让群组失败');
} finally {
groupBusy.value = false;
}
}
function memberAvatar(member) {
return String(member.displayName || member.uid || '?').slice(0, 1).toUpperCase();
}
document.addEventListener('click', closeGroupMenu);
(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .onBeforeUnmount */ .xo)(() => {
document.removeEventListener('click', closeGroupMenu);
});
(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .watch */ .wB)(() => activeConversation.value?.id, () => {
closeGroupMenu();
closeSingleProfile();
closeGroupPanel();
groupDetail.value = null;
groupMembers.value = [];
groupAliasDraft.value = '';
selectedAdminIds.value = [];
selectedKickIds.value = [];
transferTargetId.value = '';
manageSection.value = '';
});
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["chat-panel", {
'has-pinned-message': Boolean((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage)
}])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [isGroupConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "chat-title-button",
onClick: openGroupOverview
}, [activeConversation.value?.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "chat-title-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(activeConversation.value.portrait),
alt: ""
}, null, 8, _hoisted_2)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.avatarText || '?'), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.title || '未选择会话'), 1)])])) : activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "chat-title-button",
onClick: openSingleProfile
}, [singleProfile.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "chat-title-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(singleProfile.value.portrait),
alt: ""
}, null, 8, _hoisted_5)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_6, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.title || '未选择会话'), 1)])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("h2", _hoisted_8, "未选择会话")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(statusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_9, [_cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
class: "icon-button",
title: "搜索"
}, "⌕", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
class: "icon-button",
title: "更多",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(toggleGroupMenu, ["stop"])
}, "⋯"), groupMenuOpen.value && isGroupConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "quick-action-menu chat-more-menu",
onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: openGroupMembers
}, "查看群员"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: openGroupAlias
}, "我在本群的昵称"), canManageGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
onClick: openGroupManage
}, "群组管理")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])]), !activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_10, _cache[32] || (_cache[32] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "选择一个会话", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "真实会话同步完成后,可以在左侧打开聊天", -1)]))) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), activeConversation.value && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "pinned-message-banner",
title: "点击定位该消息",
onClick: _cache[2] || (_cache[2] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).focusMessage((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage))
}, [_cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "📌", -1)), _cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "置顶消息", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_11, [pinnedMessageIsImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage.attachment.url),
alt: "置顶图片"
}, null, 8, _hoisted_12)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(pinnedMessageText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", {
class: "pinned-message-close",
title: "取消置顶",
onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearPinnedMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearPinnedMessage(...args), ["stop"]))
}, "×")])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createBlock */ .Wv)(_MessageList_vue__WEBPACK_IMPORTED_MODULE_16__/* ["default"] */ .A, {
key: 2,
messages: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activeMessages,
"selection-mode": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectionMode,
"selected-message-ids": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectedMessageIds,
"favorite-message-ids": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).favoriteMessageIds,
"pinned-message-id": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage?.key || '',
"attention-message-id": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).attentionMessageId,
"can-recall-others": canManageGroup.value && isGroupConversation.value,
onMessageAction: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).handleMessageAction,
onToggleSelect: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).toggleSelectedMessage,
onSenderProfileUpdated: handleSenderProfileUpdated
}, null, 8, ["messages", "selection-mode", "selected-message-ids", "favorite-message-ids", "pinned-message-id", "attention-message-id", "can-recall-others", "onMessageAction", "onToggleSelect"])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectionMode ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "已选 " + (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectedMessageIds.length) + " 条", 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[3] || (_cache[3] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).copySelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).copySelectedMessages(...args))
}, "复制"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[4] || (_cache[4] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).deleteSelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).deleteSelectedMessages(...args))
}, "删除"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[5] || (_cache[5] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).startForwardSelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).startForwardSelectedMessages(...args))
}, "转发"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[6] || (_cache[6] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearSelection && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearSelection(...args))
}, "取消")])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createVNode */ .bF)(_MessageComposer_vue__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A, {
disabled: !activeConversation.value || !(0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(session).isAuthenticated || !(0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).canSendActiveConversation,
"quote-message": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).quotedMessage,
onCancelQuote: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelQuote,
onSend: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).sendText,
onSendAttachment: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).sendAttachment
}, null, 8, ["disabled", "quote-message", "onCancelQuote", "onSend", "onSendAttachment"]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).forwardingMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 4,
class: "modal-backdrop",
onClick: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward(...args), ["self"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[35] || (_cache[35] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "转发给", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: _cache[7] || (_cache[7] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward(...args))
}, "×")]), ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).conversations, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: item.id,
type: "button",
class: "forward-target",
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeForward(item.id)
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(item.avatarText), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(item.title), 1)], 8, _hoisted_15);
}), 128))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 5,
class: "modal-backdrop",
onClick: _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args), ["self"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("form", {
class: "edit-dialog",
onSubmit: _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeEditMessage(...args), ["prevent"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMode === 'resend' ? '重新编辑' : '编辑消息'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: _cache[9] || (_cache[9] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args))
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingText = $event),
maxlength: "5000",
rows: "5",
autofocus: ""
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingText]]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[11] || (_cache[11] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args))
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMode === 'resend' ? '发送' : '保存'), 1)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 6,
class: "modal-backdrop",
onClick: _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail(...args), ["self"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "消息详情", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: _cache[14] || (_cache[14] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail(...args))
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailLoading ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_19, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dl", _hoisted_20, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[37] || (_cache[37] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "发送时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(messageDetail.value?.sentAt)), 1)]), messageDetail.value?.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_21, [_cache[38] || (_cache[38] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "编辑时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(messageDetail.value.editedAt)), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[39] || (_cache[39] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "发送人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(messageDetail.value?.sender)), 1)]), !isMessageDetailGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[40] || (_cache[40] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "接收人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(messageDetail.value?.receiver)), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[41] || (_cache[41] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "送达时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
'message-detail-muted': !messageDetail.value?.deliveredAt
})
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetail.value?.deliveredAt ? formatDetailTime(messageDetail.value.deliveredAt) : '未送达'), 3)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[42] || (_cache[42] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "已读时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
'message-detail-muted': !messageDetail.value?.readAt
})
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetail.value?.readAt ? formatDetailTime(messageDetail.value.readAt) : '未读'), 3)])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailError ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_22, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailError), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), isMessageDetailGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_23, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[43] || (_cache[43] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("已读 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.read || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[44] || (_cache[44] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("未读 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.unread || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[45] || (_cache[45] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("未送达 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.undelivered || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[46] || (_cache[46] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("成员 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.total || 0), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[47] || (_cache[47] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "已读", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.read || 0) + " 人", 1)]), messageDetailGroup.value?.read?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_26, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.read, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: `read-${member.uid}`,
class: "message-detail-member-row"
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_27)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_29, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_30, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(member.time)), 1), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_31, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_32, "暂无已读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_33, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[48] || (_cache[48] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "未读", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.unread || 0) + " 人", 1)]), messageDetailGroup.value?.unread?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_34, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.unread, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: `unread-${member.uid}`,
class: "message-detail-member-row"
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_35)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_36, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_37, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_38, "送达 " + (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(member.time)), 1), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_39, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_40, "暂无未读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_41, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[49] || (_cache[49] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "未送达", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.undelivered || 0) + " 人", 1)]), messageDetailGroup.value?.undelivered?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_42, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.undelivered, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: `undelivered-${member.uid}`,
class: "message-detail-member-row"
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_43)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_44, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_45, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), _cache[50] || (_cache[50] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", {
class: "message-detail-member-time message-detail-muted"
}, "未送达", -1)), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_46, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_47, "暂无未送达成员"))])])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)], 64))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), singleProfileOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 7,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(closeSingleProfile, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_48, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[51] || (_cache[51] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "联系人资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeSingleProfile
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_49, [singleProfile.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "profile-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(singleProfile.value.portrait),
alt: ""
}, null, 8, _hoisted_50)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_51, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.displayName), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dl", _hoisted_52, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[52] || (_cache[52] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.userId || '-'), 1)]), singleProfile.value.uid && singleProfile.value.uid !== singleProfile.value.userId ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_53, [_cache[53] || (_cache[53] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "用户UID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.uid), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[54] || (_cache[54] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.rawName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[55] || (_cache[55] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.mobile || '未知'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[56] || (_cache[56] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.address || '未知'), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[57] || (_cache[57] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "备注名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[16] || (_cache[16] = $event => singleAliasDraft.value = $event),
maxlength: "32",
autocomplete: "off",
placeholder: "留空使用对方昵称"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, singleAliasDraft.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", _hoisted_54, [singleProfileNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_55, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileNotice.value), 1)) : singleProfileError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_56, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
disabled: singleProfileSaving.value,
onClick: closeSingleProfile
}, "取消", 8, _hoisted_57), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: singleProfileSaving.value || !singleProfile.value.uid,
onClick: saveSingleAlias
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileSaving.value ? '保存中...' : '保存备注'), 9, _hoisted_58)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), groupPanel.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 8,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(closeGroupPanel, ["self"])
}, [groupPanel.value === 'overview' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_59, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[58] || (_cache[58] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群概况", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeGroupPanel
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_60, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("dl", _hoisted_61, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[59] || (_cache[59] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.name || activeConversation.value?.title || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[60] || (_cache[60] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDisplayId.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[61] || (_cache[61] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.announcement || '未设置'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[62] || (_cache[62] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群主昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.ownerName || '-'), 1)])])), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [isGroupOwner.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
key: 0
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "danger-inline-action",
disabled: groupBusy.value,
onClick: dismissCurrentGroup
}, "解散群组", 8, _hoisted_62), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: groupBusy.value,
onClick: openTransferGroup
}, "转让群组", 8, _hoisted_63)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "danger-inline-action",
disabled: groupBusy.value,
onClick: leaveCurrentGroup
}, "退出群组", 8, _hoisted_64))])])) : groupPanel.value === 'members' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_65, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[63] || (_cache[63] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群员", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeGroupPanel
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_66, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_67, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(groupMembers.value, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: member.uid,
class: "group-member-row"
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_68)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_69, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.role === 'owner' ? '群主' : member.rawDisplayName), 1)])]);
}), 128)), !groupMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_70, "暂无群员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]))])) : groupPanel.value === 'alias' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("form", {
key: 2,
class: "group-dialog",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(saveGroupAlias, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[64] || (_cache[64] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "我在本群的昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeGroupPanel
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[65] || (_cache[65] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[17] || (_cache[17] = $event => groupAliasDraft.value = $event),
maxlength: "64",
autocomplete: "off",
placeholder: "留空使用个人昵称"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, groupAliasDraft.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: closeGroupPanel
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
class: "primary-inline-action",
disabled: groupBusy.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupBusy.value ? '保存中...' : '保存'), 9, _hoisted_71)])], 32)) : groupPanel.value === 'transfer' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_72, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[66] || (_cache[66] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "转让群组", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeGroupPanel
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_73, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_74, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(transferableMembers.value, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: member.uid,
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["group-member-row selectable", {
selected: transferTargetId.value === member.uid
}]),
onClick: $event => transferTargetId.value = member.uid
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_76)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_77, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.rawDisplayName), 1)])], 10, _hoisted_75);
}), 128)), !transferableMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_78, "暂无可转让成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: closeGroupPanel
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: groupBusy.value || !transferTargetId.value,
onClick: transferCurrentGroup
}, "确认转让", 8, _hoisted_79)])])) : groupPanel.value === 'manage' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_80, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[67] || (_cache[67] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群组管理", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeGroupPanel
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("nav", _hoisted_81, [isGroupOwner.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
active: manageSection.value === 'admins'
}),
onClick: _cache[18] || (_cache[18] = $event => manageSection.value = 'admins')
}, "管理员设置", 2)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
active: manageSection.value === 'profile'
}),
onClick: _cache[19] || (_cache[19] = $event => manageSection.value = 'profile')
}, "修改群资料", 2), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
active: manageSection.value === 'kick'
}),
onClick: _cache[20] || (_cache[20] = $event => manageSection.value = 'kick')
}, "踢人", 2), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
active: manageSection.value === 'mute'
}),
onClick: _cache[21] || (_cache[21] = $event => manageSection.value = 'mute')
}, "禁言设置", 2)]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_82, "正在加载")) : manageSection.value === 'admins' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_83, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_84, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(adminCandidateMembers.value, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("label", {
key: member.uid,
class: "group-member-row selectable with-check"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
type: "checkbox",
checked: selectedAdminIds.value.includes(member.uid),
onChange: $event => toggleAdmin(member.uid)
}, null, 40, _hoisted_85), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_86)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_87, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.rawDisplayName), 1)])]);
}), 128)), !adminCandidateMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_88, "暂无可设置成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
onClick: saveGroupAdmins
}, "保存管理员")])])) : manageSection.value === 'profile' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_89, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[68] || (_cache[68] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[22] || (_cache[22] = $event => profileDraft.value.name = $event),
maxlength: "128",
autocomplete: "off"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.name, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[69] || (_cache[69] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[23] || (_cache[23] = $event => profileDraft.value.announcement = $event),
maxlength: "1000",
rows: "3"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.announcement, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[70] || (_cache[70] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "欢迎词", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[24] || (_cache[24] = $event => profileDraft.value.welcomeText = $event),
maxlength: "1000",
rows: "3"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.welcomeText, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
onClick: saveGroupProfile
}, "保存资料")])])) : manageSection.value === 'kick' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_90, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_91, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(kickCandidateMembers.value, member => {
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("label", {
key: member.uid,
class: "group-member-row selectable with-check"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
type: "checkbox",
checked: selectedKickIds.value.includes(member.uid),
onChange: $event => toggleKick(member.uid)
}, null, 40, _hoisted_92), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
alt: ""
}, null, 8, _hoisted_93)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_94, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.role === 'admin' ? '管理员' : member.rawDisplayName), 1)])]);
}), 128)), !kickCandidateMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_95, "暂无可移除成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "danger-inline-action",
disabled: !selectedKickIds.value.length,
onClick: kickSelectedMembers
}, "移出群组", 8, _hoisted_96)])])) : manageSection.value === 'mute' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_97, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[72] || (_cache[72] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "禁言模式", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("select", {
"onUpdate:modelValue": _cache[25] || (_cache[25] = $event => muteDraft.value.mode = $event),
onChange: clearMuteSaveFeedback
}, _cache[71] || (_cache[71] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "off"
}, "关闭禁言", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "all_include_admins"
}, "全体禁言包含管理员", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "all_except_admins"
}, "除管理员外全体禁言", -1)]), 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelSelect */ .u1, muteDraft.value.mode]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[74] || (_cache[74] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "时段类型", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("select", {
"onUpdate:modelValue": _cache[26] || (_cache[26] = $event => muteDraft.value.scheduleType = $event),
onChange: clearMuteSaveFeedback
}, _cache[73] || (_cache[73] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "manual"
}, "立即禁言直到管理解除", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "once"
}, "单次", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
value: "daily"
}, "每天固定时段", -1)]), 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelSelect */ .u1, muteDraft.value.scheduleType]])]), muteDraft.value.mode !== 'off' && muteDraft.value.scheduleType === 'once' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_98, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[75] || (_cache[75] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "开始", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[27] || (_cache[27] = $event => muteDraft.value.startsAtLocal = $event),
type: "datetime-local",
onInput: clearMuteSaveFeedback
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.startsAtLocal]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[76] || (_cache[76] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "结束", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[28] || (_cache[28] = $event => muteDraft.value.endsAtLocal = $event),
type: "datetime-local",
onInput: clearMuteSaveFeedback
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.endsAtLocal]])])])) : muteDraft.value.mode !== 'off' && muteDraft.value.scheduleType === 'daily' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_99, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[77] || (_cache[77] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "开始", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[29] || (_cache[29] = $event => muteDraft.value.dailyStart = $event),
type: "time",
onInput: clearMuteSaveFeedback
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.dailyStart]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[78] || (_cache[78] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "结束", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[30] || (_cache[30] = $event => muteDraft.value.dailyEnd = $event),
type: "time",
onInput: clearMuteSaveFeedback
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.dailyEnd]])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", _hoisted_100, [muteSaveNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_101, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(muteSaveNotice.value), 1)) : muteSaveError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_102, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(muteSaveError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: groupBusy.value,
onClick: saveMuteSetting
}, "保存禁言", 8, _hoisted_103)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionNotice || (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
key: 9,
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["chat-toast", {
error: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError
}])
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError || (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionNotice), 3)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)], 2);
};
}
});
/***/ }),
/***/ 6935:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5187);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(144);
const _hoisted_1 = {
key: 0,
class: "quote-preview"
};
const _hoisted_2 = {
class: "composer-tools"
};
const _hoisted_3 = ["disabled"];
const _hoisted_4 = ["disabled"];
const _hoisted_5 = ["disabled"];
const _hoisted_6 = ["onClick"];
const _hoisted_7 = ["disabled", "onKeydown"];
const _hoisted_8 = {
class: "composer-footer"
};
const _hoisted_9 = ["disabled"];
/* harmony default export */ __webpack_exports__.A = ({
__name: 'MessageComposer',
props: {
disabled: {
type: Boolean,
default: false
},
quoteMessage: {
type: Object,
default: null
}
},
emits: ['send', 'send-attachment', 'cancel-quote'],
setup(__props, {
emit: __emit
}) {
const props = __props;
const emit = __emit;
const text = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)('');
const emojiOpen = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(false);
const dropActive = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(false);
const textareaEl = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
const imageInput = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
const fileInput = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
let dragDepth = 0;
const emojiList = ['😀', '😄', '😂', '😊', '😍', '😘', '😎', '😢', '😡', '👍', '🙏', '👏', '💪', '🎉', '❤️', '🔥', '🌹', '☕', '✅', '⭐', '💰', '🎁', '🤝', '👌'];
function submit() {
const value = text.value.trim();
if (!value) {
return;
}
emit('send', value);
text.value = '';
emojiOpen.value = false;
}
function toggleEmojiPicker() {
emojiOpen.value = !emojiOpen.value;
}
function insertEmoji(emoji) {
const element = textareaEl.value;
if (!element) {
text.value += emoji;
return;
}
const start = element.selectionStart ?? text.value.length;
const end = element.selectionEnd ?? text.value.length;
text.value = `${text.value.slice(0, start)}${emoji}${text.value.slice(end)}`;
requestAnimationFrame(() => {
element.focus();
const cursor = start + emoji.length;
element.setSelectionRange(cursor, cursor);
});
}
function chooseImage() {
imageInput.value?.click();
}
function chooseFile() {
fileInput.value?.click();
}
function attachmentTypeForFile(file, fallbackType = 'file') {
if (file?.type?.startsWith('image/')) {
return 'image';
}
return fallbackType === 'image' ? 'image' : 'file';
}
function emitFiles(files, fallbackType = 'file') {
if (props.disabled) {
return;
}
const validFiles = Array.from(files || []).filter(file => file instanceof File && file.size > 0);
if (!validFiles.length) {
return;
}
const caption = text.value.trim();
validFiles.forEach((file, index) => {
emit('send-attachment', {
type: attachmentTypeForFile(file, fallbackType),
file,
text: index === 0 ? caption : ''
});
});
text.value = '';
emojiOpen.value = false;
}
function selectAttachment(event, type) {
const input = event.target;
const files = input.files ? Array.from(input.files) : [];
input.value = '';
if (!files.length || props.disabled) {
return;
}
emitFiles(files, type);
}
function hasDraggedFiles(event) {
const types = Array.from(event.dataTransfer?.types || []);
return types.includes('Files');
}
function handleDragEnter(event) {
if (props.disabled || !hasDraggedFiles(event)) {
return;
}
dragDepth += 1;
dropActive.value = true;
event.dataTransfer.dropEffect = 'copy';
}
function handleDragOver(event) {
if (props.disabled || !hasDraggedFiles(event)) {
return;
}
dropActive.value = true;
event.dataTransfer.dropEffect = 'copy';
}
function handleDragLeave() {
dragDepth = Math.max(0, dragDepth - 1);
if (dragDepth === 0) {
dropActive.value = false;
}
}
function filesFromDataTransfer(dataTransfer) {
const items = Array.from(dataTransfer?.items || []);
const files = items.filter(item => item.kind === 'file' && !item.webkitGetAsEntry?.()?.isDirectory).map(item => item.getAsFile()).filter(Boolean);
if (files.length) {
return files;
}
return Array.from(dataTransfer?.files || []);
}
function handleDrop(event) {
dragDepth = 0;
dropActive.value = false;
if (props.disabled) {
return;
}
emitFiles(filesFromDataTransfer(event.dataTransfer));
}
function imageFilesFromClipboard(clipboardData) {
return Array.from(clipboardData?.items || []).filter(item => item.kind === 'file' && item.type.startsWith('image/')).map(item => item.getAsFile()).filter(Boolean);
}
function handlePaste(event) {
if (props.disabled) {
return;
}
const imageFiles = imageFilesFromClipboard(event.clipboardData);
if (!imageFiles.length) {
return;
}
event.preventDefault();
emitFiles(imageFiles, 'image');
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("form", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .normalizeClass */ .C4)(["message-composer", {
'drop-active': dropActive.value
}]),
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(submit, ["prevent"]),
onDragenter: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragEnter, ["prevent"]),
onDragover: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragOver, ["prevent"]),
onDragleave: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragLeave, ["prevent"]),
onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDrop, ["prevent"]),
onPaste: handlePaste
}, [__props.quoteMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("strong", null, "引用", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createTextVNode */ .eW)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .toDisplayString */ .v_)(__props.quoteMessage.quoteText || __props.quoteMessage.text), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "取消引用",
onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('cancel-quote'))
}, "×")])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "表情",
disabled: __props.disabled,
onClick: toggleEmojiPicker
}, "☺", 8, _hoisted_3), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "图片",
disabled: __props.disabled,
onClick: chooseImage
}, "▧", 8, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "文件",
disabled: __props.disabled,
onClick: chooseFile
}, "▤", 8, _hoisted_5), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("input", {
ref_key: "imageInput",
ref: imageInput,
type: "file",
accept: "image/*",
multiple: "",
onChange: _cache[1] || (_cache[1] = $event => selectAttachment($event, 'image'))
}, null, 544), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("input", {
ref_key: "fileInput",
ref: fileInput,
type: "file",
multiple: "",
onChange: _cache[2] || (_cache[2] = $event => selectAttachment($event, 'file'))
}, null, 544), emojiOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "emoji-picker",
onClick: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .renderList */ .pI)(emojiList, emoji => {
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
key: emoji,
type: "button",
onClick: $event => insertEmoji(emoji)
}, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .toDisplayString */ .v_)(emoji), 9, _hoisted_6);
}), 64))])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("textarea", {
ref_key: "textareaEl",
ref: textareaEl,
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => text.value = $event),
disabled: __props.disabled,
placeholder: "输入消息",
rows: "3",
onKeydown: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withKeys */ .jR)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(submit, ["exact", "prevent"]), ["enter"])
}, null, 40, _hoisted_7), [[vue__WEBPACK_IMPORTED_MODULE_5__/* .vModelText */ .Jo, text.value]]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_8, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, "Enter 发送,Shift + Enter 换行", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
class: "send-button",
disabled: __props.disabled || !text.value.trim()
}, "发送", 8, _hoisted_9)])], 34);
};
}
});
/***/ }),
/***/ 4021:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5187);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(9045);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(446);
const _hoisted_1 = ["data-message-key", "onClick"];
const _hoisted_2 = {
key: 0,
class: "system-message-pill"
};
const _hoisted_3 = {
key: 1,
class: "message-select"
};
const _hoisted_4 = ["checked", "onChange"];
const _hoisted_5 = ["title", "onClick"];
const _hoisted_6 = ["src"];
const _hoisted_7 = {
key: 1
};
const _hoisted_8 = {
key: 3,
class: "message-stack"
};
const _hoisted_9 = ["onClick"];
const _hoisted_10 = {
key: 0,
class: "message-sender-role"
};
const _hoisted_11 = ["onContextmenu"];
const _hoisted_12 = {
key: 0,
class: "red-packet-card"
};
const _hoisted_13 = {
class: "red-packet-card-main"
};
const _hoisted_14 = {
key: 1,
class: "red-packet-receipt"
};
const _hoisted_15 = ["onClick"];
const _hoisted_16 = ["src", "alt"];
const _hoisted_17 = ["src"];
const _hoisted_18 = ["href"];
const _hoisted_19 = {
class: "message-file-main"
};
const _hoisted_20 = {
key: 5
};
const _hoisted_21 = {
key: 0,
class: "recall-mark"
};
const _hoisted_22 = {
key: 1,
class: "edit-mark"
};
const _hoisted_23 = {
key: 2,
class: "favorite-mark",
title: "已收藏",
"aria-label": "已收藏"
};
const _hoisted_24 = ["title", "aria-label"];
const _hoisted_25 = {
key: 0,
class: "delivery-check delivery-check-second"
};
const _hoisted_26 = {
key: 4,
class: "delivery-error"
};
const _hoisted_27 = ["onClick"];
const _hoisted_28 = ["src", "alt"];
const _hoisted_29 = {
class: "sender-profile-main"
};
const _hoisted_30 = ["src"];
const _hoisted_31 = {
key: 1,
class: "profile-avatar"
};
const _hoisted_32 = {
key: 2
};
const _hoisted_33 = {
class: "sender-profile-fields"
};
const _hoisted_34 = {
key: 0
};
const _hoisted_35 = {
class: "sender-profile-alias"
};
const _hoisted_36 = ["disabled"];
const _hoisted_37 = {
class: "sender-profile-actions"
};
const _hoisted_38 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_39 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_40 = ["disabled"];
const _hoisted_41 = ["disabled"];
const IMAGE_MIN_SCALE = 0.5;
const IMAGE_MAX_SCALE = 6;
/* harmony default export */ __webpack_exports__.A = ({
__name: 'MessageList',
props: {
messages: {
type: Array,
default: () => []
},
selectionMode: {
type: Boolean,
default: false
},
selectedMessageIds: {
type: Array,
default: () => []
},
favoriteMessageIds: {
type: Array,
default: () => []
},
pinnedMessageId: {
type: String,
default: ''
},
attentionMessageId: {
type: String,
default: ''
},
canRecallOthers: {
type: Boolean,
default: false
}
},
emits: ['message-action', 'toggle-select', 'sender-profile-updated'],
setup(__props, {
emit: __emit
}) {
const props = __props;
const emit = __emit;
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_10__/* .useContactStore */ .p)();
const listEl = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
const viewerStage = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
const contextMenu = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
visible: false,
x: 0,
y: 0,
message: null
});
const imageViewer = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
visible: false,
url: '',
name: '',
sourceUrl: '',
index: 0,
scale: 1,
rotation: 0,
offsetX: 0,
offsetY: 0,
dragging: false,
dragStartX: 0,
dragStartY: 0,
dragOffsetX: 0,
dragOffsetY: 0
});
const senderProfile = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
visible: false,
uid: '',
userId: '',
displayName: '',
rawName: '',
mobile: '',
address: '',
portrait: '',
avatarText: '',
role: '',
roleLabel: '',
contactAlias: '',
groupAlias: '',
isContact: false,
aliasDraft: '',
saving: false,
adding: false,
notice: '',
error: ''
});
const imageViewerStyle = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => ({
transform: `translate3d(${imageViewer.offsetX}px, ${imageViewer.offsetY}px, 0) scale(${imageViewer.scale}) rotate(${imageViewer.rotation}deg)`
}));
const viewerImages = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => props.messages.filter(message => isImageMessage(message)));
const menuItems = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => {
if (!contextMenu.message) {
return [];
}
const isOwnMessage = contextMenu.message.direction === 'out';
if (isRecalledMessage(contextMenu.message)) {
return [...(isOwnMessage ? [{
action: 'edit',
label: '编辑'
}] : []), {
action: 'copy',
label: '复制'
}, {
action: 'delete',
label: '删除'
}, {
action: 'detail',
label: '详情'
}];
}
const favoriteLabel = isFavorite(contextMenu.message) ? '取消收藏' : '收藏';
const pinnedLabel = props.pinnedMessageId === messageIdentity(contextMenu.message) ? '取消置顶' : '置顶';
const items = [{
action: 'copy',
label: '复制'
}, {
action: 'delete',
label: '删除'
}, {
action: 'forward',
label: '转发'
}, {
action: 'favorite',
label: favoriteLabel
}, {
action: 'pin',
label: pinnedLabel
}, {
action: 'quote',
label: '引用'
}, {
action: 'select',
label: '多选'
}, {
action: 'detail',
label: '详情'
}];
if (isOwnMessage) {
items.unshift({
action: 'edit',
label: '编辑'
});
items.push({
action: 'recall',
label: '撤回'
});
} else if (props.canRecallOthers) {
items.push({
action: 'recall',
label: '撤回'
});
}
return items;
});
function scrollToBottom() {
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .nextTick */ .dY)(() => {
if (listEl.value) {
listEl.value.scrollTop = listEl.value.scrollHeight;
}
});
}
function scrollToMessage(messageId) {
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .nextTick */ .dY)(() => {
if (!listEl.value || !messageId) {
return;
}
const row = Array.from(listEl.value.querySelectorAll('.message-row')).find(element => element.dataset.messageKey === messageId);
if (row) {
row.scrollIntoView({
block: 'center',
behavior: 'smooth'
});
}
});
}
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .watch */ .wB)(() => props.messages.map(message => `${message.id}:${message.status}:${message.deliveryStatus || ''}:${message.messageUid || ''}:${message.recalled ? '1' : ''}`).join('|'), scrollToBottom, {
immediate: true
});
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .watch */ .wB)(() => props.attentionMessageId, scrollToMessage);
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .onMounted */ .sV)(() => {
document.addEventListener('click', closeMenu);
document.addEventListener('keydown', closeMenuOnEscape);
document.addEventListener('pointermove', moveImageDrag);
document.addEventListener('pointerup', stopImageDrag);
});
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .onBeforeUnmount */ .xo)(() => {
document.removeEventListener('click', closeMenu);
document.removeEventListener('keydown', closeMenuOnEscape);
document.removeEventListener('pointermove', moveImageDrag);
document.removeEventListener('pointerup', stopImageDrag);
});
function messageIdentity(message) {
return String(message.messageUid || message.id || '');
}
function canOpenMessageMenu(message) {
return message && message.status !== 'failed' && message.status !== 'sending';
}
function isSelected(message) {
return props.selectedMessageIds.includes(messageIdentity(message));
}
function isFavorite(message) {
return props.favoriteMessageIds.includes(messageIdentity(message));
}
function isAttention(message) {
return props.attentionMessageId === messageIdentity(message);
}
function isRecallNotice(message) {
return message.direction === 'out' && (message.recalled || message.status === 'recalled');
}
function isRecalledMessage(message) {
return message.recalled || message.status === 'recalled';
}
function isImageMessage(message) {
return message?.type === 'image' && message?.attachment?.url;
}
function isFileMessage(message) {
return message?.type === 'file' && message?.attachment?.url;
}
function isVideoMessage(message) {
return (message?.type === 'video' || Number(message?.contentType || 0) === 6) && message?.attachment?.url;
}
function isRedPacketMessage(message) {
return Number(message?.contentType || 0) === 90 || Boolean(redPacketPayload(message));
}
function isRedPacketReceipt(message) {
return Number(message?.contentType || 0) === 105;
}
function isSystemMessage(message) {
return [92, 93].includes(Number(message?.contentType || 0));
}
function systemMessageText(message) {
const contentType = Number(message?.contentType || 0);
if (contentType === 92) {
return '以上是打招呼的内容';
}
if (contentType === 93) {
return '你们已经是好友了,可以开始聊天了。';
}
return String(message?.text || '');
}
function redPacketReceiptText(message) {
const text = String(message?.text || '').trim();
if (text && text !== '[领取了红包]') {
return text;
}
const receiverName = message?.direction === 'out' ? '你' : message?.senderName || '对方';
const packetSenderName = message?.redPacketSenderName || nearestRedPacketSenderName(message);
return packetSenderName ? `${receiverName}领取了${packetSenderName}的红包` : `${receiverName}领取了红包`;
}
function nearestRedPacketSenderName(receiptMessage) {
const receiptIndex = props.messages.findIndex(item => messageIdentity(item) === messageIdentity(receiptMessage));
for (let index = receiptIndex - 1; index >= 0; index -= 1) {
const candidate = props.messages[index];
if (isRedPacketMessage(candidate)) {
return candidate?.direction === 'out' ? '你' : candidate?.senderName || '对方';
}
}
return '';
}
function redPacketPayload(message) {
if (message?.redPacket && typeof message.redPacket === 'object') {
return message.redPacket;
}
const text = String(message?.text || '').trim();
if (!text.startsWith('{')) {
return null;
}
try {
const payload = JSON.parse(text);
return payload?.redPackets || payload?.redPacket || null;
} catch (error) {
return null;
}
}
function redPacketBlessing(message) {
return String(redPacketPayload(message)?.blessing || '恭喜发财,大吉大利');
}
function isGroupMessage(message) {
return ['group', 'channel'].includes(message?.conversationType || '');
}
function showGroupSender(message) {
return isGroupMessage(message) && message?.direction === 'in';
}
function senderRoleLabel(message) {
const role = message?.senderProfile?.role || message?.senderRole || '';
if (role === 'owner') {
return '群主';
}
if (role === 'admin') {
return '管理员';
}
return '';
}
function groupSenderName(message) {
return message?.senderName || message?.senderProfile?.displayName || message?.from || '未知用户';
}
function groupSenderAvatarText(message) {
return String(groupSenderName(message) || '?').slice(0, 1).toUpperCase();
}
function openSenderProfile(message) {
const profile = message?.senderProfile || {};
const uid = profile.uid || message?.from || '';
const cachedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === uid) || null;
const cachedAlias = String(cachedContact?.alias || '').trim();
const contactAlias = String(profile.contactAlias || cachedAlias || profile.remarkAlias || '').trim();
const groupAlias = String(profile.groupAlias || '').trim();
const rawName = profile.rawName || cachedContact?.rawUser?.displayName || cachedContact?.rawUser?.name || cachedContact?.title || groupSenderName(message);
const displayName = contactAlias || groupAlias || rawName || uid;
senderProfile.visible = true;
senderProfile.uid = uid;
senderProfile.userId = profile.userId || profile.name || cachedContact?.rawUser?.name || uid;
senderProfile.displayName = displayName;
senderProfile.rawName = rawName || '';
senderProfile.mobile = profile.mobile || cachedContact?.rawUser?.mobile || '';
senderProfile.address = profile.address || cachedContact?.address || cachedContact?.rawUser?.address || '';
senderProfile.portrait = profile.portrait || cachedContact?.portrait || message?.senderPortrait || '';
senderProfile.avatarText = String(displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();
senderProfile.role = profile.role || message?.senderRole || '';
senderProfile.roleLabel = senderRoleLabel(message);
senderProfile.contactAlias = contactAlias;
senderProfile.groupAlias = groupAlias;
senderProfile.isContact = Boolean(profile.isContact || cachedContact);
senderProfile.aliasDraft = contactAlias;
senderProfile.saving = false;
senderProfile.adding = false;
senderProfile.notice = '';
senderProfile.error = '';
closeMenu();
}
function closeSenderProfile() {
if (senderProfile.saving || senderProfile.adding) {
return;
}
senderProfile.visible = false;
}
async function addSenderAsContact() {
if (!senderProfile.uid || senderProfile.adding || senderProfile.saving) {
return;
}
senderProfile.adding = true;
senderProfile.notice = '';
senderProfile.error = '';
const ok = await contacts.addContact(senderProfile.uid);
if (ok || String(contacts.actionError || '').includes('已经是联系人')) {
senderProfile.isContact = true;
const alias = senderProfile.aliasDraft.trim();
let aliasSaved = false;
if (alias) {
aliasSaved = await contacts.updateContactAlias(senderProfile.uid, alias);
if (aliasSaved) {
senderProfile.contactAlias = alias;
senderProfile.displayName = alias;
senderProfile.avatarText = String(alias || senderProfile.uid || '?').slice(0, 1).toUpperCase();
}
}
await contacts.refreshContacts({
force: true
}).catch(() => {});
if (alias && !aliasSaved) {
senderProfile.notice = '';
senderProfile.error = contacts.actionError ? `已添加为好友,但${contacts.actionError}` : '已添加为好友,但备注名同步失败';
} else {
senderProfile.notice = alias ? '已添加为好友,备注名已保存' : ok ? '已添加为好友' : '已是好友';
}
emit('sender-profile-updated', {
userId: senderProfile.uid
});
} else {
senderProfile.error = contacts.actionError || '添加好友失败';
}
senderProfile.adding = false;
}
async function saveSenderAlias() {
if (!senderProfile.uid || senderProfile.saving || senderProfile.adding) {
return;
}
senderProfile.saving = true;
senderProfile.notice = '';
senderProfile.error = '';
const ok = await contacts.updateContactAlias(senderProfile.uid, senderProfile.aliasDraft);
if (ok) {
await contacts.refreshContacts({
force: true
}).catch(() => {});
const alias = senderProfile.aliasDraft.trim();
senderProfile.contactAlias = alias;
senderProfile.displayName = alias || senderProfile.groupAlias || senderProfile.rawName || senderProfile.uid;
senderProfile.avatarText = String(senderProfile.displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();
senderProfile.notice = '备注名已保存';
emit('sender-profile-updated', {
userId: senderProfile.uid
});
} else {
senderProfile.error = contacts.actionError || '备注名修改失败';
}
senderProfile.saving = false;
}
function roleBubbleClass(message) {
const role = message?.senderRole || '';
if (role === 'owner') {
return 'role-bubble-owner';
}
if (role === 'admin') {
return 'role-bubble-admin';
}
return '';
}
function formatFileSize(size) {
const bytes = Number(size || 0);
if (bytes >= 1024 * 1024) {
return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;
}
if (bytes >= 1024) {
return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;
}
return bytes > 0 ? `${bytes} B` : '';
}
function handleMessageClick(message) {
if (props.selectionMode) {
emit('toggle-select', message);
}
}
function handleImageClick(message) {
if (props.selectionMode) {
emit('toggle-select', message);
return;
}
openImageViewer(message);
}
function openImageViewer(message) {
const attachment = message?.attachment || {};
if (!attachment.url) {
return;
}
closeMenu();
imageViewer.visible = true;
const index = viewerImages.value.findIndex(item => messageIdentity(item) === messageIdentity(message));
showViewerImage(index >= 0 ? index : 0);
}
function showViewerImage(index) {
const images = viewerImages.value;
if (!images.length) {
closeImageViewer();
return;
}
const normalizedIndex = (index + images.length) % images.length;
const attachment = images[normalizedIndex]?.attachment || {};
imageViewer.index = normalizedIndex;
imageViewer.sourceUrl = attachment.url || '';
imageViewer.url = (0,_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(attachment.url || '');
imageViewer.name = attachment.name || `图片 ${normalizedIndex + 1}`;
resetImageViewer();
}
function showPreviousImage() {
showViewerImage(imageViewer.index - 1);
}
function showNextImage() {
showViewerImage(imageViewer.index + 1);
}
function closeImageViewer() {
imageViewer.visible = false;
imageViewer.dragging = false;
imageViewer.sourceUrl = '';
}
function resetImageViewer() {
imageViewer.scale = 1;
imageViewer.rotation = 0;
imageViewer.offsetX = 0;
imageViewer.offsetY = 0;
}
function clampImageScale(value) {
return Math.min(IMAGE_MAX_SCALE, Math.max(IMAGE_MIN_SCALE, Number(value.toFixed(2))));
}
function setImageScale(value, originX = null, originY = null) {
const previousScale = imageViewer.scale;
const nextScale = clampImageScale(value);
if (nextScale === previousScale) {
return;
}
if (originX !== null && originY !== null && viewerStage.value) {
const rect = viewerStage.value.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const ratio = nextScale / previousScale - 1;
imageViewer.offsetX -= (originX - centerX - imageViewer.offsetX) * ratio;
imageViewer.offsetY -= (originY - centerY - imageViewer.offsetY) * ratio;
}
imageViewer.scale = nextScale;
if (nextScale <= 1) {
imageViewer.offsetX = 0;
imageViewer.offsetY = 0;
}
}
function zoomImage(delta) {
setImageScale(imageViewer.scale + delta);
}
function rotateImage() {
imageViewer.rotation = (imageViewer.rotation + 90) % 360;
}
function handleImageWheel(event) {
const factor = event.deltaY < 0 ? 1.12 : 1 / 1.12;
setImageScale(imageViewer.scale * factor, event.clientX, event.clientY);
}
function startImageDrag(event) {
if (!imageViewer.visible || imageViewer.scale <= 1) {
return;
}
imageViewer.dragging = true;
imageViewer.dragStartX = event.clientX;
imageViewer.dragStartY = event.clientY;
imageViewer.dragOffsetX = imageViewer.offsetX;
imageViewer.dragOffsetY = imageViewer.offsetY;
}
function moveImageDrag(event) {
if (!imageViewer.dragging) {
return;
}
imageViewer.offsetX = imageViewer.dragOffsetX + event.clientX - imageViewer.dragStartX;
imageViewer.offsetY = imageViewer.dragOffsetY + event.clientY - imageViewer.dragStartY;
}
function stopImageDrag() {
imageViewer.dragging = false;
}
function saveViewerImage() {
if (!imageViewer.sourceUrl) {
return;
}
const downloadUrl = new URL('/api/media_download.php', window.location.origin);
downloadUrl.searchParams.set('url', imageViewer.sourceUrl);
downloadUrl.searchParams.set('name', imageViewer.name || 'image');
const link = document.createElement('a');
link.href = downloadUrl.toString();
link.download = imageViewer.name || 'image';
document.body.appendChild(link);
link.click();
link.remove();
}
function openMenu(event, message) {
if (!canOpenMessageMenu(message)) {
closeMenu();
return;
}
contextMenu.visible = true;
contextMenu.message = message;
contextMenu.x = Math.min(event.clientX, window.innerWidth - 148);
contextMenu.y = Math.min(event.clientY, window.innerHeight - 352);
}
function closeMenu() {
contextMenu.visible = false;
contextMenu.message = null;
}
function closeMenuOnEscape(event) {
if (imageViewer.visible && event.key === 'ArrowLeft') {
event.preventDefault();
showPreviousImage();
return;
}
if (imageViewer.visible && event.key === 'ArrowRight') {
event.preventDefault();
showNextImage();
return;
}
if (event.key === 'Escape') {
if (senderProfile.visible) {
closeSenderProfile();
}
if (imageViewer.visible) {
closeImageViewer();
}
closeMenu();
}
}
function chooseMenuAction(action) {
if (contextMenu.message) {
emit('message-action', {
action,
message: contextMenu.message
});
}
closeMenu();
}
function formatTime(timestamp) {
return new Intl.DateTimeFormat('zh-CN', {
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
}).format(timestamp);
}
function deliveryState(message) {
if (message.direction !== 'out' || message.status === 'failed' || message.status === 'recalled' || message.recalled) {
return '';
}
const state = message.deliveryStatus || message.status;
if (state === 'read') {
return 'read';
}
if (state === 'delivered') {
return 'delivered';
}
if (state === 'sent') {
return 'sent';
}
return '';
}
function deliveryTitle(message) {
const state = deliveryState(message);
if (state === 'read') {
return '对方已读';
}
if (state === 'delivered') {
return '已送达对方';
}
if (state === 'sent') {
return '已送出';
}
return '';
}
function failureText(message) {
if (message.status === 'failed') {
if (message.errorCode) {
return message.error ? `失败:${message.error}(${message.errorCode})` : `失败:${message.errorCode}`;
}
return message.error ? `失败:${message.error}` : '失败';
}
return '';
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
ref_key: "listEl",
ref: listEl,
class: "message-list"
}, [((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .renderList */ .pI)(__props.messages, message => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("article", {
key: message.id,
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["message-row", [message.direction, {
system: isSystemMessage(message),
selected: isSelected(message),
attention: isAttention(message),
recalled: message.recalled || message.status === 'recalled'
}]]),
"data-message-key": messageIdentity(message),
onClick: $event => handleMessageClick(message)
}, [isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_2, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(systemMessageText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), __props.selectionMode && !isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("label", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("input", {
type: "checkbox",
checked: isSelected(message),
onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
onChange: $event => emit('toggle-select', message)
}, null, 40, _hoisted_4)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !isSystemMessage(message) && showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 2,
type: "button",
class: "message-sender-avatar",
title: groupSenderName(message),
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
}, [message.senderPortrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("img", {
key: 0,
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(message.senderPortrait),
alt: ""
}, null, 8, _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(groupSenderAvatarText(message)), 1))], 8, _hoisted_5)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_8, [showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "message-sender-name",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createTextVNode */ .eW)((0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(groupSenderName(message)) + " ", 1), senderRoleLabel(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderRoleLabel(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 8, _hoisted_9)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["message-bubble", roleBubbleClass(message)]),
onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openMenu($event, message), ["prevent"])
}, [isRedPacketMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_13, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
class: "red-packet-icon"
}, "福", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(redPacketBlessing(message)), 1), _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("small", null, "请在 App 上领取", -1))])]), _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
class: "red-packet-card-footer"
}, "中聊红包", -1))])) : isRedPacketReceipt(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_14, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
class: "red-packet-mini-icon"
}, "福", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(redPacketReceiptText(message)), 1)])) : isImageMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 2,
type: "button",
class: "message-image",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => handleImageClick(message), ["stop"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("img", {
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(message.attachment.url),
alt: message.attachment.name || '图片'
}, null, 8, _hoisted_16)], 8, _hoisted_15)) : isVideoMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("video", {
key: 3,
class: "message-video",
src: message.attachment.url,
controls: "",
playsinline: "",
preload: "metadata"
}, " 当前浏览器无法播放该视频 ", 8, _hoisted_17)) : isFileMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("a", {
key: 4,
class: "message-file",
href: message.attachment.url,
target: "_blank",
rel: "noreferrer",
download: ""
}, [_cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
class: "message-file-icon"
}, "▤", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", _hoisted_19, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.attachment.name || '文件'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatFileSize(message.attachment.size)), 1)])], 8, _hoisted_18)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), message.text && !isRedPacketMessage(message) && !isRedPacketReceipt(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("p", _hoisted_20, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.text), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("time", null, [isRecallNotice(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.recallStatus || '已撤回'), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatTime(message.displayTimestamp || message.timestamp)), 1), message.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_22, "【edit " + (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatTime(message.editedAt)) + "】", 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), isFavorite(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_23, "★")) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), deliveryState(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", {
key: 3,
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["delivery-mark", `delivery-mark-${deliveryState(message)}`]),
title: deliveryTitle(message),
"aria-label": deliveryTitle(message)
}, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
class: "delivery-check"
}, "✓", -1)), deliveryState(message) !== 'sent' ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_25, "✓")) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_24)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), message.status === 'failed' ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(failureText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)])], 42, _hoisted_11)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_1);
}), 128)), contextMenu.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "message-context-menu",
style: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeStyle */ .Tr)({
left: `${contextMenu.x}px`,
top: `${contextMenu.y}px`
}),
onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .renderList */ .pI)(menuItems.value, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: item.action,
type: "button",
onClick: $event => chooseMenuAction(item.action)
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(item.label), 9, _hoisted_27);
}), 128))], 4)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Teleport */ .Im, {
to: "body"
}, [imageViewer.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "image-viewer-backdrop",
onClick: closeImageViewer
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
class: "image-viewer-dialog",
onClick: _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
class: "image-viewer-toolbar"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "旋转",
"aria-label": "旋转",
onClick: rotateImage
}, "⟳"), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "保存",
"aria-label": "保存",
onClick: saveViewerImage
}, "⇩"), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "关闭",
"aria-label": "关闭",
onClick: closeImageViewer
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
ref_key: "viewerStage",
ref: viewerStage,
class: "image-viewer-stage"
}, [viewerImages.value.length > 1 ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "image-viewer-nav image-viewer-prev",
title: "上一张",
"aria-label": "上一张",
onPointerdown: _cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(showPreviousImage, ["stop"])
}, "‹", 32)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("img", {
class: "image-viewer-img",
src: imageViewer.url,
alt: imageViewer.name || '图片',
style: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeStyle */ .Tr)(imageViewerStyle.value),
draggable: "false"
}, null, 12, _hoisted_28), viewerImages.value.length > 1 ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "image-viewer-nav image-viewer-next",
title: "下一张",
"aria-label": "下一张",
onPointerdown: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(showNextImage, ["stop"])
}, "›", 32)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 512)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)])), ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Teleport */ .Im, {
to: "body"
}, [senderProfile.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "sender-profile-backdrop",
onClick: closeSenderProfile
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("section", {
class: "sender-profile-dialog",
onClick: _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("header", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, "用户资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeSenderProfile
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_29, [senderProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "profile-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(senderProfile.portrait),
alt: ""
}, null, 8, _hoisted_30)) : ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_31, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.displayName || senderProfile.uid), 1), senderProfile.roleLabel ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_32, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.roleLabel), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dl", _hoisted_33, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.userId || senderProfile.uid || '-'), 1)]), senderProfile.uid && senderProfile.userId && senderProfile.uid !== senderProfile.userId ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_34, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "用户UID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.uid), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.rawName || senderProfile.displayName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.mobile || '未知'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.address || '未知'), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("label", _hoisted_35, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, "备注名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => senderProfile.aliasDraft = $event),
maxlength: "32",
autocomplete: "off",
placeholder: "可给群员设置备注",
disabled: senderProfile.saving || senderProfile.adding
}, null, 8, _hoisted_36), [[vue__WEBPACK_IMPORTED_MODULE_6__/* .vModelText */ .Jo, senderProfile.aliasDraft, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("footer", _hoisted_37, [senderProfile.notice ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_38, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.notice), 1)) : senderProfile.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_39, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !senderProfile.isContact ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
key: 2,
type: "button",
class: "ghost-inline-action",
disabled: senderProfile.adding || senderProfile.saving || !senderProfile.uid,
onClick: addSenderAsContact
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.adding ? '添加中...' : '添加为好友'), 9, _hoisted_40)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: senderProfile.saving || senderProfile.adding || !senderProfile.uid,
onClick: saveSenderAlias
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.saving ? '保存中...' : '保存备注'), 9, _hoisted_41)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)]))], 512);
};
}
});
/***/ }),
/***/ 3915:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5187);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9045);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(446);
const _hoisted_1 = {
class: "contact-panel"
};
const _hoisted_2 = {
class: "chat-header"
};
const _hoisted_3 = {
class: "contact-profile"
};
const _hoisted_4 = ["src"];
const _hoisted_5 = {
key: 1,
class: "profile-avatar"
};
const _hoisted_6 = {
class: "profile-main"
};
const _hoisted_7 = {
class: "remark-row"
};
const _hoisted_8 = {
class: "profile-fields"
};
const _hoisted_9 = {
key: 0,
class: "form-error"
};
const _hoisted_10 = {
class: "modal-actions"
};
const _hoisted_11 = ["disabled"];
const _hoisted_12 = ["disabled"];
const _hoisted_13 = {
key: 1,
class: "empty-chat"
};
/* harmony default export */ __webpack_exports__.A = ({
__name: 'ContactPanel',
setup(__props) {
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_4__/* .useContactStore */ .p)();
const contact = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contacts.activeContact);
const remarkName = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.alias || '未设置');
const username = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.displayName || contact.value?.rawUser?.name || contact.value?.uid || '');
const mobile = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.mobile || '未知');
const address = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.address || '未知');
const editingAlias = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
const aliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
const aliasSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
const aliasError = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .watch */ .wB)(contact, () => {
editingAlias.value = false;
aliasError.value = '';
});
function openAliasEditor() {
aliasDraft.value = contact.value?.alias || '';
aliasError.value = '';
editingAlias.value = true;
}
function closeAliasEditor() {
if (aliasSaving.value) {
return;
}
editingAlias.value = false;
aliasError.value = '';
}
async function submitAlias() {
if (!contact.value) {
return;
}
aliasSaving.value = true;
aliasError.value = '';
const ok = await contacts.updateContactAlias(contact.value.uid, aliasDraft.value);
aliasSaving.value = false;
if (ok) {
editingAlias.value = false;
return;
}
aliasError.value = contacts.actionError || '备注名修改失败';
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("section", _hoisted_1, [contact.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_1__/* .Fragment */ .FK, {
key: 0
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(remarkName.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(username.value), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_3, [contact.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "profile-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__/* .imageDisplayUrl */ .B)(contact.value.portrait),
alt: ""
}, null, 8, _hoisted_4)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(contact.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(remarkName.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button remark-edit-button",
title: "编辑备注名",
onClick: openAliasEditor
}, "✏️")])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dl", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(username.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(mobile.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(address.value), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
class: "primary-action profile-action",
onClick: _cache[0] || (_cache[0] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(contacts).openChat(contact.value))
}, "发消息")]), editingAlias.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "modal-backdrop contact-modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(closeAliasEditor, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("form", {
class: "modal-panel",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(submitAlias, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "编辑备注名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeAliasEditor
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "备注名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => aliasDraft.value = $event),
maxlength: "32",
autocomplete: "off",
autofocus: ""
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, aliasDraft.value, void 0, {
trim: true
}]])]), aliasError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(aliasError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
disabled: aliasSaving.value,
onClick: closeAliasEditor
}, "取消", 8, _hoisted_11), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
type: "submit",
class: "primary-inline-action",
disabled: aliasSaving.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(aliasSaving.value ? '保存中' : '保存'), 9, _hoisted_12)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", _hoisted_13, _cache[7] || (_cache[7] = [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "选择一个联系人", -1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "好友列表同步完成后,可以在左侧查看资料", -1)])))]);
};
}
});
/***/ }),
/***/ 9829:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7566);
const _hoisted_1 = {
class: "conversation-list favorite-list"
};
const _hoisted_2 = {
class: "list-header"
};
const _hoisted_3 = {
class: "sidebar-scroll"
};
const _hoisted_4 = ["onClick"];
const _hoisted_5 = {
class: "favorite-item-main"
};
const _hoisted_6 = {
key: 0,
class: "empty-list"
};
/* harmony default export */ __webpack_exports__.A = ({
__name: 'FavoriteList',
setup(__props) {
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_5__/* .useConversationStore */ .w)();
const activeKey = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => conversations.activeFavorite?.key || '');
function favoriteTitle(item) {
if (item.conversationTitle) {
return item.conversationTitle;
}
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
return conversation?.title || item.conversationId || '未知会话';
}
function favoritePreview(item) {
if (item.recalled) {
return `[${item.recallStatus || '已撤回'}]`;
}
if (item.preview) {
return item.preview;
}
if (item.text) {
return item.text;
}
if (item.type === 'image') {
return '[图片]';
}
if (item.type === 'file') {
return `[文件] ${item.attachment?.name || '文件'}`;
}
return '(无文字内容)';
}
function formatFavoriteTime(timestamp) {
const value = Number(timestamp || 0);
if (!value) {
return '';
}
return new Intl.DateTimeFormat('zh-CN', {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false
}).format(value);
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h2", null, "收藏", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages.length) + " 条消息", 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .renderList */ .pI)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
key: item.key,
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["favorite-item", {
active: activeKey.value === item.key
}]),
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).setActiveFavorite(item.key)
}, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
class: "favorite-item-icon"
}, "★", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteTitle(item)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoritePreview(item)), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("time", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFavoriteTime(item.timestamp)), 1)], 10, _hoisted_4);
}), 128)), !(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_6, " 暂无收藏消息 ")) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)])]);
};
}
});
/***/ }),
/***/ 6415:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7566);
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1414);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(446);
const _hoisted_1 = {
class: "favorite-panel"
};
const _hoisted_2 = {
class: "chat-header"
};
const _hoisted_3 = {
class: "favorite-detail"
};
const _hoisted_4 = {
class: "favorite-detail-body"
};
const _hoisted_5 = {
key: 0,
class: "recall-mark"
};
const _hoisted_6 = ["href"];
const _hoisted_7 = ["src", "alt"];
const _hoisted_8 = ["href"];
const _hoisted_9 = {
class: "message-file-main"
};
const _hoisted_10 = {
key: 3
};
const _hoisted_11 = {
class: "favorite-detail-actions"
};
const _hoisted_12 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_13 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_14 = {
key: 1,
class: "empty-chat"
};
/* harmony default export */ __webpack_exports__.A = ({
__name: 'FavoritePanel',
setup(__props) {
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_5__/* .useConversationStore */ .w)();
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_6__/* .useNavigationStore */ .l)();
const favorite = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => conversations.activeFavorite);
const notice = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
const error = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
function clearFeedback() {
notice.value = '';
error.value = '';
}
function favoriteTitle(item) {
if (item.conversationTitle) {
return item.conversationTitle;
}
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
return conversation?.title || item.conversationId || '未知会话';
}
function favoriteText(item) {
return item.text || '';
}
function isImageFavorite(item) {
return item?.type === 'image' && item?.attachment?.url;
}
function isFileFavorite(item) {
return item?.type === 'file' && item?.attachment?.url;
}
function favoriteCopyText(item) {
if (!item) {
return '';
}
if (item.text) {
return item.text;
}
if (item.recalled) {
return item.recallStatus || '已撤回';
}
if (isImageFavorite(item)) {
return item.attachment.url;
}
if (isFileFavorite(item)) {
return `${item.attachment.name || '文件'} ${item.attachment.url}`.trim();
}
return item.preview || '';
}
function formatFileSize(size) {
const bytes = Number(size || 0);
if (bytes >= 1024 * 1024) {
return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;
}
if (bytes >= 1024) {
return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;
}
return bytes > 0 ? `${bytes} B` : '';
}
function formatFavoriteTime(timestamp) {
const value = Number(timestamp || 0);
if (!value) {
return '';
}
return new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false
}).format(value);
}
async function copyFavorite() {
clearFeedback();
const text = favoriteCopyText(favorite.value || {}).trim();
if (!text) {
error.value = '没有可复制的文字内容';
return;
}
try {
await writeClipboard(text);
notice.value = '已复制';
} catch (copyError) {
error.value = '复制失败';
}
}
async function writeClipboard(text) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const element = document.createElement('textarea');
element.value = text;
element.setAttribute('readonly', 'readonly');
element.style.position = 'fixed';
element.style.left = '-9999px';
document.body.appendChild(element);
element.select();
document.execCommand('copy');
document.body.removeChild(element);
}
function openConversation() {
clearFeedback();
const item = favorite.value;
if (!item?.conversationId) {
error.value = '缺少原会话信息';
return;
}
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
if (!conversation) {
error.value = '原会话暂未加载,请刷新会话后再试';
conversations.refreshRemoteConversations();
return;
}
navigation.showMessages();
conversations.setActiveConversation(item.conversationId);
window.setTimeout(() => {
conversations.focusMessage({
id: item.id || item.key,
messageUid: item.messageUid || item.key
});
}, 450);
}
function removeFavorite() {
clearFeedback();
const key = favorite.value?.key || '';
if (!key) {
return;
}
conversations.removeFavorite(key);
notice.value = '已取消收藏';
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("section", _hoisted_1, [favorite.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
key: 0
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h2", null, "收藏详情", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteTitle(favorite.value)), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["favorite-detail-message", {
recalled: favorite.value.recalled
}])
}, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
class: "favorite-detail-star"
}, "★", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_4, [favorite.value.recalled ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favorite.value.recallStatus || '已撤回'), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), isImageFavorite(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("a", {
key: 1,
class: "favorite-detail-image",
href: favorite.value.attachment.url,
target: "_blank",
rel: "noreferrer"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", {
src: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__/* .imageDisplayUrl */ .B)(favorite.value.attachment.url),
alt: favorite.value.attachment.name || '图片'
}, null, 8, _hoisted_7)], 8, _hoisted_6)) : isFileFavorite(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("a", {
key: 2,
class: "message-file favorite-detail-file",
href: favorite.value.attachment.url,
target: "_blank",
rel: "noreferrer",
download: ""
}, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
class: "message-file-icon"
}, "▤", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favorite.value.attachment.name || '文件'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFileSize(favorite.value.attachment.size)), 1)])], 8, _hoisted_8)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), favoriteText(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteText(favorite.value)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("time", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFavoriteTime(favorite.value.timestamp)), 1)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_11, [notice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(notice.value), 1)) : error.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_13, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(error.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: copyFavorite
}, "复制"), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: openConversation
}, "打开原会话"), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "danger-inline-action",
onClick: removeFavorite
}, "取消收藏")])])], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_14, _cache[3] || (_cache[3] = [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, "暂无收藏消息", -1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "右键消息气泡选择“收藏”后,会显示在这里", -1)])))]);
};
}
});
/***/ }),
/***/ 5684:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5187);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(9045);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(446);
const _hoisted_1 = {
class: "conversation-list"
};
const _hoisted_2 = {
class: "list-header"
};
const _hoisted_3 = {
class: "header-actions"
};
const _hoisted_4 = {
class: "search-box"
};
const _hoisted_5 = {
class: "sidebar-scroll"
};
const _hoisted_6 = ["onClick"];
const _hoisted_7 = ["src"];
const _hoisted_8 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_9 = {
class: "conversation-copy"
};
const _hoisted_10 = {
key: 0,
class: "empty-list"
};
const _hoisted_11 = {
key: 0,
class: "form-error"
};
const _hoisted_12 = {
key: 1,
class: "form-info"
};
const _hoisted_13 = {
class: "modal-actions"
};
const _hoisted_14 = ["disabled"];
/* harmony default export */ __webpack_exports__.A = ({
__name: 'ContactList',
setup(__props) {
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_7__/* .useContactStore */ .p)();
const keyword = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)('');
const addingContact = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)(false);
const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)('');
const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .computed */ .EW)(() => {
const value = keyword.value.toLowerCase();
if (!value) {
return contacts.contacts;
}
return contacts.contacts.filter(item => {
return item.title.toLowerCase().includes(value) || item.subtitle.toLowerCase().includes(value) || item.uid.toLowerCase().includes(value);
});
});
function openAddContact() {
contacts.actionError = '';
contacts.actionInfo = '';
addKeyword.value = '';
addingContact.value = true;
}
function closeAddContact() {
addingContact.value = false;
}
async function submitAddContact() {
const added = await contacts.addContact(addKeyword.value);
if (added) {
window.setTimeout(() => {
addingContact.value = false;
}, 500);
}
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("h2", null, "联系人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).contacts.length) + " 位好友", 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
class: "icon-button",
title: "添加联系人",
onClick: openAddContact
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
class: "icon-button",
title: "刷新",
onClick: _cache[0] || (_cache[0] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).refreshContacts({
force: true
}))
}, "↻")])]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => keyword.value = $event),
placeholder: "搜索联系人"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_3__/* .vModelText */ .Jo, keyword.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_4__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .renderList */ .pI)(filteredContacts.value, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("button", {
key: item.id,
class: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .normalizeClass */ .C4)(["conversation-item", {
active: item.id === (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).activeId
}]),
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).setActiveContact(item.id)
}, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_8__/* .imageDisplayUrl */ .B)(item.portrait),
alt: ""
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.title), 1), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.subtitle), 1)])], 10, _hoisted_6);
}), 128)), !filteredContacts.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("div", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '正在加载' : '暂无联系人'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '请稍候' : '好友同步完成后会显示在这里'), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true)]), addingContact.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withModifiers */ .D$)(closeAddContact, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("form", {
class: "modal-panel",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withModifiers */ .D$)(submitAddContact, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("header", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, "添加联系人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeAddContact
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("label", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", null, "用户ID / 手机号 / 用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => addKeyword.value = $event),
autocomplete: "off",
placeholder: "请输入要添加的联系人"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_3__/* .vModelText */ .Jo, addKeyword.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("p", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionError), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionInfo ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("p", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionInfo), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: closeAddContact
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
class: "primary-inline-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading || !addKeyword.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '添加中...' : '添加'), 9, _hoisted_14)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true)]);
};
}
});
/***/ }),
/***/ 4621:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(531);
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3579);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5367);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2731);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(5187);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(7566);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(9045);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(446);
const _hoisted_1 = {
class: "conversation-list"
};
const _hoisted_2 = {
class: "list-header"
};
const _hoisted_3 = {
class: "header-actions action-menu-anchor"
};
const _hoisted_4 = {
class: "search-box"
};
const _hoisted_5 = {
class: "sidebar-scroll"
};
const _hoisted_6 = ["onClick", "onContextmenu"];
const _hoisted_7 = ["src"];
const _hoisted_8 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_9 = {
class: "conversation-copy"
};
const _hoisted_10 = {
key: 0,
class: "conversation-pin",
"aria-label": "已置顶"
};
const _hoisted_11 = ["aria-label"];
const _hoisted_12 = {
key: 1,
class: "empty-list"
};
const _hoisted_13 = {
key: 2,
class: "empty-list"
};
const _hoisted_14 = {
key: 0
};
const _hoisted_15 = {
key: 2
};
const _hoisted_16 = {
key: 5,
class: "form-error"
};
const _hoisted_17 = {
key: 6,
class: "form-info"
};
const _hoisted_18 = {
class: "modal-actions"
};
const _hoisted_19 = ["disabled"];
/* harmony default export */ __webpack_exports__.A = ({
__name: 'ConversationList',
setup(__props) {
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_20__/* .useConversationStore */ .w)();
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_21__/* .useContactStore */ .p)();
const actionMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)(false);
const activeAction = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const actionBusy = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)(false);
const searchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const groupName = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const groupAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const groupWelcomeText = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const joinGroupKey = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const broadcastText = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const channelName = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const channelAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const contactKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
const selectedContactIds = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)([]);
const conversationMenu = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)({
item: null,
x: 0,
y: 0
});
const actionTitles = {
addContact: '添加联系人',
createGroup: '新建群组',
joinGroup: '加入群组',
broadcast: '群发助手',
createChannel: '创建频道/公告群'
};
const submitLabels = {
addContact: '添加',
createGroup: '创建',
joinGroup: '加入',
broadcast: '发送',
createChannel: '创建'
};
const actionTitle = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => actionTitles[activeAction.value] || '');
const submitLabel = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => submitLabels[activeAction.value] || '确定');
const modalError = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => contacts.actionError || conversations.actionError);
const modalInfo = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => contacts.actionInfo || conversations.actionNotice);
const normalizedSearchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => searchKeyword.value.trim().toLowerCase());
const contactsByUid = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
const map = new Map();
contacts.contacts.forEach(contact => {
const uid = String(contact.uid || contact.id || '');
if (uid) {
map.set(uid, contact);
}
});
return map;
});
const filteredConversationItems = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
const keyword = normalizedSearchKeyword.value;
if (!keyword) {
return conversations.conversations.map(item => conversationResult(item));
}
const conversationResults = conversations.conversations.filter(item => matchesConversation(item, keyword, contactForConversation(item))).map(item => conversationResult(item));
const conversationTargets = new Set(conversations.conversations.filter(item => item.type === 'single').map(item => conversationTarget(item)));
const contactResults = contacts.contacts.filter(item => !conversationTargets.has(String(item.uid || item.id || ''))).filter(item => matchesContact(item, keyword)).map(item => contactResult(item));
return [...conversationResults, ...contactResults];
});
const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
const keyword = contactKeyword.value.toLowerCase();
if (!keyword) {
return contacts.contacts;
}
return contacts.contacts.filter(item => {
return String(item.title || '').toLowerCase().includes(keyword) || String(item.subtitle || '').toLowerCase().includes(keyword) || String(item.uid || '').toLowerCase().includes(keyword);
});
});
const submitDisabled = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
if (activeAction.value === 'addContact') {
return !addKeyword.value;
}
if (activeAction.value === 'createGroup') {
return !groupName.value || !selectedContactIds.value.length;
}
if (activeAction.value === 'joinGroup') {
return !joinGroupKey.value;
}
if (activeAction.value === 'broadcast') {
return !broadcastText.value || !selectedContactIds.value.length;
}
if (activeAction.value === 'createChannel') {
return !channelName.value;
}
return true;
});
(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .onMounted */ .sV)(() => {
contacts.refreshContacts().catch(() => {});
});
function isPinned(item) {
return item?.resultKind === 'conversation' && Number(item.pinnedAt || item.top || 0) > 0;
}
function openConversationMenu(event, item) {
if (item.resultKind !== 'conversation') return;
conversationMenu.value = {
item,
x: Math.min(event.clientX, window.innerWidth - 140),
y: Math.min(event.clientY, window.innerHeight - 60)
};
}
function closeConversationMenu() {
conversationMenu.value = {
item: null,
x: 0,
y: 0
};
}
function togglePinned() {
const item = conversationMenu.value.item;
if (item) conversations.togglePinnedConversation(item.id);
closeConversationMenu();
}
const ContactPicker = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .defineComponent */ .pM)({
name: 'ContactPicker',
props: {
contacts: {
type: Array,
default: () => []
},
selectedIds: {
type: Array,
default: () => []
},
keyword: {
type: String,
default: ''
},
emptyText: {
type: String,
default: '暂无联系人'
}
},
emits: ['toggle', 'update:keyword'],
setup(props, {
emit
}) {
return () => (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
class: 'contact-picker'
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('input', {
value: props.keyword,
placeholder: '搜索联系人',
onInput: event => emit('update:keyword', event.target.value)
}), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
class: 'contact-picker-list'
}, props.contacts.length ? props.contacts.map(contact => (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('button', {
key: contact.uid,
type: 'button',
class: ['contact-picker-row', {
selected: props.selectedIds.includes(contact.uid)
}],
onClick: () => emit('toggle', contact.uid)
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
class: 'contact-check'
}, props.selectedIds.includes(contact.uid) ? '✓' : ''), contact.portrait ? (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('img', {
class: 'conversation-avatar image-avatar',
src: contact.portrait,
alt: ''
}) : (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
class: 'conversation-avatar'
}, contact.avatarText), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
class: 'contact-picker-copy'
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('strong', contact.title), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('small', contact.subtitle)])])) : [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
class: 'contact-picker-empty'
}, props.emptyText)])]);
}
});
function searchableValues(...values) {
return values.flatMap(value => {
if (Array.isArray(value)) {
return value;
}
if (value && typeof value === 'object') {
return Object.values(value);
}
return [value];
}).map(value => String(value || '').toLowerCase()).filter(Boolean);
}
function matchesKeyword(values, keyword) {
const compactKeyword = keyword.replace(/[^\p{L}\p{N}]+/gu, '');
return searchableValues(values).some(value => {
if (value.includes(keyword)) {
return true;
}
if (!compactKeyword) {
return false;
}
return value.replace(/[^\p{L}\p{N}]+/gu, '').includes(compactKeyword);
});
}
function conversationTarget(item) {
if (item.type !== 'single') {
return String(item.target || item.raw?.target || item.id || '');
}
return String(item.target || item.raw?.target || item.id.replace(/^single-/, '') || '');
}
function contactForConversation(item) {
const target = conversationTarget(item);
return target ? contactsByUid.value.get(target) || null : null;
}
function matchesConversation(item, keyword, contact = null) {
return matchesKeyword([item.title, item.subtitle, item.target, item.id, item.type, item.raw?.target, item.raw?.groupId, item.raw?.group_id, item.raw?.owner_uid, item.raw?.name, item.raw?.displayName, item.raw?.mobile, item.raw?.friendAlias, item.raw?.alias, contact?.title, contact?.subtitle, contact?.uid, contact?.id, contact?.alias, contact?.address, contact?.rawUser, contact?.rawFriend], keyword);
}
function matchesContact(item, keyword) {
return matchesKeyword([item.title, item.subtitle, item.uid, item.id, item.alias, item.address, item.rawUser, item.rawFriend], keyword);
}
function conversationResult(item) {
return {
...item,
resultKind: 'conversation',
resultKey: `conversation-${item.id}`
};
}
function contactResult(contact) {
return {
id: contact.id,
resultKind: 'contact',
resultKey: `contact-${contact.uid || contact.id}`,
contact,
title: contact.title,
subtitle: contact.subtitle,
portrait: contact.portrait,
avatarText: contact.avatarText,
unread: 0
};
}
function isListItemActive(item) {
if (item.resultKind === 'conversation') {
return item.id === conversations.activeId;
}
return `single-${item.contact?.uid || item.id}` === conversations.activeId;
}
function selectListItem(item) {
if (item.resultKind === 'contact') {
contacts.openChat(item.contact);
return;
}
conversations.setActiveConversation(item.id);
}
function clearStoreMessages() {
contacts.actionError = '';
contacts.actionInfo = '';
conversations.actionError = '';
conversations.actionNotice = '';
}
function resetActionFields() {
addKeyword.value = '';
groupName.value = '';
groupAnnouncement.value = '';
groupWelcomeText.value = '';
joinGroupKey.value = '';
broadcastText.value = '';
channelName.value = '';
channelAnnouncement.value = '';
contactKeyword.value = '';
selectedContactIds.value = [];
clearStoreMessages();
}
function toggleActionMenu() {
actionMenuOpen.value = !actionMenuOpen.value;
}
function closeActionMenu() {
actionMenuOpen.value = false;
}
function openAction(action) {
resetActionFields();
activeAction.value = action;
actionMenuOpen.value = false;
if (['createGroup', 'broadcast', 'createChannel'].includes(action)) {
contacts.refreshContacts({
force: true
});
}
}
function closeActionModal() {
activeAction.value = '';
actionBusy.value = false;
resetActionFields();
}
function toggleContact(contactId) {
const selected = new Set(selectedContactIds.value);
if (selected.has(contactId)) {
selected.delete(contactId);
} else {
selected.add(contactId);
}
selectedContactIds.value = Array.from(selected);
}
async function submitAction() {
if (submitDisabled.value || actionBusy.value) {
return;
}
actionBusy.value = true;
clearStoreMessages();
try {
let ok = false;
if (activeAction.value === 'addContact') {
ok = await contacts.addContact(addKeyword.value);
if (ok && contacts.activeContact) {
contacts.openChat(contacts.activeContact);
}
} else if (activeAction.value === 'createGroup') {
ok = await conversations.createGroup({
name: groupName.value,
announcement: groupAnnouncement.value,
welcomeText: groupWelcomeText.value,
memberIds: selectedContactIds.value
});
} else if (activeAction.value === 'joinGroup') {
ok = await conversations.joinGroup(joinGroupKey.value);
} else if (activeAction.value === 'broadcast') {
ok = await conversations.broadcastMessage(selectedContactIds.value, broadcastText.value);
} else if (activeAction.value === 'createChannel') {
ok = await conversations.createGroup({
name: channelName.value,
memberIds: selectedContactIds.value,
announcement: channelAnnouncement.value,
channel: true
});
}
if (ok) {
window.setTimeout(closeActionModal, 450);
}
} finally {
actionBusy.value = false;
}
}
document.addEventListener('click', closeActionMenu);
document.addEventListener('click', closeConversationMenu);
(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .onBeforeUnmount */ .xo)(() => {
document.removeEventListener('click', closeActionMenu);
document.removeEventListener('click', closeConversationMenu);
});
function formatUnread(value) {
const count = Number(value || 0);
return count > 99 ? '99+' : String(count);
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", null, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("h2", null, "消息", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).totalUnread) + " 条未读", 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
class: "icon-button",
title: "新建会话",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(toggleActionMenu, ["stop"])
}, "+"), actionMenuOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "quick-action-menu",
onClick: _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[0] || (_cache[0] = $event => openAction('addContact'))
}, "添加联系人"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[1] || (_cache[1] = $event => openAction('createGroup'))
}, "新建群组"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[2] || (_cache[2] = $event => openAction('joinGroup'))
}, "加入群组"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[3] || (_cache[3] = $event => openAction('broadcast'))
}, "群发助手"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: _cache[4] || (_cache[4] = $event => openAction('createChannel'))
}, "创建频道/公告群")])) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[6] || (_cache[6] = $event => searchKeyword.value = $event),
placeholder: "搜索会话、联系人"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, searchKeyword.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .renderList */ .pI)(filteredConversationItems.value, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("button", {
key: item.resultKey,
class: (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .normalizeClass */ .C4)(["conversation-item", {
active: isListItemActive(item),
pinned: isPinned(item)
}]),
onClick: $event => selectListItem(item),
onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)($event => openConversationMenu($event, item), ["prevent"])
}, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "conversation-avatar image-avatar",
src: (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(item.portrait),
alt: ""
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, [isPinned(item) ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", _hoisted_10, "⌖")) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createTextVNode */ .eW)((0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.title), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.subtitle), 1)]), Number(item.unread || 0) > 0 ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", {
key: 2,
class: "unread-badge",
"aria-label": `${item.unread} 条未读消息`
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(formatUnread(item.unread)), 9, _hoisted_11)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)], 42, _hoisted_6);
}), 128)), conversationMenu.value.item ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "conversation-context-menu",
style: (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .normalizeStyle */ .Tr)({
left: `${conversationMenu.value.x}px`,
top: `${conversationMenu.value.y}px`
}),
onClick: _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
onClick: togglePinned
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(isPinned(conversationMenu.value.item) ? '取消置顶' : '置顶会话'), 1)], 4)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), !filteredConversationItems.value.length && searchKeyword.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", _hoisted_12, _cache[20] || (_cache[20] = [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, "没有匹配结果", -1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "换个关键词再试试", -1)]))) : !(0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).conversations.length && !(0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).usingDemoData ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", _hoisted_13, _cache[21] || (_cache[21] = [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, "暂无会话", -1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "收到或发起消息后会出现在这里", -1)]))) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)]), activeAction.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(closeActionModal, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("form", {
class: "modal-panel conversation-action-panel",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(submitAction, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("header", null, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(actionTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeActionModal
}, "×")]), activeAction.value === 'addContact' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("label", _hoisted_14, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "用户ID / 手机号 / 用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[8] || (_cache[8] = $event => addKeyword.value = $event),
autocomplete: "off",
placeholder: "请输入要添加的联系人"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, addKeyword.value, void 0, {
trim: true
}]])])) : activeAction.value === 'createGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群组名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => groupName.value = $event),
maxlength: "64",
autocomplete: "off",
placeholder: "请输入群组名称"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupName.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => groupAnnouncement.value = $event),
maxlength: "1000",
rows: "3",
placeholder: "可选"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupAnnouncement.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "欢迎词", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[11] || (_cache[11] = $event => groupWelcomeText.value = $event),
maxlength: "1000",
rows: "3",
placeholder: "群组创建后自动发送"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupWelcomeText.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
contacts: filteredContacts.value,
"selected-ids": selectedContactIds.value,
keyword: contactKeyword.value,
"empty-text": "暂无可选联系人",
"onUpdate:keyword": _cache[12] || (_cache[12] = $event => contactKeyword.value = $event),
onToggle: toggleContact
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : activeAction.value === 'joinGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("label", _hoisted_15, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群组ID / 群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[13] || (_cache[13] = $event => joinGroupKey.value = $event),
autocomplete: "off",
placeholder: "请输入群组ID或群名称"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, joinGroupKey.value, void 0, {
trim: true
}]])])) : activeAction.value === 'broadcast' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
key: 3
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群发内容", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[14] || (_cache[14] = $event => broadcastText.value = $event),
maxlength: "2000",
rows: "4",
placeholder: "输入要群发的文字"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, broadcastText.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
contacts: filteredContacts.value,
"selected-ids": selectedContactIds.value,
keyword: contactKeyword.value,
"empty-text": "暂无可选联系人",
"onUpdate:keyword": _cache[15] || (_cache[15] = $event => contactKeyword.value = $event),
onToggle: toggleContact
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : activeAction.value === 'createChannel' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
key: 4
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "频道/公告群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[16] || (_cache[16] = $event => channelName.value = $event),
maxlength: "64",
autocomplete: "off",
placeholder: "请输入名称"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, channelName.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "公告说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
"onUpdate:modelValue": _cache[17] || (_cache[17] = $event => channelAnnouncement.value = $event),
maxlength: "1000",
rows: "3",
placeholder: "可选"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, channelAnnouncement.value, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
contacts: filteredContacts.value,
"selected-ids": selectedContactIds.value,
keyword: contactKeyword.value,
"empty-text": "暂无可选联系人",
"onUpdate:keyword": _cache[18] || (_cache[18] = $event => contactKeyword.value = $event),
onToggle: toggleContact
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), modalError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(modalError.value), 1)) : modalInfo.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(modalInfo.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: closeActionModal
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
class: "primary-inline-action",
disabled: actionBusy.value || submitDisabled.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(actionBusy.value ? '处理中...' : submitLabel.value), 9, _hoisted_19)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)]);
};
}
});
/***/ }),
/***/ 7420:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5130);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6768);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5187);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(926);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(446);
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(1414);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(9045);
const _hoisted_1 = {
class: "navigation-rail"
};
const _hoisted_2 = ["src"];
const _hoisted_3 = {
key: 1
};
const _hoisted_4 = {
class: "settings-panel"
};
const _hoisted_5 = {
class: "settings-layout"
};
const _hoisted_6 = {
class: "settings-menu",
"aria-label": "设置菜单"
};
const _hoisted_7 = ["onClick"];
const _hoisted_8 = {
key: 0
};
const _hoisted_9 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_10 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_11 = ["disabled"];
const _hoisted_12 = {
key: 1,
class: "settings-placeholder"
};
const _hoisted_13 = {
class: "profile-avatar-field"
};
const _hoisted_14 = ["src"];
const _hoisted_15 = {
key: 1
};
const _hoisted_16 = ["value"];
const _hoisted_17 = {
class: "modal-actions"
};
const _hoisted_18 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_19 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_20 = ["disabled"];
const _hoisted_21 = {
class: "avatar-preview-dialog"
};
const _hoisted_22 = {
class: "avatar-preview-actions"
};
const _hoisted_23 = ["src"];
const _hoisted_24 = {
class: "modal-panel avatar-cropper-panel"
};
const _hoisted_25 = {
class: "avatar-cropper-header-actions"
};
const _hoisted_26 = ["disabled"];
const _hoisted_27 = {
class: "avatar-cropper-layout"
};
const _hoisted_28 = {
key: 0,
class: "avatar-cropper-placeholder"
};
const _hoisted_29 = {
class: "avatar-cropper-controls"
};
const _hoisted_30 = {
class: "avatar-cropper-tools"
};
const _hoisted_31 = {
class: "avatar-cropper-preview"
};
const _hoisted_32 = {
key: 0,
class: "inline-save-status error"
};
const _hoisted_33 = ["disabled"];
const _hoisted_34 = ["disabled"];
const CROP_OUTPUT_SIZE = 512;
/* harmony default export */ __webpack_exports__.A = ({
__name: 'NavigationRail',
setup(__props) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_6__/* .useSessionStore */ .B)();
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_8__/* .useNavigationStore */ .l)();
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_9__/* .useContactStore */ .p)();
const settingsItems = [{
key: 'notifications',
label: '通知设置'
}, {
key: 'password',
label: '更改密码'
}, {
key: 'wallet',
label: '钱包管理'
}, {
key: 'language',
label: '切换语言'
}, {
key: 'feedback',
label: '问题反馈'
}];
const initials = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => (session.displayName || session.userId || 'Q').slice(0, 1).toUpperCase());
const settingsOpen = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const settingsSection = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('password');
const passwordSaving = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const settingsNotice = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const settingsError = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const profileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const profileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const profileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const profileError = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const profileFile = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
const profilePreview = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const portraitInput = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
const cropperCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
const cropperPreviewCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)({
displayName: ''
});
const passwordDraft = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
oldPassword: '',
newPassword: '',
confirmPassword: ''
});
const currentAvatarUrl = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => profilePreview.value || session.portrait || '');
const activeSettingsItem = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => settingsItems.find(item => item.key === settingsSection.value) || settingsItems[0]);
const avatarPreviewViewer = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
open: false,
url: '',
scale: 1,
offsetX: 0,
offsetY: 0,
dragging: false,
dragStartX: 0,
dragStartY: 0,
dragOffsetX: 0,
dragOffsetY: 0
});
const avatarCropper = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
open: false,
loaded: false,
busy: false,
error: '',
objectUrl: '',
fileName: 'avatar.jpg',
image: null,
baseScale: 1,
scale: 1,
rotation: 0,
offsetX: 0,
offsetY: 0,
dragging: false,
dragStartX: 0,
dragStartY: 0,
dragOffsetX: 0,
dragOffsetY: 0
});
const avatarPreviewStyle = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => ({
transform: `translate3d(${avatarPreviewViewer.offsetX}px, ${avatarPreviewViewer.offsetY}px, 0) scale(${avatarPreviewViewer.scale})`
}));
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onMounted */ .sV)(() => {
session.refreshProfile();
window.addEventListener('resize', drawAvatarCropper);
});
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onBeforeUnmount */ .xo)(() => {
revokeProfilePreview();
closeAvatarCropper();
window.removeEventListener('resize', drawAvatarCropper);
});
function showContacts() {
navigation.showContacts();
contacts.refreshContacts();
}
function clearProfileFeedback() {
profileNotice.value = '';
profileError.value = '';
}
function clearSettingsFeedback() {
settingsNotice.value = '';
settingsError.value = '';
}
function resetPasswordDraft() {
passwordDraft.oldPassword = '';
passwordDraft.newPassword = '';
passwordDraft.confirmPassword = '';
}
function openSettings() {
settingsOpen.value = true;
settingsSection.value = 'password';
clearSettingsFeedback();
}
function closeSettings() {
if (passwordSaving.value) {
return;
}
settingsOpen.value = false;
clearSettingsFeedback();
resetPasswordDraft();
}
function selectSettingsSection(section) {
settingsSection.value = section;
clearSettingsFeedback();
}
function revokeProfilePreview() {
if (profilePreview.value) {
URL.revokeObjectURL(profilePreview.value);
profilePreview.value = '';
}
}
function revokeCropperObjectUrl() {
if (avatarCropper.objectUrl) {
URL.revokeObjectURL(avatarCropper.objectUrl);
avatarCropper.objectUrl = '';
}
}
async function openProfileEditor() {
profileOpen.value = true;
clearProfileFeedback();
profileDraft.value.displayName = session.displayName || session.userId || '';
const profile = await session.refreshProfile();
if (profileOpen.value && profile) {
profileDraft.value.displayName = session.displayName || session.userId || '';
}
}
function closeProfileEditor() {
profileOpen.value = false;
profileFile.value = null;
clearProfileFeedback();
revokeProfilePreview();
closeAvatarPreview();
closeAvatarCropper();
}
function selectPortrait(event) {
const file = event.target.files?.[0] || null;
event.target.value = '';
clearProfileFeedback();
if (file) {
openAvatarCropper(file);
}
}
function choosePortraitFile() {
portraitInput.value?.click();
}
function openAvatarPreview() {
if (!currentAvatarUrl.value) {
return;
}
avatarPreviewViewer.open = true;
avatarPreviewViewer.url = currentAvatarUrl.value;
resetAvatarPreview();
}
function closeAvatarPreview() {
avatarPreviewViewer.open = false;
avatarPreviewViewer.dragging = false;
}
function resetAvatarPreview() {
avatarPreviewViewer.scale = 1;
avatarPreviewViewer.offsetX = 0;
avatarPreviewViewer.offsetY = 0;
}
function zoomAvatarPreview(factor) {
avatarPreviewViewer.scale = Math.max(0.5, Math.min(6, Number((avatarPreviewViewer.scale * factor).toFixed(2))));
if (avatarPreviewViewer.scale <= 1) {
avatarPreviewViewer.offsetX = 0;
avatarPreviewViewer.offsetY = 0;
}
}
function handleAvatarPreviewWheel(event) {
zoomAvatarPreview(event.deltaY < 0 ? 1.12 : 1 / 1.12);
}
function startAvatarPreviewDrag(event) {
if (avatarPreviewViewer.scale <= 1) {
return;
}
avatarPreviewViewer.dragging = true;
avatarPreviewViewer.dragStartX = event.clientX;
avatarPreviewViewer.dragStartY = event.clientY;
avatarPreviewViewer.dragOffsetX = avatarPreviewViewer.offsetX;
avatarPreviewViewer.dragOffsetY = avatarPreviewViewer.offsetY;
event.currentTarget.setPointerCapture?.(event.pointerId);
}
function moveAvatarPreviewDrag(event) {
if (!avatarPreviewViewer.dragging) {
return;
}
avatarPreviewViewer.offsetX = avatarPreviewViewer.dragOffsetX + event.clientX - avatarPreviewViewer.dragStartX;
avatarPreviewViewer.offsetY = avatarPreviewViewer.dragOffsetY + event.clientY - avatarPreviewViewer.dragStartY;
}
function stopAvatarPreviewDrag() {
avatarPreviewViewer.dragging = false;
}
function dropPortrait(event) {
const file = Array.from(event.dataTransfer?.files || []).find(item => item.type.startsWith('image/'));
if (file) {
clearProfileFeedback();
openAvatarCropper(file);
}
}
function cropperStageSize() {
const canvas = cropperCanvas.value;
const rect = canvas?.getBoundingClientRect();
const width = Math.max(280, Math.round(rect?.width || 360));
const height = Math.max(280, Math.round(rect?.height || 360));
return {
width,
height
};
}
function cropperBoxSize() {
const {
width,
height
} = cropperStageSize();
return Math.round(Math.min(width, height) * 0.74);
}
function rotatedImageSize() {
const image = avatarCropper.image;
if (!image) {
return {
width: 1,
height: 1
};
}
const quarterTurn = Math.abs(avatarCropper.rotation % 180) === 90;
return {
width: quarterTurn ? image.naturalHeight : image.naturalWidth,
height: quarterTurn ? image.naturalWidth : image.naturalHeight
};
}
function clampCropperOffset() {
const cropSize = cropperBoxSize();
const rotated = rotatedImageSize();
const scaledWidth = rotated.width * avatarCropper.scale;
const scaledHeight = rotated.height * avatarCropper.scale;
const maxX = Math.max(0, (scaledWidth - cropSize) / 2);
const maxY = Math.max(0, (scaledHeight - cropSize) / 2);
avatarCropper.offsetX = Math.max(-maxX, Math.min(maxX, avatarCropper.offsetX));
avatarCropper.offsetY = Math.max(-maxY, Math.min(maxY, avatarCropper.offsetY));
}
function updateCropperBaseScale() {
const cropSize = cropperBoxSize();
const rotated = rotatedImageSize();
avatarCropper.baseScale = Math.max(cropSize / rotated.width, cropSize / rotated.height);
avatarCropper.scale = Math.max(avatarCropper.baseScale, avatarCropper.scale || avatarCropper.baseScale);
}
function drawCanvasImage(canvas, width, height, outputScale = 1, cropOnly = false) {
const image = avatarCropper.image;
if (!canvas || !image) {
return;
}
const dpr = cropOnly ? 1 : window.devicePixelRatio || 1;
canvas.width = Math.round(width * dpr);
canvas.height = Math.round(height * dpr);
const context = canvas.getContext('2d');
context.setTransform(dpr, 0, 0, dpr, 0, 0);
context.clearRect(0, 0, width, height);
context.fillStyle = '#eef4f7';
context.fillRect(0, 0, width, height);
context.save();
context.translate(width / 2 + avatarCropper.offsetX * outputScale, height / 2 + avatarCropper.offsetY * outputScale);
context.rotate(avatarCropper.rotation * Math.PI / 180);
context.scale(avatarCropper.scale * outputScale, avatarCropper.scale * outputScale);
context.drawImage(image, -image.naturalWidth / 2, -image.naturalHeight / 2);
context.restore();
if (!cropOnly) {
const cropSize = cropperBoxSize();
context.save();
context.fillStyle = 'rgba(10, 18, 30, 0.42)';
context.beginPath();
context.rect(0, 0, width, height);
context.rect((width - cropSize) / 2, (height - cropSize) / 2, cropSize, cropSize);
context.fill('evenodd');
context.restore();
}
}
function drawAvatarCropper() {
if (!avatarCropper.open || !avatarCropper.loaded) {
return;
}
clampCropperOffset();
const {
width,
height
} = cropperStageSize();
drawCanvasImage(cropperCanvas.value, width, height);
const previewCanvas = cropperPreviewCanvas.value;
if (previewCanvas) {
drawCanvasImage(previewCanvas, 108, 108, 108 / cropperBoxSize(), true);
}
}
function resetCropperTransform() {
if (!avatarCropper.image) {
return;
}
avatarCropper.rotation = 0;
avatarCropper.offsetX = 0;
avatarCropper.offsetY = 0;
updateCropperBaseScale();
avatarCropper.scale = avatarCropper.baseScale;
drawAvatarCropper();
}
function openAvatarCropper(file) {
if (!file.type.startsWith('image/')) {
profileError.value = '请选择图片文件';
return;
}
if (file.size > 8 * 1024 * 1024) {
profileError.value = '头像图片不能超过8MB';
return;
}
closeAvatarCropper();
avatarCropper.open = true;
avatarCropper.loaded = false;
avatarCropper.error = '';
avatarCropper.fileName = file.name || 'avatar.jpg';
avatarCropper.objectUrl = URL.createObjectURL(file);
const image = new Image();
image.onload = () => {
avatarCropper.image = image;
avatarCropper.loaded = true;
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .nextTick */ .dY)(resetCropperTransform);
};
image.onerror = () => {
avatarCropper.error = '图片加载失败';
avatarCropper.loaded = false;
};
image.src = avatarCropper.objectUrl;
}
function closeAvatarCropper() {
avatarCropper.open = false;
avatarCropper.loaded = false;
avatarCropper.busy = false;
avatarCropper.error = '';
avatarCropper.image = null;
avatarCropper.dragging = false;
revokeCropperObjectUrl();
}
function zoomCropper(factor) {
if (!avatarCropper.loaded) {
return;
}
updateCropperBaseScale();
avatarCropper.scale = Math.max(avatarCropper.baseScale, Math.min(avatarCropper.baseScale * 6, avatarCropper.scale * factor));
drawAvatarCropper();
}
function rotateCropper(degrees) {
if (!avatarCropper.loaded) {
return;
}
avatarCropper.rotation = (avatarCropper.rotation + degrees + 360) % 360;
updateCropperBaseScale();
clampCropperOffset();
drawAvatarCropper();
}
function handleCropperWheel(event) {
zoomCropper(event.deltaY < 0 ? 1.08 : 1 / 1.08);
}
function startCropperDrag(event) {
if (!avatarCropper.loaded) {
return;
}
avatarCropper.dragging = true;
avatarCropper.dragStartX = event.clientX;
avatarCropper.dragStartY = event.clientY;
avatarCropper.dragOffsetX = avatarCropper.offsetX;
avatarCropper.dragOffsetY = avatarCropper.offsetY;
event.currentTarget.setPointerCapture?.(event.pointerId);
}
function moveCropperDrag(event) {
if (!avatarCropper.dragging) {
return;
}
avatarCropper.offsetX = avatarCropper.dragOffsetX + event.clientX - avatarCropper.dragStartX;
avatarCropper.offsetY = avatarCropper.dragOffsetY + event.clientY - avatarCropper.dragStartY;
drawAvatarCropper();
}
function stopCropperDrag() {
avatarCropper.dragging = false;
}
function canvasToBlob(canvas, type = 'image/jpeg', quality = 0.9) {
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
if (blob) {
resolve(blob);
} else {
reject(new Error('头像裁切失败'));
}
}, type, quality);
});
}
async function confirmAvatarCrop() {
if (!avatarCropper.loaded || avatarCropper.busy) {
return;
}
avatarCropper.busy = true;
avatarCropper.error = '';
try {
const outputCanvas = document.createElement('canvas');
drawCanvasImage(outputCanvas, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE / cropperBoxSize(), true);
const blob = await canvasToBlob(outputCanvas);
const fileName = avatarCropper.fileName.replace(/\.[^.]+$/, '') || 'avatar';
const croppedFile = new File([blob], `${fileName}.jpg`, {
type: 'image/jpeg'
});
profileFile.value = croppedFile;
revokeProfilePreview();
profilePreview.value = URL.createObjectURL(croppedFile);
closeAvatarCropper();
} catch (error) {
avatarCropper.error = error.message || '头像裁切失败';
} finally {
avatarCropper.busy = false;
}
}
async function saveProfile() {
if (profileSaving.value || !profileDraft.value.displayName) {
return;
}
clearProfileFeedback();
profileSaving.value = true;
try {
await session.saveProfile({
displayName: profileDraft.value.displayName,
portraitFile: profileFile.value
});
profileFile.value = null;
revokeProfilePreview();
profileNotice.value = '资料已保存';
contacts.refreshContacts({
force: true
});
} catch (error) {
profileError.value = error.message || '资料保存失败';
} finally {
profileSaving.value = false;
}
}
async function savePassword() {
if (passwordSaving.value) {
return;
}
clearSettingsFeedback();
const oldPassword = passwordDraft.oldPassword;
const newPassword = passwordDraft.newPassword;
const confirmPassword = passwordDraft.confirmPassword;
if (!oldPassword || !newPassword || !confirmPassword) {
settingsError.value = '请填写完整密码';
return;
}
if (newPassword !== confirmPassword) {
settingsError.value = '两次输入的新密码不一致';
return;
}
if (oldPassword === newPassword) {
settingsError.value = '新密码不能和当前密码相同';
return;
}
passwordSaving.value = true;
try {
await session.changePassword({
oldPassword,
newPassword
});
resetPasswordDraft();
settingsNotice.value = '密码已更新';
} catch (error) {
settingsError.value = error.message || '密码修改失败';
} finally {
passwordSaving.value = false;
}
}
function logout() {
closeSettings();
contacts.clearContacts();
session.logout();
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, null, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "rail-avatar rail-avatar-button",
title: "编辑个人资料",
onClick: openProfileEditor
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
key: 0,
src: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__/* .imageDisplayUrl */ .B)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).portrait),
alt: ""
}, null, 8, _hoisted_2)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(initials.value), 1))]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'messages'
}]),
title: "消息",
onClick: _cache[0] || (_cache[0] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showMessages && (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showMessages(...args))
}, "💬", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'contacts'
}]),
title: "联系人",
onClick: showContacts
}, "👥", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'favorites'
}]),
title: "收藏",
onClick: _cache[1] || (_cache[1] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showFavorites && (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showFavorites(...args))
}, "☆", 2), _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: "rail-spacer"
}, null, -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "rail-button",
title: "设置",
"aria-label": "设置",
onClick: openSettings
}, _cache[13] || (_cache[13] = [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("svg", {
viewBox: "0 0 24 24",
"aria-hidden": "true"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("path", {
d: "M12 8.2a3.8 3.8 0 1 1 0 7.6 3.8 3.8 0 0 1 0-7.6Z"
}), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("path", {
d: "M19.4 13.6a7.8 7.8 0 0 0 .1-1.6l1.7-1.3-1.7-3-2 .8a8 8 0 0 0-1.4-.8L15.8 5h-3.5l-.3 2.1a8 8 0 0 0-1.5.8l-1.9-.8-1.8 3 1.7 1.3a7.8 7.8 0 0 0 0 1.6l-1.7 1.3 1.8 3 1.9-.8c.5.4 1 .7 1.5.8l.3 2.1h3.5l.3-2.1c.5-.2 1-.5 1.4-.8l2 .8 1.7-3-1.8-1.3Z"
})], -1)])), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "rail-button rail-logout-button",
title: "退出登录",
"aria-label": "退出登录",
onClick: logout
}, _cache[14] || (_cache[14] = [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createStaticVNode */ .Fv)("<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4.5 20.5V3.5h9.2a1.8 1.8 0 0 1 1.8 1.8v13.4a1.8 1.8 0 0 1-1.8 1.8H4.5Z\"></path><path d=\"M9 12h9.5\"></path><path d=\"m15.5 8.8 3.2 3.2-3.2 3.2\"></path><path d=\"M7.8 20.5V5.8l6.5-2.3\"></path></svg>", 1)]))]), settingsOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "modal-backdrop settings-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeSettings, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "设置", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeSettings
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("nav", _hoisted_6, [((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .renderList */ .pI)(settingsItems, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
key: item.key,
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
active: settingsSection.value === item.key
}),
onClick: $event => selectSettingsSection(item.key)
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(item.label), 1), item.key !== 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("small", _hoisted_8, "稍后开放")) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_7);
}), 64))]), settingsSection.value === 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("form", {
key: 0,
class: "settings-password-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(savePassword, ["prevent"])
}, [_cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("h3", null, "更改密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "当前密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => passwordDraft.oldPassword = $event),
type: "password",
autocomplete: "current-password"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.oldPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => passwordDraft.newPassword = $event),
type: "password",
autocomplete: "new-password"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.newPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "确认新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => passwordDraft.confirmPassword = $event),
type: "password",
autocomplete: "new-password"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("footer", null, [settingsNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(settingsNotice.value), 1)) : settingsError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(settingsError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "submit",
class: "primary-inline-action",
disabled: passwordSaving.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(passwordSaving.value ? '保存中...' : '保存密码'), 9, _hoisted_11)])], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("section", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(activeSettingsItem.value?.label || '设置'), 1), _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("p", null, "该功能稍后开放。", -1))]))])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), profileOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
key: 1,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeProfileEditor, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("form", {
class: "modal-panel profile-edit-panel",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(saveProfile, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "个人资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeProfileEditor
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["profile-avatar-preview", {
clickable: currentAvatarUrl.value
}]),
title: "预览头像",
onClick: openAvatarPreview
}, [currentAvatarUrl.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
key: 0,
src: currentAvatarUrl.value,
alt: ""
}, null, 8, _hoisted_14)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(initials.value), 1))], 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action profile-avatar-change-button",
onClick: choosePortraitFile
}, "更换头像"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
ref_key: "portraitInput",
ref: portraitInput,
type: "file",
accept: "image/*",
onChange: selectPortrait
}, null, 544)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => profileDraft.value.displayName = $event),
maxlength: "64",
autocomplete: "off"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, profileDraft.value.displayName, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
value: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).userId,
readonly: ""
}, null, 8, _hoisted_16)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: closeProfileEditor
}, "取消"), profileNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_18, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileNotice.value), 1)) : profileError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "primary-inline-action",
disabled: profileSaving.value || !profileDraft.value.displayName
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileSaving.value ? '保存中...' : '保存'), 9, _hoisted_20)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), avatarPreviewViewer.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
key: 2,
class: "modal-backdrop avatar-preview-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeAvatarPreview, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "头像预览", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_22, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "缩小",
onClick: _cache[6] || (_cache[6] = $event => zoomAvatarPreview(1 / 1.16))
}, "−"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "放大",
onClick: _cache[7] || (_cache[7] = $event => zoomAvatarPreview(1.16))
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "还原",
onClick: resetAvatarPreview
}, "1:1"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeAvatarPreview
}, "×")])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["avatar-preview-stage", {
dragging: avatarPreviewViewer.dragging
}]),
onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(handleAvatarPreviewWheel, ["prevent"]),
onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(startAvatarPreviewDrag, ["prevent"]),
onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(moveAvatarPreviewDrag, ["prevent"]),
onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopAvatarPreviewDrag, ["prevent"]),
onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopAvatarPreviewDrag, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("img", {
src: avatarPreviewViewer.url,
alt: "头像预览",
style: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeStyle */ .Tr)(avatarPreviewStyle.value),
draggable: "false"
}, null, 12, _hoisted_23)], 34)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), avatarCropper.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
key: 3,
class: "modal-backdrop avatar-cropper-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeAvatarCropper, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "头像预裁切", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: avatarCropper.busy,
onClick: choosePortraitFile
}, "上传", 8, _hoisted_26), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeAvatarCropper
}, "×")])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_27, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["avatar-cropper-stage", {
dragging: avatarCropper.dragging
}]),
onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(handleCropperWheel, ["prevent"]),
onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(startCropperDrag, ["prevent"]),
onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(moveCropperDrag, ["prevent"]),
onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopCropperDrag, ["prevent"]),
onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopCropperDrag, ["prevent"]),
onDragover: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(() => {}, ["prevent"])),
onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(dropPortrait, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("canvas", {
ref_key: "cropperCanvas",
ref: cropperCanvas
}, null, 512), _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: "avatar-cropper-mask",
"aria-hidden": "true"
}, null, -1)), _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: "avatar-cropper-box",
"aria-hidden": "true"
}, null, -1)), !avatarCropper.loaded ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", _hoisted_28, "图片加载中")) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 34), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("aside", _hoisted_29, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_30, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "左旋90度",
onClick: _cache[9] || (_cache[9] = $event => rotateCropper(-90))
}, "↶90°"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "右旋90度",
onClick: _cache[10] || (_cache[10] = $event => rotateCropper(90))
}, "↷90°"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "放大",
onClick: _cache[11] || (_cache[11] = $event => zoomCropper(1.12))
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "缩小",
onClick: _cache[12] || (_cache[12] = $event => zoomCropper(1 / 1.12))
}, "−"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "重置",
onClick: resetCropperTransform
}, "重置")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_31, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("canvas", {
ref_key: "cropperPreviewCanvas",
ref: cropperPreviewCanvas
}, null, 512)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("footer", null, [avatarCropper.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_32, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(avatarCropper.error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
disabled: avatarCropper.busy,
onClick: closeAvatarCropper
}, "取消", 8, _hoisted_33), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: avatarCropper.busy || !avatarCropper.loaded,
onClick: confirmAvatarCrop
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(avatarCropper.busy ? '处理中...' : '确认裁切'), 9, _hoisted_34)])])])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 64);
};
}
});
/***/ }),
/***/ 2169:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
const currentHost = window.location.hostname || '127.0.0.1';
const runtimeConfig = window.JC_WEB_IM_CONFIG || {};
const appServerOrigin = `${window.location.protocol}//${currentHost}:8888`;
const qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`;
const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;
const appConfig = {
appName: 'Web IM',
adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin,
appServer: runtimeConfig.appServer || undefined || appServerOrigin,
qrAppServer: runtimeConfig.qrAppServer || undefined || qrAppServerOrigin,
platformConfigApi: runtimeConfig.platformConfigApi || undefined || ( false ? 0 : '/api/platform_config.php'),
registerConfigApi: runtimeConfig.registerConfigApi || undefined || `${adminServerOrigin}/api/register-config`,
registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || undefined || `${adminServerOrigin}/api/register-phone-exists`,
contactsApi: runtimeConfig.contactsApi || undefined || ( false ? 0 : '/api/contacts.php'),
updateAliasApi: runtimeConfig.updateAliasApi || undefined || ( false ? 0 : '/api/update_alias.php'),
addContactApi: runtimeConfig.addContactApi || undefined || ( false ? 0 : '/api/add_contact.php'),
conversationActionsApi: runtimeConfig.conversationActionsApi || undefined || ( false ? 0 : '/api/conversation_actions.php'),
sendMessageApi: runtimeConfig.sendMessageApi || undefined || ( false ? 0 : '/api/send_message.php'),
messageActionApi: runtimeConfig.messageActionApi || undefined || ( false ? 0 : '/api/message_action.php'),
messageDetailApi: runtimeConfig.messageDetailApi || undefined || ( false ? 0 : '/api/message_detail.php'),
messagesApi: runtimeConfig.messagesApi || undefined || ( false ? 0 : '/api/messages.php'),
profileApi: runtimeConfig.profileApi || undefined || ( false ? 0 : '/api/profile.php'),
changePasswordApi: runtimeConfig.changePasswordApi || undefined || `${appServerOrigin}/auth/changePassword`,
logoutApi: runtimeConfig.logoutApi || undefined || `${appServerOrigin}/auth/logout`,
imServerHost: runtimeConfig.imServerHost || undefined || currentHost,
imRoutePort: Number(runtimeConfig.imRoutePort || undefined || 18000),
useWss: runtimeConfig.useWss ?? undefined === 'true',
wsPath: runtimeConfig.wsPath || undefined || '/ws',
wsUrl: runtimeConfig.wsUrl || undefined || '',
sdkMode: runtimeConfig.sdkMode || undefined || 'http',
syncIntervalMs: Number(runtimeConfig.syncIntervalMs || undefined || 300),
sseEnabled: runtimeConfig.sseEnabled ?? undefined === 'true',
sseTicketApi: runtimeConfig.sseTicketApi || undefined || '/api/sse_ticket.php',
sseUrl: runtimeConfig.sseUrl || undefined || '/ws-events',
platform: 5,
clientIdStorageKey: 'qmt-web-im-client-id',
authTokenStoragePrefix: 'qmt-web-im-auth-token-'
};
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "U", 0, /* binding */ appConfig
/* harmony export */ ]);
/***/ }),
/***/ 1406:
/***/ (function(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) {
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
/* harmony import */ var _App_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7067);
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createApp */ .Ef)(_App_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A).use((0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .createPinia */ .Ey)()).mount('#app');
/***/ }),
/***/ 9311:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Ln: function() { return /* binding */ appServerPost; },
/* harmony export */ Pd: function() { return /* binding */ getStoredAppAuth; },
/* harmony export */ eG: function() { return /* binding */ persistAppAuth; },
/* harmony export */ u$: function() { return /* binding */ clearStoredAppAuth; }
/* harmony export */ });
/* unused harmony exports appServerRequest, appServerGet */
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9577);
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6632);
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4226);
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9486);
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(456);
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4979);
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2387);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2169);
const AES_KEY = 'xczx2026!@#secKe';
const ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check'];
const AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1';
const AUTH_ERROR_CODE = 13;
const REFRESH_ERROR_CODE = 20045;
let importedCryptoKeyPromise = null;
let refreshPromise = null;
function storageScope() {
return _config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer || '';
}
function readAuthStore() {
try {
return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}');
} catch (error) {
return {};
}
}
function writeAuthStore(store) {
localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store));
}
function normalizeAuthBundle(bundle = {}) {
const accessToken = String(bundle.accessToken || '').trim();
const refreshToken = String(bundle.refreshToken || '').trim();
if (!accessToken || !refreshToken) {
return null;
}
return {
accessToken,
refreshToken,
tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer',
accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0,
accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0,
refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0,
refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0
};
}
function getStoredAppAuth() {
const store = readAuthStore();
return normalizeAuthBundle(store[storageScope()]);
}
function persistAppAuth(bundle) {
const normalized = normalizeAuthBundle(bundle);
const store = readAuthStore();
if (!normalized) {
delete store[storageScope()];
writeAuthStore(store);
return null;
}
store[storageScope()] = normalized;
writeAuthStore(store);
return normalized;
}
function clearStoredAppAuth() {
persistAppAuth(null);
}
function hasFormData(value) {
return typeof FormData !== 'undefined' && value instanceof FormData;
}
function absoluteUrl(url) {
return new URL(url, window.location.origin);
}
function shouldEncrypt(url) {
const pathname = absoluteUrl(url).pathname;
return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path));
}
function shouldAttachAuth(config) {
return !config.skipAuth;
}
function textEncoder() {
return new TextEncoder();
}
function textDecoder() {
return new TextDecoder();
}
function bytesToBase64(bytes) {
let binary = '';
bytes.forEach(byte => {
binary += String.fromCharCode(byte);
});
return btoa(binary);
}
function base64ToBytes(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let index = 0; index < binary.length; index += 1) {
bytes[index] = binary.charCodeAt(index);
}
return bytes;
}
async function getCryptoKey() {
if (!importedCryptoKeyPromise) {
importedCryptoKeyPromise = window.crypto.subtle.importKey('raw', textEncoder().encode(AES_KEY), {
name: 'AES-CBC'
}, false, ['encrypt', 'decrypt']);
}
return importedCryptoKeyPromise;
}
async function encryptPayload(plainText) {
const iv = window.crypto.getRandomValues(new Uint8Array(16));
const key = await getCryptoKey();
const encrypted = await window.crypto.subtle.encrypt({
name: 'AES-CBC',
iv
}, key, textEncoder().encode(plainText));
return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`;
}
async function decryptPayload(cipherText) {
const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2);
if (!ivBase64 || !encryptedBase64) {
throw new Error('Encrypted payload format is invalid');
}
const key = await getCryptoKey();
const decrypted = await window.crypto.subtle.decrypt({
name: 'AES-CBC',
iv: base64ToBytes(ivBase64)
}, key, base64ToBytes(encryptedBase64));
return textDecoder().decode(decrypted);
}
function normalizeBusinessResponse(payload) {
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
return payload;
}
return {
code: 0,
message: 'success',
data: payload
};
}
async function decodeResponsePayload(response) {
const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true';
if (encrypted && typeof response.data === 'string') {
const plainText = await decryptPayload(response.data);
response.data = normalizeBusinessResponse(JSON.parse(plainText));
return response;
}
response.data = normalizeBusinessResponse(response.data);
return response;
}
const client = axios__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.create({
withCredentials: false
});
client.interceptors.request.use(async config => {
const nextConfig = {
...config
};
const url = absoluteUrl(nextConfig.url || '').toString();
if (shouldAttachAuth(nextConfig)) {
const auth = getStoredAppAuth();
if (auth?.accessToken) {
nextConfig.headers = {
...(nextConfig.headers || {}),
Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}`
};
}
}
if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) {
const plainBody = JSON.stringify(nextConfig.data ?? {});
nextConfig.data = await encryptPayload(plainBody);
nextConfig.headers = {
...(nextConfig.headers || {}),
'Content-Type': 'text/plain;charset=UTF-8',
'X-Timestamp': `${Math.floor(Date.now() / 1000)}`
};
}
return nextConfig;
});
client.interceptors.response.use(async response => decodeResponsePayload(response));
async function refreshAccessToken() {
if (refreshPromise) {
return refreshPromise;
}
const auth = getStoredAppAuth();
if (!auth?.refreshToken) {
clearStoredAppAuth();
throw new Error('登录状态已失效,请重新登录');
}
refreshPromise = client.post(`${_config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer}/auth/refreshToken`, {
refreshToken: auth.refreshToken
}, {
skipAuth: true
}).then(response => {
const payload = response.data || {};
if (Number(payload.code) !== 0 || !payload.data) {
if (Number(payload.code) === REFRESH_ERROR_CODE) {
clearStoredAppAuth();
}
throw new Error(payload.message || '刷新登录状态失败');
}
persistAppAuth(payload.data);
return payload.data;
}).finally(() => {
refreshPromise = null;
});
return refreshPromise;
}
async function request(config) {
const response = await client.request(config);
const payload = response.data || {};
if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) {
await refreshAccessToken();
return request({
...config,
_retriedAfterRefresh: true
});
}
return response;
}
async function appServerRequest(config) {
return request(config);
}
async function appServerGet(url, config = {}) {
return request({
...config,
method: 'get',
url
});
}
async function appServerPost(url, data = {}, config = {}) {
return request({
...config,
method: 'post',
url,
data
});
}
/***/ }),
/***/ 4355:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ u: function() { return /* binding */ DocumentedHttpImClient; }
/* harmony export */ });
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2169);
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5099);
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2387);
/* harmony import */ var _appServerClient__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9311);
function inferAccountType(account) {
return String(account || '').includes('@') ? 2 : 1;
}
function unwrapData(response) {
return response.data?.data ?? response.data?.result ?? null;
}
function unwrapMessage(response, fallback) {
return response.data?.message || response.data?.msg || fallback;
}
class DocumentedHttpImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_2__/* .HttpImClient */ .Y {
unsupported(feature) {
throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`);
}
async loginWithPassword(account, password, type = inferAccountType(account)) {
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/login_pwd`, {
type,
number: account,
password,
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
clientId: this.getClientId()
}, {
skipAuth: true
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '登录失败'));
}
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
return unwrapData(response);
}
async requestAuthCode(email) {
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/sendEmailCode`, {
email
}, {
skipAuth: true
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '验证码发送失败'));
}
return unwrapData(response);
}
async loginWithCode(account, code) {
void account;
void code;
throw new Error('接口文档未提供验证码登录接口,请使用密码登录');
}
async register({
type,
number,
code = '',
password,
invitationCode = ''
}) {
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/register`, {
type,
number,
code,
password,
clientId: this.getClientId(),
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
invitationCode
}, {
skipAuth: true
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '注册失败'));
}
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
return unwrapData(response);
}
async createPcSession(userId = '') {
const response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/pc_session`, {
flag: 1,
device_name: 'Web IM',
userId,
clientId: this.getClientId(),
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '二维码登录会话创建失败'));
}
return unwrapData(response) || {};
}
async loginWithPcSession(token) {
const url = `${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/session_login/${encodeURIComponent(token)}`;
let response;
try {
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(url, null, {
withCredentials: false
});
} catch (postError) {
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.get(url, {
withCredentials: false
});
}
this.persistAppToken(url, response);
const payload = response.data || {};
const result = payload.result ?? payload.data ?? null;
if (Number(payload.code) === 0 && result) {
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(result);
}
if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) {
return {
...payload,
data: result
};
}
throw new Error(payload.message || '扫码登录失败');
}
async changePassword({
oldPassword,
newPassword
}) {
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.changePasswordApi, {
oldPassword,
newPassword
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '密码修改失败'));
}
return true;
}
async resetPasswordWithCode({
mobile,
resetCode,
newPassword
}) {
void mobile;
void resetCode;
void newPassword;
throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程');
}
async logout() {
const auth = (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .getStoredAppAuth */ .Pd)();
if (!auth?.refreshToken) {
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
return true;
}
try {
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.logoutApi, {
refreshToken: auth.refreshToken
});
if (response.data?.code !== 0) {
throw new Error(unwrapMessage(response, '退出登录失败'));
}
} finally {
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
}
return true;
}
async fetchRemoteConversations() {
return [];
}
async fetchRemoteMessages() {
return [];
}
async getServerContactList() {
return [];
}
async getProfile() {
return null;
}
async sendTextMessage() {
this.unsupported('发送消息');
}
async sendAttachmentMessage() {
this.unsupported('发送附件消息');
}
async addContact() {
this.unsupported('添加联系人');
}
async updateContactAlias() {
this.unsupported('联系人备注');
}
async createGroup() {
this.unsupported('创建群组');
}
async joinGroup() {
this.unsupported('加入群组');
}
async broadcastMessage() {
this.unsupported('群发消息');
}
async getGroupDetail() {
this.unsupported('群详情');
}
async getGroupMembers() {
this.unsupported('群成员');
}
async updateGroupAlias() {
this.unsupported('群备注');
}
async leaveGroup() {
this.unsupported('退出群组');
}
async dismissGroup() {
this.unsupported('解散群组');
}
async transferGroup() {
this.unsupported('转让群组');
}
async setGroupAdmins() {
this.unsupported('设置群管理员');
}
async updateGroupProfile() {
this.unsupported('更新群资料');
}
async kickGroupMembers() {
this.unsupported('移除群成员');
}
async updateGroupMuteSetting() {
this.unsupported('群禁言设置');
}
async updateProfile() {
this.unsupported('更新个人资料');
}
async recallMessage() {
this.unsupported('撤回消息');
}
async editMessage() {
this.unsupported('编辑消息');
}
async getMessageDetail() {
this.unsupported('消息详情');
}
}
/***/ }),
/***/ 5099:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Y: function() { return /* binding */ HttpImClient; }
/* harmony export */ });
/* unused harmony export imClient */
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3579);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5367);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2731);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__);
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(2387);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2169);
/* harmony import */ var _services_appServerClient__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(9311);
const LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2';
const LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1';
const LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1';
function scopedStorageKey(baseKey, userId = '') {
const scope = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer || ''}:${userId || 'anonymous'}`;
return `${baseKey}:${encodeURIComponent(scope)}`;
}
function randomId() {
if (window.crypto && window.crypto.randomUUID) {
return window.crypto.randomUUID().replaceAll('-', '');
}
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
}
function readLocalMessages(userId) {
try {
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}');
} catch (error) {
return {};
}
}
function readMessageSet(storageKey, userId) {
try {
return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}');
} catch (error) {
return {};
}
}
function writeMessageSet(storageKey, messagesByConversation, userId) {
localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation));
}
function messageKeys(message) {
return [message?.id, message?.messageUid].filter(Boolean).map(value => String(value));
}
function hasStoredMessage(storageKey, conversationId, message, userId) {
const stored = readMessageSet(storageKey, userId);
const ids = new Set(stored[conversationId] || []);
return messageKeys(message).some(id => ids.has(id));
}
function storeMessageKeys(storageKey, conversationId, messages, userId) {
const stored = readMessageSet(storageKey, userId);
const ids = new Set(stored[conversationId] || []);
messages.forEach(message => {
messageKeys(message).forEach(id => ids.add(id));
});
stored[conversationId] = Array.from(ids);
writeMessageSet(storageKey, stored, userId);
}
function withRecalledState(message) {
return {
...message,
status: 'recalled',
deliveryStatus: '',
recalled: true,
recallStatus: '已撤回'
};
}
function applyLocalMessageState(conversationId, messages, userId) {
return messages.filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)).map(message => {
const isRecalled = Boolean(message.recalled) || message.status === 'recalled' || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId);
if (!isRecalled) {
return message;
}
return withRecalledState(message);
});
}
function writeLocalMessages(messagesByConversation, userId) {
localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation));
}
function saveLocalMessage(message, userId) {
const messagesByConversation = readLocalMessages(userId);
messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || [];
const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id);
if (index >= 0) {
messagesByConversation[message.conversationId].splice(index, 1, message);
} else {
messagesByConversation[message.conversationId].push(message);
}
writeLocalMessages(messagesByConversation, userId);
}
function mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) {
const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId);
const localByKey = new Map();
visibleLocalMessages.forEach(message => {
messageKeys(message).forEach(key => {
if (!localByKey.has(key)) {
localByKey.set(key, message);
}
});
});
const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => {
if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) {
return remoteMessage;
}
const localMessage = messageKeys(remoteMessage).map(key => localByKey.get(key)).find(message => message?.text && message.text !== '你撤回了一条消息');
return localMessage ? {
...remoteMessage,
text: localMessage.text
} : remoteMessage;
});
const remoteKeys = new Set();
visibleRemoteMessages.forEach(message => {
messageKeys(message).forEach(key => remoteKeys.add(key));
});
const now = Date.now();
function hasRemoteMatch(localMessage) {
if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) {
return true;
}
return visibleRemoteMessages.some(remoteMessage => {
return remoteMessage.direction === localMessage.direction && remoteMessage.text === localMessage.text && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000;
});
}
const pendingLocalMessages = visibleLocalMessages.filter(message => {
if (message.status === 'recalled' || message.recalled) {
return message.direction === 'out' && !hasRemoteMatch(message);
}
if (message.direction !== 'out') {
return false;
}
if (message.status === 'sent' && message.messageUid) {
return !hasRemoteMatch(message);
}
if (message.status === 'sent') {
return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000;
}
return message.status === 'sending' || message.status === 'failed';
});
return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => {
return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0);
});
}
function getTitle(value, fallback) {
return value || fallback || '';
}
function getUniqueEquipment(mobile, fallback) {
const allowedDevices = {
'18301902119': '67072d37062c4f31b1165073552933ba',
'18301902116': '1777479418113eeea8e236edce',
'18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',
'18301902117': 'd117f480faa64145b6162107b1b49617'
};
return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback;
}
function canUseLocalLoginFallback(response) {
const message = response.data?.message || '';
return false && 0;
}
class HttpImClient {
constructor() {
this.listeners = new Map();
this.connected = false;
this.currentUser = null;
}
getClientId() {
let clientId = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey);
if (!clientId) {
clientId = randomId();
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
}
return clientId;
}
restoreClientId(clientId) {
if (clientId) {
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
}
}
getSdkVersion() {
return 'HTTP';
}
async ensureSdk() {
return true;
}
async loginWithPassword(mobile, password) {
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login_pwd`;
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
mobile,
password,
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
clientId: this.getClientId()
}, {
withCredentials: false
});
this.persistAppToken(url, response);
if (response.data?.code !== 0) {
if (canUseLocalLoginFallback(response)) {
return {
userId: mobile,
token: `local-device-pending-${Date.now()}`,
displayName: mobile,
localOnly: true
};
}
throw new Error(response.data?.message || '登录失败');
}
return response.data.result;
}
async requestAuthCode(mobile) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/send_code`, {
mobile
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '验证码发送失败');
}
return response.data.result;
}
async loginWithCode(mobile, code) {
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login`;
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
mobile,
code,
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
clientId: this.getClientId()
}, {
withCredentials: false
});
this.persistAppToken(url, response);
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '登录失败');
}
return response.data.result;
}
async createPcSession(userId = '') {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/pc_session`, {
flag: 1,
device_name: 'Web IM',
userId,
clientId: this.getClientId(),
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '二维码登录会话创建失败');
}
return response.data.result || {};
}
async loginWithPcSession(token) {
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/session_login/${encodeURIComponent(token)}`;
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, null, {
withCredentials: false
});
this.persistAppToken(url, response);
const data = response.data || {};
if ([0, 8, 9, 10, 18].includes(Number(data.code))) {
return data;
}
throw new Error(data.message || '扫码登录失败');
}
async registerWithPhone(mobile, code) {
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/register`;
const deviceId = getUniqueEquipment(mobile, this.getClientId());
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
mobile,
code,
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
clientId: deviceId,
uniqueEquipment: deviceId
}, {
withCredentials: false
});
this.persistAppToken(url, response);
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '注册失败');
}
return response.data.result;
} catch (error) {
const status = error.response?.status;
if (status === 404 || status === 405) {
return this.loginWithCode(mobile, code);
}
throw error;
}
}
connect(userId, token) {
this.currentUser = {
userId,
token
};
this.connected = true;
this.emit('connectionStatusChanged', {
connected: true,
statusText: '已连接'
});
this.refreshConversationList();
}
disconnect() {
this.connected = false;
this.currentUser = null;
this.emit('connectionStatusChanged', {
connected: false,
statusText: '未连接'
});
}
getConversationList() {
return [];
}
refreshConversationList() {
const conversations = this.getConversationList();
if (conversations.length) {
this.emit('conversationsChanged', conversations);
}
if (this.currentUser?.userId) {
this.fetchRemoteConversations().then(remoteConversations => {
this.emit('conversationsChanged', remoteConversations);
}).catch(() => {});
}
return conversations;
}
async fetchRemoteConversations(limit = 50) {
if (!this.currentUser?.userId) {
return [];
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
userId: this.currentUser.userId,
limit
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '会话同步失败');
}
return (response.data?.result?.conversations || []).map(conversation => ({
...conversation,
updatedAt: Number(conversation.updatedAt || Date.now()),
avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(),
raw: conversation.raw || {
type: 'single',
target: conversation.target,
line: 0
}
}));
}
getMessages(conversation) {
if (!conversation?.id) {
return [];
}
const userId = this.currentUser?.userId || '';
return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId);
}
async fetchRemoteMessages(conversation, limit = 50, options = {}) {
if (!conversation?.id || !this.currentUser?.userId) {
return [];
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
userId: this.currentUser.userId,
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
limit,
conversationType: conversation.type || conversation.raw?.type || 0,
markRead: Boolean(options.markRead),
includeConversations: Boolean(options.includeConversations)
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '消息同步失败');
}
const messages = (response.data?.result?.messages || []).map(message => ({
...message,
displayTimestamp: message.displayTimestamp || message.timestamp,
conversationId: conversation.id
}));
messages.pinnedMessageUid = String(response.data?.result?.pinnedMessageUid || '');
if (options.includeConversations && Array.isArray(response.data?.result?.conversations)) {
const remoteConversations = response.data.result.conversations.map(remoteConversation => ({
...remoteConversation,
updatedAt: Number(remoteConversation.updatedAt || Date.now()),
avatarText: remoteConversation.avatarText || String(remoteConversation.title || remoteConversation.target || '?').slice(0, 1).toUpperCase(),
raw: remoteConversation.raw || {
type: 'single',
target: remoteConversation.target,
line: 0
}
}));
this.emit('conversationsChanged', remoteConversations);
}
const userId = this.currentUser?.userId || '';
const messagesByConversation = readLocalMessages(userId);
messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);
messagesByConversation[conversation.id].pinnedMessageUid = messages.pinnedMessageUid;
writeLocalMessages(messagesByConversation, userId);
return messagesByConversation[conversation.id];
}
async setPinnedMessage(conversation, messageUid = '') {
const action = messageUid ? 'pin' : 'unpin';
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
action,
userId: this.currentUser?.userId || '',
messageUid: messageUid || '1',
target: conversation.target || conversation.raw?.target || '',
conversationType: ['group', 'channel'].includes(conversation.type) ? 'group' : 'single'
}, {
withCredentials: false
});
if (response.data?.code !== 0) throw new Error(response.data?.message || '置顶失败');
}
hideMessages(conversation, messages) {
const items = Array.isArray(messages) ? messages : [messages];
if (!conversation?.id || !items.length) {
return;
}
const userId = this.currentUser?.userId || '';
storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
const messagesByConversation = readLocalMessages(userId);
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
writeLocalMessages(messagesByConversation, userId);
}
markMessagesRecalled(conversation, messages) {
const items = Array.isArray(messages) ? messages : [messages];
if (!conversation?.id || !items.length) {
return;
}
const userId = this.currentUser?.userId || '';
storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
const messagesByConversation = readLocalMessages(userId);
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
writeLocalMessages(messagesByConversation, userId);
}
async recallMessage(conversation, message) {
const messageUid = String(message?.messageUid || message?.id || '').trim();
if (!/^\d+$/.test(messageUid)) {
throw new Error('缺少可撤回的消息ID');
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
action: 'recall',
userId: this.currentUser?.userId || message.from || '',
messageUid
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '撤回失败');
}
this.markMessagesRecalled(conversation, [message]);
return response.data.result;
}
async editMessage(conversation, message, text) {
const messageUid = String(message?.messageUid || message?.id || '').trim();
if (!/^\d+$/.test(messageUid)) {
throw new Error('缺少可编辑的消息ID');
}
const nextText = String(text || '').trim();
if (!nextText) {
throw new Error('编辑内容不能为空');
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
action: 'edit',
userId: this.currentUser?.userId || message.from || '',
messageUid,
text: nextText
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '编辑失败');
}
const result = response.data?.result?.message || {};
const editedMessage = {
...message,
text: result.text || nextText,
status: 'delivered',
deliveryStatus: 'delivered',
editedAt: Number(result.editedAt || Date.now()),
activityTimestamp: Number(result.editedAt || Date.now())
};
saveLocalMessage(editedMessage, this.currentUser?.userId || '');
this.emit('messageStatusChanged', editedMessage);
return editedMessage;
}
async getMessageDetail(conversation, message) {
const messageUid = String(message?.messageUid || message?.id || '').trim();
if (!messageUid) {
throw new Error('缺少消息ID');
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageDetailApi, {
userId: this.currentUser?.userId || '',
target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '',
conversationType: conversation?.type || conversation?.raw?.type || 'single',
messageUid
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '消息详情加载失败');
}
return response.data?.result?.detail || null;
}
async sendTextMessage(conversation, text, initialMessage = null) {
const senderRole = conversation?.role || conversation?.raw?.role || '';
const message = initialMessage || {
id: randomId(),
conversationId: conversation.id,
from: this.currentUser?.userId || 'me',
senderRole,
direction: 'out',
type: 'text',
text,
status: 'sending',
deliveryStatus: 'sending',
timestamp: Date.now()
};
saveLocalMessage(message, this.currentUser?.userId || '');
if (!initialMessage) {
this.emit('messageSent', message);
}
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, {
sender: this.currentUser?.userId || '',
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
conversationType: conversation.type || conversation.raw?.type || 0,
text
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '发送失败');
}
const sentMessage = {
...message,
status: 'sent',
deliveryStatus: 'sent',
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
senderRole: response.data?.result?.senderRole || message.senderRole || '',
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
timestamp: message.timestamp,
displayTimestamp: message.displayTimestamp || message.timestamp
};
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
this.emit('messageStatusChanged', sentMessage);
return sentMessage;
} catch (error) {
const failedMessage = {
...message,
status: 'failed',
deliveryStatus: '',
error: error.response?.data?.message || error.message || '发送失败'
};
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
this.emit('messageStatusChanged', failedMessage);
return failedMessage;
}
}
async sendAttachmentMessage(conversation, {
type,
file,
text = ''
}, initialMessage = null) {
const senderRole = conversation?.role || conversation?.raw?.role || '';
const message = initialMessage || {
id: randomId(),
conversationId: conversation.id,
from: this.currentUser?.userId || 'me',
senderRole,
direction: 'out',
type,
text,
attachment: {
type,
name: file?.name || (type === 'image' ? '图片' : '文件'),
mime: file?.type || '',
size: file?.size || 0,
url: type === 'image' && file ? URL.createObjectURL(file) : ''
},
status: 'sending',
deliveryStatus: 'sending',
timestamp: Date.now()
};
saveLocalMessage(message, this.currentUser?.userId || '');
if (!initialMessage) {
this.emit('messageSent', message);
}
try {
const formData = new FormData();
formData.append('sender', this.currentUser?.userId || '');
formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''));
formData.append('conversationType', conversation.type || conversation.raw?.type || 0);
formData.append('messageType', type);
formData.append('text', text || '');
formData.append('attachment', file);
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, formData, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '发送失败');
}
const sentMessage = {
...message,
status: 'sent',
deliveryStatus: 'sent',
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
senderRole: response.data?.result?.senderRole || message.senderRole || '',
attachment: response.data?.result?.attachment || message.attachment,
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
timestamp: message.timestamp,
displayTimestamp: message.displayTimestamp || message.timestamp
};
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
this.emit('messageStatusChanged', sentMessage);
return sentMessage;
} catch (error) {
const failedMessage = {
...message,
status: 'failed',
deliveryStatus: '',
error: error.response?.data?.message || error.message || '发送失败'
};
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
this.emit('messageStatusChanged', failedMessage);
return failedMessage;
}
}
getContactList() {
return [];
}
async getServerContactList(userId) {
if (!userId) {
return [];
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi, {
userId
}, {
withCredentials: false,
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi)
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '联系人加载失败');
}
return (response.data?.result?.contacts || []).map(item => {
return this.mapContact(item.uid, {
alias: item.alias
}, {
uid: item.uid,
displayName: item.displayName,
name: item.name,
mobile: item.mobile,
portrait: item.portrait,
address: item.address,
friendAlias: item.alias
});
}).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
}
async addContact(userId, keyword, reason = '') {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.addContactApi, {
userId,
keyword,
reason
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '添加联系人失败');
}
const item = response.data?.result?.contact;
if (!item?.uid) {
return null;
}
return this.mapContact(item.uid, {
alias: item.alias
}, {
uid: item.uid,
displayName: item.displayName,
name: item.name,
mobile: item.mobile,
portrait: item.portrait,
address: item.address,
friendAlias: item.alias
});
}
normalizeConversation(conversation) {
const title = getTitle(conversation?.title, conversation?.target || '');
return {
...conversation,
id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`,
target: conversation?.target || conversation?.raw?.target || '',
title,
subtitle: conversation?.subtitle || '',
unread: Number(conversation?.unread || 0),
portrait: conversation?.portrait || '',
avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(),
updatedAt: Number(conversation?.updatedAt || Date.now()),
raw: conversation?.raw || {
type: conversation?.type === 'single' ? 'single' : 'group',
target: conversation?.target || '',
line: 0
}
};
}
async createGroup(userId, {
name,
memberIds = [],
announcement = '',
welcomeText = '',
channel = false
}) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: channel ? 'create_channel' : 'create_group',
userId,
name,
memberIds,
announcement,
welcomeText
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败'));
}
return this.normalizeConversation(response.data?.result?.conversation || {});
}
async joinGroup(userId, groupKey) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'join_group',
userId,
groupKey
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '加入群组失败');
}
return this.normalizeConversation(response.data?.result?.conversation || {});
}
async broadcastMessage(userId, targetIds, text) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'broadcast',
userId,
targetIds,
text
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '群发失败');
}
return response.data?.result || {};
}
async getGroupDetail(userId, groupId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'group_detail',
userId,
groupId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '群资料加载失败');
}
return response.data?.result?.group || null;
}
async getGroupMembers(userId, groupId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'group_members',
userId,
groupId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '群员加载失败');
}
return response.data?.result?.members || [];
}
async updateGroupAlias(userId, groupId, alias) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'update_group_alias',
userId,
groupId,
alias
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '本群昵称保存失败');
}
return response.data?.result?.alias || '';
}
async leaveGroup(userId, groupId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'leave_group',
userId,
groupId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '退出群组失败');
}
return response.data?.result || {};
}
async dismissGroup(userId, groupId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'dismiss_group',
userId,
groupId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '解散群组失败');
}
return response.data?.result || {};
}
async transferGroup(userId, groupId, targetUserId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'transfer_group',
userId,
groupId,
targetUserId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '转让群组失败');
}
return response.data?.result || {};
}
async setGroupAdmins(userId, groupId, adminIds) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'set_group_admins',
userId,
groupId,
adminIds
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '管理员设置失败');
}
return response.data?.result || {};
}
async updateGroupProfile(userId, groupId, {
name,
announcement,
welcomeText
}) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'update_group_profile',
userId,
groupId,
name,
announcement,
welcomeText
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '群资料保存失败');
}
return response.data?.result || {};
}
async kickGroupMembers(userId, groupId, targetIds) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'kick_group_members',
userId,
groupId,
targetIds
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '踢人失败');
}
return response.data?.result || {};
}
async updateGroupMuteSetting(userId, groupId, setting) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
action: 'update_mute_setting',
userId,
groupId,
...setting
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '禁言设置保存失败');
}
return response.data?.result?.muteSetting || null;
}
async updateContactAlias(userId, targetId, alias) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi, {
userId,
targetId,
alias
}, {
withCredentials: false,
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi)
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '备注名修改失败');
}
return response.data?.result?.contact?.alias || '';
}
async getProfile(userId) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, {
action: 'get',
userId
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '用户资料加载失败');
}
return response.data?.result?.profile || null;
}
async updateProfile(userId, {
displayName,
portraitFile
}) {
const formData = new FormData();
formData.append('action', 'update');
formData.append('userId', userId);
formData.append('displayName', displayName);
if (portraitFile) {
formData.append('portraitFile', portraitFile);
}
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, formData, {
withCredentials: false,
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer)
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || '用户资料保存失败');
}
return response.data?.result?.profile || null;
}
async changePassword({
oldPassword,
newPassword
}) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi, {
oldPassword,
newPassword
}, {
withCredentials: false,
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi)
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || response.data?.msg || '密码修改失败');
}
return true;
}
async resetPasswordWithCode({
mobile,
resetCode,
newPassword
}) {
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.resetPasswordApi, {
mobile,
resetCode,
newPassword
}, {
withCredentials: false
});
if (response.data?.code !== 0) {
throw new Error(response.data?.message || response.data?.msg || '密码设置失败');
}
return true;
}
refreshContactList() {
const contacts = this.getContactList();
this.emit('contactsChanged', contacts);
return contacts;
}
createSingleConversation(userId, userInfo = null) {
const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId);
return {
id: `single-${userId}`,
type: 'single',
target: userId,
title,
subtitle: '',
unread: 0,
portrait: userInfo?.portrait || '',
avatarText: title.slice(0, 1).toUpperCase(),
updatedAt: Date.now(),
raw: {
type: 'single',
target: userId,
line: 0
}
};
}
mapContact(userId, friend, userInfo) {
const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId);
return {
id: userId,
uid: userId,
title,
subtitle: userInfo?.mobile || userInfo?.name || userId,
portrait: userInfo?.portrait || '',
address: userInfo?.address || '',
avatarText: title.slice(0, 1).toUpperCase(),
alias: friend?.alias || userInfo?.friendAlias || '',
rawFriend: friend,
rawUser: userInfo
};
}
on(eventName, handler) {
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, new Set());
}
this.listeners.get(eventName).add(handler);
return () => this.off(eventName, handler);
}
off(eventName, handler) {
this.listeners.get(eventName)?.delete(handler);
}
emit(eventName, payload) {
this.listeners.get(eventName)?.forEach(handler => handler(payload));
}
persistAppToken(url, response) {
const appToken = response.headers?.authtoken || response.headers?.authToken;
if (appToken) {
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + this.getUrlHost(url), appToken);
}
}
getAppAuthHeaders(url) {
const host = this.getUrlHost(url);
if (!host) {
return {};
}
const token = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + host);
return token ? {
authToken: token
} : {};
}
getUrlHost(url) {
try {
return new URL(url, window.location.origin).host;
} catch (error) {
return '';
}
}
}
const imClient = new HttpImClient();
/***/ }),
/***/ 5051:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* unused harmony export WildfireImClient */
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2169);
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5099);
/* harmony import */ var _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3909);
/* harmony import */ var _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4355);
class UnsupportedWildfireImClient {
constructor() {
throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK');
}
}
const imClient = _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'wildfire' ? new UnsupportedWildfireImClient() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'custom-ws' || _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'long' ? new _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__/* .LongConnectionImClient */ .E() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'legacy-http' ? new _httpImClient__WEBPACK_IMPORTED_MODULE_1__/* .HttpImClient */ .Y() : new _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__/* .DocumentedHttpImClient */ .u();
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "wD", 0, /* binding */ imClient
/* harmony export */ ]);
/***/ }),
/***/ 3909:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ E: function() { return /* binding */ LongConnectionImClient; }
/* harmony export */ });
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2169);
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5099);
const HEARTBEAT_INTERVAL_MS = 25000;
const RECONNECT_MIN_MS = 1000;
const RECONNECT_MAX_MS = 15000;
function buildWsUrl() {
if (_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl) {
return _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl;
}
const protocol = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.useWss ? 'wss' : 'ws';
const host = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imServerHost || window.location.hostname;
const port = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort ? `:${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort}` : '';
const path = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath?.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath : `/${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath || 'ws'}`;
return `${protocol}://${host}${port}${path}`;
}
function normalizeConversationId(payload) {
const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender;
return payload.conversationId || (target ? `single-${target}` : '');
}
function normalizeIncomingMessage(payload, currentUserId) {
const item = payload.message || payload;
const from = item.from || item.sender || item.fromUser || '';
const target = item.target || item.to || item.receiver || '';
const direction = from && String(from) === String(currentUserId) ? 'out' : 'in';
const conversationId = item.conversationId || normalizeConversationId({
...item,
target: direction === 'out' ? target : from
});
if (!conversationId) {
return null;
}
const status = item.status || item.deliveryStatus || 'sent';
return {
id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`,
messageUid: item.messageUid || item.uid || item.messageId || '',
conversationId,
from,
target,
direction,
type: item.type || 'text',
text: item.text || item.content || item.searchableContent || '',
status,
deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''),
timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()),
displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()),
raw: item
};
}
class LongConnectionImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_5__/* .HttpImClient */ .Y {
constructor() {
super();
this.socket = null;
this.wsUrl = buildWsUrl();
this.heartbeatTimer = null;
this.reconnectTimer = null;
this.reconnectAttempts = 0;
this.manualClose = false;
}
getSdkVersion() {
return 'JC-LC/0.1';
}
shouldUseMessagePolling() {
return !this.connected;
}
async ensureSdk() {
if (typeof WebSocket === 'undefined') {
throw new Error('当前浏览器不支持 WebSocket 长连接');
}
return true;
}
connect(userId, token) {
this.currentUser = {
userId,
token
};
this.manualClose = false;
this.openSocket();
}
disconnect() {
this.manualClose = true;
this.clearReconnectTimer();
this.clearHeartbeatTimer();
if (this.socket) {
this.socket.close();
this.socket = null;
}
super.disconnect();
}
openSocket() {
if (this.socket?.readyState === WebSocket.OPEN) {
this.sendAuthFrame();
return;
}
if (this.socket?.readyState === WebSocket.CONNECTING) {
return;
}
this.emit('connectionStatusChanged', {
connected: false,
statusText: '长连接连接中'
});
try {
this.socket = new WebSocket(this.wsUrl);
this.socket.binaryType = 'arraybuffer';
} catch (error) {
this.emit('connectionStatusChanged', {
connected: false,
statusText: '长连接创建失败,使用HTTP补偿'
});
this.scheduleReconnect();
return;
}
this.socket.onopen = () => {
this.connected = true;
this.reconnectAttempts = 0;
this.emit('connectionStatusChanged', {
connected: true,
statusText: '长连接已连接'
});
this.sendAuthFrame();
this.startHeartbeat();
this.refreshConversationList();
};
this.socket.onmessage = event => {
this.handleFrame(event.data);
};
this.socket.onerror = () => {
this.emit('connectionStatusChanged', {
connected: false,
statusText: '长连接异常,使用HTTP补偿'
});
};
this.socket.onclose = () => {
this.connected = false;
this.clearHeartbeatTimer();
this.socket = null;
if (this.manualClose) {
return;
}
this.emit('connectionStatusChanged', {
connected: false,
statusText: '长连接重连中'
});
this.scheduleReconnect();
};
}
sendAuthFrame() {
this.sendFrame({
type: 'auth',
userId: this.currentUser?.userId || '',
token: this.currentUser?.token || '',
clientId: this.getClientId(),
platform: _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.platform,
timestamp: Date.now()
});
}
sendFrame(frame) {
if (this.socket?.readyState !== WebSocket.OPEN) {
return false;
}
this.socket.send(JSON.stringify(frame));
return true;
}
handleFrame(rawData) {
if (rawData instanceof ArrayBuffer) {
this.emit('rawFrameReceived', rawData);
return;
}
let payload;
try {
payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
} catch (error) {
return;
}
const type = payload.type || payload.event || payload.cmd || '';
if (type === 'pong' || type === 'auth_ok' || type === 'connected') {
return;
}
if (type === 'contactsChanged') {
this.emit('contactsChanged', payload.contacts || []);
return;
}
if (type === 'conversationsChanged') {
this.emit('conversationsChanged', payload.conversations || []);
return;
}
if (type === 'messages' && Array.isArray(payload.messages)) {
payload.messages.map(message => normalizeIncomingMessage(message, this.currentUser?.userId)).filter(Boolean).forEach(message => this.emit('messageReceived', message));
return;
}
const message = normalizeIncomingMessage(payload, this.currentUser?.userId);
if (message) {
this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message);
}
}
startHeartbeat() {
this.clearHeartbeatTimer();
this.heartbeatTimer = window.setInterval(() => {
this.sendFrame({
type: 'ping',
timestamp: Date.now()
});
}, HEARTBEAT_INTERVAL_MS);
}
clearHeartbeatTimer() {
if (this.heartbeatTimer) {
window.clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
scheduleReconnect() {
this.clearReconnectTimer();
const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts);
this.reconnectAttempts += 1;
this.reconnectTimer = window.setTimeout(() => {
this.openSocket();
}, delay);
}
clearReconnectTimer() {
if (this.reconnectTimer) {
window.clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
}
}
/***/ }),
/***/ 446:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ B: function() { return /* binding */ imageDisplayUrl; }
/* harmony export */ });
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8__);
function configuredProxyHosts() {
const configured = window.JC_WEB_IM_CONFIG?.mediaProxyHosts;
const values = Array.isArray(configured) ? configured : String(configured || '').split(/[\s,]+/);
return new Set(['zhiyanim.dfpnm.cn', ...values].map(value => String(value || '').trim().toLowerCase().replace(/\.$/, '')).filter(Boolean));
}
function imageDisplayUrl(value) {
const source = String(value || '').trim();
if (!source || source.startsWith('blob:') || source.startsWith('data:')) {
return source;
}
try {
const url = new URL(source, window.location.origin);
if (url.protocol !== 'https:' || !configuredProxyHosts().has(url.hostname.toLowerCase())) {
return source;
}
const proxyUrl = new URL('/api/media_proxy.php', window.location.origin);
proxyUrl.searchParams.set('url', url.toString());
return proxyUrl.toString();
} catch (error) {
return source;
}
}
/***/ }),
/***/ 9687:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2387);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2169);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5051);
class RealtimeNotificationClient {
constructor() {
this.source = null;
this.userId = '';
this.handler = null;
this.reconnectTimer = null;
this.reconnectAttempt = 0;
this.generation = 0;
}
isConnected() {
return this.source?.readyState === WebSocket.OPEN;
}
start(userId, handler) {
this.stop();
if (!_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseEnabled || !userId || typeof window.WebSocket !== 'function') return;
this.userId = userId;
this.handler = handler;
this.generation += 1;
this.open(this.generation);
}
stop() {
this.generation += 1;
window.clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
if (this.source) this.source.close();
this.source = null;
this.userId = '';
this.handler = null;
this.reconnectAttempt = 0;
}
async open(generation) {
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseTicketApi, {
userId: this.userId
}, {
withCredentials: false,
headers: _services_imClient__WEBPACK_IMPORTED_MODULE_3__/* .imClient */ .wD.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.appServer)
});
if (generation !== this.generation) return;
if (response.data?.code !== 0) throw new Error(response.data?.message || '实时通知凭证申请失败');
const ticket = response.data?.result?.ticket || '';
if (!ticket) throw new Error('实时通知凭证为空');
const separator = _config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseUrl.includes('?') ? '&' : '?';
const endpoint = `${_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseUrl}${separator}ticket=${encodeURIComponent(ticket)}`;
const socketUrl = endpoint.startsWith('ws://') || endpoint.startsWith('wss://') ? endpoint : `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
const source = new WebSocket(socketUrl);
this.source = source;
source.onopen = () => {
this.reconnectAttempt = 0;
};
source.onmessage = event => {
if (generation !== this.generation) return;
let payload = {};
try {
payload = JSON.parse(event.data || '{}');
} catch (error) {
payload = {};
}
if (payload.type !== 'message-notification') return;
this.handler?.(payload);
};
source.onerror = () => {
if (generation !== this.generation) return;
source.close();
if (this.source === source) this.source = null;
this.scheduleReconnect(generation);
};
source.onclose = () => {
if (generation !== this.generation || this.source !== source) return;
this.source = null;
this.scheduleReconnect(generation);
};
} catch (error) {
if (generation === this.generation) this.scheduleReconnect(generation);
}
}
scheduleReconnect(generation) {
window.clearTimeout(this.reconnectTimer);
const delay = Math.min(30000, 1000 * 2 ** Math.min(this.reconnectAttempt, 5));
this.reconnectAttempt += 1;
this.reconnectTimer = window.setTimeout(() => this.open(generation), delay);
}
}
const realtimeNotifications = new RealtimeNotificationClient();
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "w", 0, /* binding */ realtimeNotifications
/* harmony export */ ]);
/***/ }),
/***/ 9045:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5367);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2731);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2261);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5051);
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(7566);
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(1414);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(926);
const CONTACT_CACHE_MS = 15000;
function normalizeContacts(contacts) {
const unique = new Map();
contacts.forEach(contact => {
const uid = String(contact.uid || contact.id || '').trim();
if (!uid) {
return;
}
const normalized = {
...contact,
id: String(contact.id || uid),
uid
};
unique.set(uid, {
...(unique.get(uid) || {}),
...normalized
});
});
return Array.from(unique.values()).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
}
const useContactStore = (0,pinia__WEBPACK_IMPORTED_MODULE_6__/* .defineStore */ .nY)('contacts', {
state: () => ({
contacts: [],
activeId: '',
loading: false,
eventsBound: false,
refreshSerial: 0,
refreshPromise: null,
loadedForUserId: '',
loadedAt: 0,
actionError: '',
actionInfo: ''
}),
getters: {
activeContact(state) {
return state.contacts.find(item => item.id === state.activeId) || state.contacts[0] || null;
}
},
actions: {
bindImEvents() {
if (this.eventsBound) {
return;
}
this.eventsBound = true;
_services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.on('contactsChanged', contacts => {
if (!contacts.length && this.contacts.length) {
return;
}
this.contacts = normalizeContacts(contacts);
if (!this.contacts.find(item => item.id === this.activeId)) {
this.activeId = this.contacts[0]?.id || '';
}
});
},
async refreshContacts(options = {}) {
this.bindImEvents();
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
const requestUserId = session.userId;
const force = Boolean(options.force);
if (!requestUserId) {
this.clearContacts();
return [];
}
if (!force && this.contacts.length && this.loadedForUserId === requestUserId && Date.now() - this.loadedAt < CONTACT_CACHE_MS) {
return this.contacts;
}
if (this.refreshPromise && !force) {
return this.refreshPromise;
}
const serial = this.refreshSerial + 1;
this.refreshSerial = serial;
this.loading = true;
this.refreshPromise = (async () => {
this.contacts = normalizeContacts(_services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.refreshContactList());
if (!this.contacts.find(item => item.id === this.activeId)) {
this.activeId = this.contacts[0]?.id || '';
}
if (!this.contacts.length || force) {
const serverContacts = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.getServerContactList(requestUserId);
if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)().userId !== requestUserId) {
return this.contacts;
}
this.contacts = normalizeContacts(serverContacts);
this.loadedForUserId = requestUserId;
this.loadedAt = Date.now();
if (!this.contacts.find(item => item.id === this.activeId)) {
this.activeId = this.contacts[0]?.id || '';
}
}
window.setTimeout(() => {
if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)().userId !== requestUserId) {
return;
}
const latest = _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.getContactList(false);
if (latest.length || !this.contacts.length) {
this.contacts = normalizeContacts(latest);
this.loadedForUserId = requestUserId;
this.loadedAt = Date.now();
if (!this.contacts.find(item => item.id === this.activeId)) {
this.activeId = this.contacts[0]?.id || '';
}
}
}, 1200);
return this.contacts;
})();
try {
return await this.refreshPromise;
} finally {
if (serial === this.refreshSerial) {
this.loading = false;
this.refreshPromise = null;
}
}
},
async addContact(keyword) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
const value = String(keyword || '').trim();
this.actionError = '';
this.actionInfo = '';
if (!session.userId) {
this.actionError = '请先登录';
return false;
}
if (!value) {
this.actionError = '请输入用户ID、手机号或用户名';
return false;
}
this.loading = true;
try {
const contact = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.addContact(session.userId, value, '添加联系人');
if (contact) {
this.contacts = normalizeContacts([...this.contacts, contact]);
this.activeId = contact.id;
}
this.actionInfo = '联系人已添加';
await this.refreshContacts({
force: true
});
return true;
} catch (error) {
this.actionError = error.message || '添加联系人失败';
return false;
} finally {
this.loading = false;
}
},
async updateContactAlias(contactId, alias) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
const targetId = String(contactId || '').trim();
const nextAlias = String(alias || '').trim();
this.actionError = '';
this.actionInfo = '';
if (!session.userId) {
this.actionError = '请先登录';
return false;
}
if (!targetId) {
this.actionError = '缺少联系人ID';
return false;
}
try {
const savedAlias = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.updateContactAlias(session.userId, targetId, nextAlias);
this.contacts = normalizeContacts(this.contacts.map(item => {
if (item.uid !== targetId && item.id !== targetId) {
return item;
}
const rawUser = {
...(item.rawUser || {}),
friendAlias: savedAlias
};
const rawFriend = {
...(item.rawFriend || {}),
alias: savedAlias
};
const title = savedAlias || rawUser.displayName || rawUser.name || item.uid;
return {
...item,
title,
avatarText: title.slice(0, 1).toUpperCase(),
alias: savedAlias,
rawFriend,
rawUser
};
}));
this.loadedAt = Date.now();
this.actionInfo = '备注名已修改';
return true;
} catch (error) {
this.actionError = error.message || '备注名修改失败';
return false;
}
},
clearContacts() {
this.refreshSerial += 1;
this.contacts = [];
this.activeId = '';
this.loading = false;
this.refreshPromise = null;
this.loadedForUserId = '';
this.loadedAt = 0;
this.actionError = '';
this.actionInfo = '';
},
setActiveContact(id) {
this.activeId = id;
},
openChat(contact) {
if (!contact) {
return;
}
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_8__/* .useConversationStore */ .w)();
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_9__/* .useNavigationStore */ .l)();
const conversation = _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.createSingleConversation(contact.uid, contact);
conversations.upsertConversation(conversation);
conversations.setActiveConversation(conversation.id);
navigation.showMessages();
}
}
});
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "p", 0, /* binding */ useContactStore
/* harmony export */ ]);
/***/ }),
/***/ 7566:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* unused harmony import specifier */ var imClient;
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(531);
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7588);
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(8237);
/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(3579);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5367);
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(2731);
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18__);
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(2261);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(5051);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(2169);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(926);
/* harmony import */ var _services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(9687);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(446);
const LOCAL_CONVERSATION_STORAGE_KEY = 'qmt-web-im-local-conversations-v2';
const LOCAL_FAVORITE_MESSAGES_KEY = 'qmt-web-im-favorite-messages-v1';
const LOCAL_PINNED_MESSAGES_KEY = 'qmt-web-im-pinned-messages-v1';
function scopedStorageKey(baseKey) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
const scope = `${_config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.appServer || ''}:${session.userId || 'anonymous'}`;
return `${baseKey}:${encodeURIComponent(scope)}`;
}
function readFavoriteMessages() {
try {
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY)) || '[]');
} catch (error) {
return [];
}
}
function writeFavoriteMessages(messages) {
localStorage.setItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY), JSON.stringify(messages));
}
function readLocalConversations() {
try {
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY)) || '[]');
} catch (error) {
return [];
}
}
function writeLocalConversations(conversations) {
localStorage.setItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY), JSON.stringify(conversations));
}
function readPinnedMessages() {
try {
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_PINNED_MESSAGES_KEY)) || '{}');
} catch (error) {
return {};
}
}
function writePinnedMessages(messages) {
localStorage.setItem(scopedStorageKey(LOCAL_PINNED_MESSAGES_KEY), JSON.stringify(messages));
}
function sortConversations(conversations) {
return [...conversations].sort((left, right) => {
const leftPinned = Number(left.pinnedAt || left.top || 0);
const rightPinned = Number(right.pinnedAt || right.top || 0);
if (Boolean(leftPinned) !== Boolean(rightPinned)) {
return rightPinned ? 1 : -1;
}
if (leftPinned && rightPinned && leftPinned !== rightPinned) {
return rightPinned - leftPinned;
}
return Number(right.updatedAt || 0) - Number(left.updatedAt || 0);
});
}
function randomId() {
if (window.crypto && window.crypto.randomUUID) {
return window.crypto.randomUUID().replaceAll('-', '');
}
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
}
function messageKey(message) {
return message.id || message.messageUid;
}
function messageStableKey(message) {
return String(message?.messageUid || message?.id || '');
}
function messageActivityTimestamp(message) {
return Number(message?.activityTimestamp || message?.editedAt || message?.displayTimestamp || message?.timestamp || 0);
}
function isRecalledMessage(message) {
return Boolean(message?.recalled) || message?.status === 'recalled';
}
function attachmentLabel(message) {
const attachment = message?.attachment;
if (!attachment) {
return '';
}
if (attachment.type === 'image') {
return '[图片]';
}
return `[文件] ${attachment.name || '文件'}`;
}
function messagePreviewText(message) {
if (isRecalledMessage(message)) {
return `[${message?.recallStatus || '已撤回'}]`;
}
const text = String(message?.text || '').replace(/\s+/g, ' ').trim();
return text || attachmentLabel(message);
}
function quotePrefix(message) {
const text = messagePreviewText(message);
return text.length > 48 ? `${text.slice(0, 48)}...` : text;
}
async function writeClipboard(text) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const element = document.createElement('textarea');
element.value = text;
element.setAttribute('readonly', 'readonly');
element.style.position = 'fixed';
element.style.left = '-9999px';
document.body.appendChild(element);
element.select();
document.execCommand('copy');
document.body.removeChild(element);
}
function isSameMessage(left, right) {
if (left.messageUid && right.messageUid && left.messageUid === right.messageUid) {
return true;
}
if (left.id && right.id && left.id === right.id) {
return true;
}
return left.direction === right.direction && left.text === right.text && (left.type || 'text') === (right.type || 'text') && Math.abs(Number(left.displayTimestamp || left.timestamp || 0) - Number(right.displayTimestamp || right.timestamp || 0)) < 15000;
}
function hasExactMessage(messages, message) {
return messages.some(item => {
if (item.id && message.id && item.id === message.id) {
return true;
}
return item.messageUid && message.messageUid && item.messageUid === message.messageUid;
});
}
function shouldUseMessagePolling() {
return imClient.shouldUseMessagePolling ? imClient.shouldUseMessagePolling() : true;
}
function canMarkReadNow(options = {}) {
if (typeof document === 'undefined') {
return false;
}
if (document.visibilityState !== 'visible') {
return false;
}
if (options.userAction) {
return true;
}
return true;
}
function normalizeMessageForDisplay(message) {
if (!message || message.attachment || String(message.text || '').trim()) {
return message;
}
const contentType = Number(message.contentType || 0);
const labels = {
3: '[图片加载失败]',
6: '[视频加载失败]',
90: '[红包]',
92: '以上是打招呼的内容',
93: '你们已经是好友了,可以开始聊天了。',
105: '[领取了红包]'
};
if (!labels[contentType]) {
return message;
}
return {
...message,
type: 'text',
text: labels[contentType]
};
}
function mergeVisibleMessages(currentMessages, syncedMessages) {
const merged = [...syncedMessages].map(normalizeMessageForDisplay);
currentMessages.forEach(currentMessage => {
currentMessage = normalizeMessageForDisplay(currentMessage);
const exists = merged.some(message => isSameMessage(message, currentMessage));
const shouldKeepLocal = currentMessage.status === 'sending' || currentMessage.status === 'failed' || currentMessage.direction === 'out' && currentMessage.status === 'sent' && Date.now() - Number(currentMessage.timestamp || 0) < 30000;
if (!exists && shouldKeepLocal) {
merged.push(currentMessage);
}
});
return merged.filter((message, index, messages) => {
const key = messageKey(message);
return messages.findIndex(item => messageKey(item) === key) === index;
}).sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0));
}
function incomingEditedMessages(previousMessages, nextMessages) {
const previousByKey = new Map();
(previousMessages || []).forEach(message => {
const key = messageStableKey(message);
if (key) {
previousByKey.set(key, message);
}
});
return (nextMessages || []).filter(message => {
if (message.direction !== 'in') {
return false;
}
const editedAt = Number(message.editedAt || 0);
if (editedAt <= 0) {
return false;
}
const previous = previousByKey.get(messageStableKey(message));
return previous && editedAt > Number(previous.editedAt || 0);
});
}
let notificationAudioContext = null;
function playNotificationSound() {
if (typeof window === 'undefined') {
return;
}
try {
const AudioContext = window.AudioContext || window.webkitAudioContext;
if (!AudioContext) {
return;
}
notificationAudioContext = notificationAudioContext || new AudioContext();
if (notificationAudioContext.state === 'suspended') {
notificationAudioContext.resume().catch(() => {});
}
const oscillator = notificationAudioContext.createOscillator();
const gain = notificationAudioContext.createGain();
const startAt = notificationAudioContext.currentTime;
oscillator.type = 'sine';
oscillator.frequency.setValueAtTime(880, startAt);
oscillator.frequency.setValueAtTime(660, startAt + 0.1);
gain.gain.setValueAtTime(0.0001, startAt);
gain.gain.exponentialRampToValueAtTime(0.12, startAt + 0.02);
gain.gain.exponentialRampToValueAtTime(0.0001, startAt + 0.22);
oscillator.connect(gain);
gain.connect(notificationAudioContext.destination);
oscillator.start(startAt);
oscillator.stop(startAt + 0.24);
} catch (error) {
// Notification sound is best-effort; browsers may block audio until user interaction.
}
}
const useConversationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_19__/* .defineStore */ .nY)('conversations', {
state: () => ({
activeId: '',
conversations: [],
messagesByConversation: {},
visibleMessagesByConversation: {},
eventsBound: false,
usingDemoData: false,
loading: false,
syncTimer: null,
conversationSyncTimer: null,
readPresenceEventsBound: false,
syncInFlight: false,
pendingReadReceiptConversationId: '',
conversationSyncInFlight: false,
syncAfterSendTimer: null,
optimisticMessagesByConversation: {},
quotedMessage: null,
forwardingMessages: [],
editingMessage: null,
editingText: '',
editingMode: '',
messageDetailOpen: false,
messageDetailLoading: false,
messageDetailError: '',
messageDetail: null,
attentionMessageId: '',
attentionMessageTimer: null,
selectionMode: false,
selectedMessageIds: [],
favoriteMessages: [],
pinnedMessagesByConversation: {},
activeFavoriteKey: '',
actionNotice: '',
actionError: '',
actionNoticeTimer: null,
realtimeSyncTimer: null
}),
getters: {
activeConversation(state) {
return state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;
},
activeMessages(state) {
return state.visibleMessagesByConversation[state.activeId] || [];
},
totalUnread(state) {
return state.conversations.reduce((sum, item) => sum + Number(item.unread || 0), 0);
},
canSendActiveConversation(state) {
const conversation = state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;
if (!conversation) {
return false;
}
if (conversation.type !== 'channel') {
return true;
}
return ['owner', 'admin'].includes(conversation.role || conversation.raw?.role || '');
},
favoriteMessageIds(state) {
return state.favoriteMessages.map(message => message.key);
},
activeFavorite(state) {
return state.favoriteMessages.find(message => message.key === state.activeFavoriteKey) || state.favoriteMessages[0] || null;
},
activePinnedMessage(state) {
const pinned = state.pinnedMessagesByConversation[state.activeId] || null;
if (!pinned) return null;
const message = (state.visibleMessagesByConversation[state.activeId] || []).find(item => messageStableKey(item) === pinned.key);
return message ? {
...pinned,
...message,
key: pinned.key
} : pinned;
},
selectedMessages(state) {
const selectedIds = new Set(state.selectedMessageIds);
return (state.visibleMessagesByConversation[state.activeId] || []).filter(message => selectedIds.has(messageStableKey(message)));
}
},
actions: {
bootstrapDemoData() {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
this.bindImEvents();
this.usingDemoData = false;
if (!session.userId) {
this.clearUserState();
return;
}
this.loadScopedLocalState();
this.startMessageSync();
_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.start(session.userId, payload => this.handleRealtimeNotification(payload));
},
loadScopedLocalState() {
this.conversations = [];
this.favoriteMessages = readFavoriteMessages();
this.pinnedMessagesByConversation = readPinnedMessages();
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
this.activeId = '';
this.messagesByConversation = {};
this.visibleMessagesByConversation = {};
this.optimisticMessagesByConversation = {};
this.quotedMessage = null;
this.forwardingMessages = [];
this.editingMessage = null;
this.editingText = '';
this.editingMode = '';
this.messageDetailOpen = false;
this.messageDetailLoading = false;
this.messageDetailError = '';
this.messageDetail = null;
this.selectionMode = false;
this.selectedMessageIds = [];
},
clearUserState() {
window.clearInterval(this.syncTimer);
window.clearInterval(this.conversationSyncTimer);
window.clearTimeout(this.syncAfterSendTimer);
window.clearTimeout(this.attentionMessageTimer);
window.clearTimeout(this.actionNoticeTimer);
window.clearTimeout(this.realtimeSyncTimer);
_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.stop();
this.syncTimer = null;
this.conversationSyncTimer = null;
this.syncAfterSendTimer = null;
this.attentionMessageTimer = null;
this.actionNoticeTimer = null;
this.realtimeSyncTimer = null;
this.syncInFlight = false;
this.conversationSyncInFlight = false;
this.pendingReadReceiptConversationId = '';
this.activeId = '';
this.conversations = [];
this.messagesByConversation = {};
this.visibleMessagesByConversation = {};
this.optimisticMessagesByConversation = {};
this.quotedMessage = null;
this.forwardingMessages = [];
this.editingMessage = null;
this.editingText = '';
this.editingMode = '';
this.messageDetailOpen = false;
this.messageDetailLoading = false;
this.messageDetailError = '';
this.messageDetail = null;
this.attentionMessageId = '';
this.selectionMode = false;
this.selectedMessageIds = [];
this.favoriteMessages = [];
this.activeFavoriteKey = '';
this.actionNotice = '';
this.actionError = '';
},
bindImEvents() {
if (this.eventsBound) {
return;
}
this.eventsBound = true;
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageSent', message => {
this.appendMessage(message.conversationId, message);
});
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageReceived', message => {
this.appendMessage(message.conversationId, message);
if (message.conversationId === this.activeId) {
this.scheduleActiveMessagesSync({
allowReadReceipt: true
}, 500);
}
});
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageStatusChanged', message => {
this.replaceMessage(message.conversationId, message);
});
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('conversationsChanged', remoteConversations => {
this.usingDemoData = false;
this.applyRemoteConversations(remoteConversations);
});
},
setActiveConversation(id) {
this.activeId = id;
const conversation = this.conversations.find(item => item.id === id);
if (conversation) {
conversation.unread = 0;
}
this.loadActiveMessages({
allowReadReceipt: true,
userAction: true
});
},
sendText(text) {
const conversation = this.activeConversation;
if (!conversation || !text.trim()) {
return;
}
let value = text.trim();
if (this.quotedMessage) {
value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`;
this.quotedMessage = null;
}
const message = {
id: randomId(),
conversationId: conversation.id,
from: 'me',
direction: 'out',
type: 'text',
text: value,
status: 'sending',
deliveryStatus: 'sending',
timestamp: Date.now(),
displayTimestamp: Date.now()
};
this.appendVisibleMessage(conversation.id, message);
this.appendMessage(conversation.id, message);
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendTextMessage(conversation, value, message);
conversation.subtitle = value;
conversation.updatedAt = Date.now();
writeLocalConversations(this.conversations);
window.clearTimeout(this.syncAfterSendTimer);
this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 250);
},
sendAttachment({
type,
file,
text = ''
}) {
const conversation = this.activeConversation;
if (!conversation || !file || !['image', 'file'].includes(type)) {
return;
}
let value = text.trim();
if (this.quotedMessage) {
value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`.trim();
this.quotedMessage = null;
}
const now = Date.now();
const message = {
id: randomId(),
conversationId: conversation.id,
from: 'me',
senderRole: conversation.role || conversation.raw?.role || '',
direction: 'out',
type,
text: value,
attachment: {
type,
name: file.name || (type === 'image' ? '图片' : '文件'),
mime: file.type || '',
size: file.size || 0,
url: type === 'image' ? URL.createObjectURL(file) : ''
},
status: 'sending',
deliveryStatus: 'sending',
timestamp: now,
displayTimestamp: now
};
this.appendVisibleMessage(conversation.id, message);
this.appendMessage(conversation.id, message);
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendAttachmentMessage(conversation, {
type,
file,
text: value
}, message);
conversation.subtitle = messagePreviewText(message);
conversation.updatedAt = now;
writeLocalConversations(this.conversations);
window.clearTimeout(this.syncAfterSendTimer);
this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 350);
},
async sendTextToConversation(conversation, text) {
if (!conversation || !text.trim()) {
return null;
}
const value = text.trim();
const message = {
id: randomId(),
conversationId: conversation.id,
from: 'me',
direction: 'out',
type: 'text',
text: value,
status: 'sending',
deliveryStatus: 'sending',
timestamp: Date.now(),
displayTimestamp: Date.now()
};
this.appendMessage(conversation.id, message);
const sentMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendTextMessage(conversation, value, message);
this.replaceMessage(conversation.id, sentMessage);
return sentMessage;
},
upsertConversation(conversation) {
const index = this.conversations.findIndex(item => item.id === conversation.id);
if (index >= 0) {
this.conversations.splice(index, 1, {
...this.conversations[index],
...conversation
});
} else {
this.conversations.unshift(conversation);
}
this.usingDemoData = false;
writeLocalConversations(this.conversations);
},
removeConversation(conversationId) {
this.conversations = this.conversations.filter(conversation => conversation.id !== conversationId);
const {
[conversationId]: removedMessages,
...messagesByConversation
} = this.messagesByConversation;
const {
[conversationId]: removedVisibleMessages,
...visibleMessagesByConversation
} = this.visibleMessagesByConversation;
const {
[conversationId]: removedOptimisticMessages,
...optimisticMessagesByConversation
} = this.optimisticMessagesByConversation;
void removedMessages;
void removedVisibleMessages;
void removedOptimisticMessages;
this.messagesByConversation = messagesByConversation;
this.visibleMessagesByConversation = visibleMessagesByConversation;
this.optimisticMessagesByConversation = optimisticMessagesByConversation;
if (this.activeId === conversationId) {
this.activeId = this.conversations[0]?.id || '';
}
writeLocalConversations(this.conversations);
if (this.activeId) {
this.loadActiveMessages();
}
},
applyRemoteConversations(remoteConversations) {
const remote = Array.isArray(remoteConversations) ? remoteConversations : [];
if (!remote.length && this.conversations.length) {
return;
}
const merged = new Map();
this.conversations.forEach(conversation => {
merged.set(conversation.id, conversation);
});
remote.forEach(conversation => {
const unread = conversation.id === this.activeId && canMarkReadNow() ? 0 : Number(conversation.unread || 0);
merged.set(conversation.id, {
...(merged.get(conversation.id) || {}),
...conversation,
unread
});
});
this.conversations = sortConversations(Array.from(merged.values())).slice(0, 100);
if (!this.conversations.length) {
this.activeId = '';
this.messagesByConversation = {};
this.visibleMessagesByConversation = {};
this.optimisticMessagesByConversation = {};
writeLocalConversations(this.conversations);
return;
}
if (!this.conversations.find(item => item.id === this.activeId)) {
this.activeId = this.conversations[0].id;
}
writeLocalConversations(this.conversations);
this.loadActiveMessages();
},
togglePinnedConversation(conversationId) {
const conversation = this.conversations.find(item => item.id === conversationId);
if (!conversation) return;
conversation.pinnedAt = Number(conversation.pinnedAt || conversation.top || 0) > 0 ? 0 : Date.now();
conversation.top = conversation.pinnedAt;
this.conversations = sortConversations(this.conversations);
writeLocalConversations(this.conversations);
},
appendMessage(conversationId, message) {
if (!this.messagesByConversation[conversationId]) {
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: []
};
}
if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent')) {
this.keepOptimisticMessage(conversationId, message);
}
if (!hasExactMessage(this.messagesByConversation[conversationId], message)) {
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: [...this.messagesByConversation[conversationId], message]
};
}
this.updateConversationFromMessage(conversationId, message);
this.syncVisibleMessages(conversationId);
writeLocalConversations(this.conversations);
},
removeMessages(conversationId, messages) {
const ids = new Set(messages.flatMap(message => [message.id, message.messageUid].filter(Boolean).map(String)));
const filterMessages = list => (list || []).filter(message => {
return ![message.id, message.messageUid].filter(Boolean).some(id => ids.has(String(id)));
});
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: filterMessages(this.messagesByConversation[conversationId])
};
this.visibleMessagesByConversation = {
...this.visibleMessagesByConversation,
[conversationId]: filterMessages(this.visibleMessagesByConversation[conversationId])
};
this.optimisticMessagesByConversation = {
...this.optimisticMessagesByConversation,
[conversationId]: filterMessages(this.optimisticMessagesByConversation[conversationId])
};
this.selectedMessageIds = this.selectedMessageIds.filter(id => !ids.has(String(id)));
},
replaceLocalMessage(conversationId, targetMessage, nextMessage) {
const keys = new Set([targetMessage.id, targetMessage.messageUid].filter(Boolean).map(String));
const replaceInList = list => (list || []).map(message => {
const matched = [message.id, message.messageUid].filter(Boolean).some(id => keys.has(String(id)));
return matched ? {
...message,
...nextMessage
} : message;
});
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: replaceInList(this.messagesByConversation[conversationId])
};
this.visibleMessagesByConversation = {
...this.visibleMessagesByConversation,
[conversationId]: replaceInList(this.visibleMessagesByConversation[conversationId])
};
},
updateConversationFromMessage(conversationId, message) {
const conversation = this.conversations.find(item => item.id === conversationId);
if (!conversation) {
return;
}
conversation.subtitle = message.text || conversation.subtitle || '';
conversation.updatedAt = messageActivityTimestamp(message) || Date.now();
if (message.direction === 'in') {
conversation.unread = conversationId === this.activeId ? 0 : Number(conversation.unread || 0) + 1;
}
this.conversations = [...this.conversations].sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));
},
appendVisibleMessage(conversationId, message) {
const messages = this.visibleMessagesByConversation[conversationId] || [];
this.visibleMessagesByConversation = {
...this.visibleMessagesByConversation,
[conversationId]: [...messages.filter(item => item.id !== message.id), message].sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0))
};
},
replaceMessage(conversationId, message) {
if (!this.messagesByConversation[conversationId]) {
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: []
};
}
if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent' || message.status === 'failed')) {
this.keepOptimisticMessage(conversationId, message);
}
const index = this.messagesByConversation[conversationId].findIndex(item => item.id === message.id);
if (index >= 0) {
const messages = [...this.messagesByConversation[conversationId]];
messages.splice(index, 1, message);
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: messages
};
} else {
this.messagesByConversation = {
...this.messagesByConversation,
[conversationId]: [...this.messagesByConversation[conversationId], message]
};
}
this.syncVisibleMessages(conversationId);
},
syncVisibleMessages(conversationId) {
this.visibleMessagesByConversation = {
...this.visibleMessagesByConversation,
[conversationId]: mergeVisibleMessages(this.optimisticMessagesByConversation[conversationId] || [], this.messagesByConversation[conversationId] || [])
};
},
keepOptimisticMessage(conversationId, message) {
if (!this.optimisticMessagesByConversation[conversationId]) {
this.optimisticMessagesByConversation = {
...this.optimisticMessagesByConversation,
[conversationId]: []
};
}
const messages = this.optimisticMessagesByConversation[conversationId];
const index = messages.findIndex(item => item.id === message.id);
let nextMessages;
if (index >= 0) {
nextMessages = [...messages];
nextMessages.splice(index, 1, message);
} else {
nextMessages = [...messages, message];
}
this.optimisticMessagesByConversation = {
...this.optimisticMessagesByConversation,
[conversationId]: nextMessages
};
},
pruneOptimisticMessages(conversationId, syncedMessages) {
const messages = this.optimisticMessagesByConversation[conversationId] || [];
if (!messages.length) {
return;
}
this.optimisticMessagesByConversation = {
...this.optimisticMessagesByConversation,
[conversationId]: messages.filter(message => {
const remoteMatched = syncedMessages.some(syncedMessage => {
return syncedMessage.id !== message.id && isSameMessage(syncedMessage, message);
});
if (remoteMatched && message.status !== 'failed') {
return false;
}
return Date.now() - Number(message.displayTimestamp || message.timestamp || 0) < 30000 || message.status === 'failed';
})
};
},
loadActiveMessages(options = {}) {
const syncOptions = typeof options === 'boolean' ? {
allowReadReceipt: options
} : options;
const conversation = this.activeConversation;
if (!conversation) {
return;
}
this.loading = true;
const messages = _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.getMessages(conversation, 30);
this.pruneOptimisticMessages(conversation.id, messages);
this.messagesByConversation = {
...this.messagesByConversation,
[conversation.id]: mergeVisibleMessages(this.messagesByConversation[conversation.id] || [], messages)
};
this.syncVisibleMessages(conversation.id);
this.loading = false;
this.syncActiveMessages(syncOptions);
},
async syncActiveMessages(options = {}) {
const conversation = this.activeConversation;
if (!conversation) {
return;
}
const wantsReadReceipt = Boolean(options.allowReadReceipt);
const explicitReadReceipt = wantsReadReceipt && canMarkReadNow({
userAction: Boolean(options.userAction)
});
const pollingReadReceipt = canMarkReadNow();
const markRead = explicitReadReceipt || pollingReadReceipt;
if (this.syncInFlight) {
if (wantsReadReceipt) {
this.pendingReadReceiptConversationId = conversation.id;
}
return;
}
this.syncInFlight = true;
const syncedConversationId = conversation.id;
const previousMessages = this.messagesByConversation[syncedConversationId] || [];
try {
const messages = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.fetchRemoteMessages(conversation, 50, {
markRead,
includeConversations: Boolean(options.includeConversations)
});
const remotePinnedKey = String(messages.pinnedMessageUid || '');
if (remotePinnedKey) {
const pinnedMessage = messages.find(item => messageStableKey(item) === remotePinnedKey);
this.pinnedMessagesByConversation = {
...this.pinnedMessagesByConversation,
[syncedConversationId]: pinnedMessage ? {
key: remotePinnedKey,
id: remotePinnedKey,
text: messagePreviewText(pinnedMessage),
type: pinnedMessage.type || 'text',
attachment: pinnedMessage.attachment ? {
...pinnedMessage.attachment
} : null,
senderName: pinnedMessage.senderName || pinnedMessage.from || '',
timestamp: Number(pinnedMessage.displayTimestamp || pinnedMessage.timestamp || Date.now())
} : {
key: remotePinnedKey,
id: remotePinnedKey,
text: '[置顶消息]'
}
};
writePinnedMessages(this.pinnedMessagesByConversation);
}
const editedIncomingMessages = incomingEditedMessages(previousMessages, messages);
this.pruneOptimisticMessages(syncedConversationId, messages);
this.messagesByConversation = {
...this.messagesByConversation,
[syncedConversationId]: mergeVisibleMessages(this.messagesByConversation[syncedConversationId] || [], messages)
};
this.syncVisibleMessages(syncedConversationId);
if (editedIncomingMessages.length && syncedConversationId === this.activeId) {
this.focusMessage(editedIncomingMessages.sort((a, b) => messageActivityTimestamp(b) - messageActivityTimestamp(a))[0]);
playNotificationSound();
}
const latest = messages.reduce((latestMessage, message) => {
if (!latestMessage || messageActivityTimestamp(message) > messageActivityTimestamp(latestMessage)) {
return message;
}
return latestMessage;
}, null);
if (latest) {
conversation.subtitle = messagePreviewText(latest);
conversation.updatedAt = messageActivityTimestamp(latest);
writeLocalConversations(this.conversations);
}
} catch (error) {
// Keep the local view usable if a polling request misses.
} finally {
this.syncInFlight = false;
if (this.pendingReadReceiptConversationId === this.activeId && canMarkReadNow()) {
this.pendingReadReceiptConversationId = '';
window.setTimeout(() => this.syncActiveMessages({
allowReadReceipt: true
}), 0);
}
}
},
scheduleActiveMessagesSync(options = {}, delay = 500) {
if (!this.activeId || typeof document !== 'undefined' && document.visibilityState !== 'visible') {
return;
}
window.clearTimeout(this.syncAfterSendTimer);
this.syncAfterSendTimer = window.setTimeout(() => {
this.syncAfterSendTimer = null;
this.syncActiveMessages(options);
}, Math.max(0, Number(delay) || 0));
},
startMessageSync() {
this.bindReadPresenceEvents();
if (!this.syncTimer) {
this.syncTimer = window.setInterval(() => {
if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
this.syncActiveMessages();
}
}, Math.max(250, _config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.syncIntervalMs));
}
if (!this.conversationSyncTimer) {
this.conversationSyncTimer = window.setInterval(() => {
if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
this.refreshRemoteConversations();
}
}, Math.max(5000, _config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.syncIntervalMs * 2));
this.refreshRemoteConversations();
}
},
handleRealtimeNotification() {
window.clearTimeout(this.realtimeSyncTimer);
this.realtimeSyncTimer = window.setTimeout(() => {
this.refreshRemoteConversations();
this.scheduleActiveMessagesSync({
allowReadReceipt: canMarkReadNow(),
includeConversations: true
}, 300);
}, 300);
},
bindReadPresenceEvents() {
if (this.readPresenceEventsBound || typeof window === 'undefined' || typeof document === 'undefined') {
return;
}
this.readPresenceEventsBound = true;
const syncWhenReadable = () => {
if (canMarkReadNow()) {
this.refreshRemoteConversations();
this.scheduleActiveMessagesSync({
allowReadReceipt: true
}, 200);
}
};
window.addEventListener('focus', syncWhenReadable);
document.addEventListener('visibilitychange', syncWhenReadable);
},
async refreshRemoteConversations() {
this.bindImEvents();
this.usingDemoData = false;
if (this.conversationSyncInFlight) {
return;
}
this.conversationSyncInFlight = true;
try {
const remoteConversations = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.fetchRemoteConversations(50);
this.applyRemoteConversations(remoteConversations);
} catch (error) {
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.refreshConversationList();
} finally {
this.conversationSyncInFlight = false;
}
},
setActionNotice(message) {
this.actionNotice = message;
this.actionError = '';
window.clearTimeout(this.actionNoticeTimer);
this.actionNoticeTimer = window.setTimeout(() => {
this.actionNotice = '';
this.actionNoticeTimer = null;
}, 3000);
},
setActionError(message) {
this.actionError = message;
this.actionNotice = '';
window.clearTimeout(this.actionNoticeTimer);
},
focusMessage(message) {
const key = messageStableKey(message);
if (!key) {
return;
}
this.attentionMessageId = key;
window.clearTimeout(this.attentionMessageTimer);
this.attentionMessageTimer = window.setTimeout(() => {
if (this.attentionMessageId === key) {
this.attentionMessageId = '';
}
}, 2800);
},
async handleMessageAction({
action,
message
}) {
if (!message) {
return;
}
if (action === 'copy') {
await this.copyMessages([message]);
} else if (action === 'edit') {
this.startEditMessage(message);
} else if (action === 'delete') {
this.deleteMessages([message]);
} else if (action === 'forward') {
this.startForward([message]);
} else if (action === 'favorite') {
this.toggleFavorite(message);
} else if (action === 'pin') {
this.togglePinnedMessage(message);
} else if (action === 'detail') {
await this.openMessageDetail(message);
} else if (action === 'quote') {
this.quoteMessage(message);
} else if (action === 'select') {
this.enterSelectionMode(message);
} else if (action === 'recall') {
await this.recallMessage(message);
}
},
async openMessageDetail(message) {
const conversation = this.activeConversation;
if (!conversation || !message) {
return;
}
const key = messageStableKey(message);
this.messageDetailOpen = true;
this.messageDetailLoading = true;
this.messageDetailError = '';
this.messageDetail = {
messageUid: key,
conversationType: conversation.type || conversation.raw?.type || 'single',
sentAt: Number(message.displayTimestamp || message.timestamp || 0),
editedAt: Number(message.editedAt || 0),
recalled: isRecalledMessage(message),
localOnly: true,
sender: {
uid: message.from || '',
name: message.senderName || message.from || ''
}
};
try {
if (!/^\d+$/.test(key)) {
this.messageDetailError = '本地临时消息暂无送达/已读详情';
return;
}
const detail = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.getMessageDetail(conversation, message);
this.messageDetail = detail || this.messageDetail;
} catch (error) {
this.messageDetailError = error.message || '消息详情加载失败';
} finally {
this.messageDetailLoading = false;
}
},
closeMessageDetail() {
this.messageDetailOpen = false;
this.messageDetailLoading = false;
this.messageDetailError = '';
this.messageDetail = null;
},
async copyMessages(messages) {
const text = messages.map(message => message.text || '').join('\n');
if (!text.trim()) {
return;
}
try {
await writeClipboard(text);
this.setActionNotice(messages.length > 1 ? '已复制所选消息' : '已复制');
} catch (error) {
this.setActionError('复制失败');
}
},
deleteMessages(messages) {
const conversation = this.activeConversation;
if (!conversation || !messages.length) {
return;
}
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.hideMessages(conversation, messages);
this.removeMessages(conversation.id, messages);
if (!this.selectedMessageIds.length) {
this.selectionMode = false;
}
this.setActionNotice(messages.length > 1 ? '已删除所选消息' : '已删除');
},
toggleFavorite(message) {
const key = messageStableKey(message);
if (!key) {
return;
}
const index = this.favoriteMessages.findIndex(item => item.key === key);
if (index >= 0) {
this.favoriteMessages.splice(index, 1);
if (this.activeFavoriteKey === key) {
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
}
this.setActionNotice('已取消收藏');
} else {
const conversation = this.conversations.find(item => item.id === message.conversationId) || {};
this.favoriteMessages.unshift({
key,
id: message.id,
messageUid: message.messageUid,
conversationId: message.conversationId,
conversationTitle: conversation.title || message.conversationTitle || '',
type: message.type || 'text',
text: message.text || '',
preview: messagePreviewText(message),
senderName: message.senderName || message.from || '',
timestamp: Number(message.displayTimestamp || message.timestamp || Date.now()),
editedAt: Number(message.editedAt || 0),
recalled: isRecalledMessage(message),
recallStatus: message.recallStatus || (isRecalledMessage(message) ? '已撤回' : ''),
attachment: message.attachment ? {
...message.attachment
} : null
});
this.activeFavoriteKey = key;
this.setActionNotice('已收藏');
}
this.favoriteMessages = this.favoriteMessages.slice(0, 200);
writeFavoriteMessages(this.favoriteMessages);
},
async togglePinnedMessage(message) {
const conversationId = message?.conversationId || this.activeId;
const key = messageStableKey(message);
if (!conversationId || !key) return;
const current = this.pinnedMessagesByConversation[conversationId];
const next = {
...this.pinnedMessagesByConversation
};
if (current && current.key === key) {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, '').catch(error => this.setActionError(error.message || '取消置顶失败'));
delete next[conversationId];
this.setActionNotice('已取消置顶');
} else {
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, key);
} catch (error) {
this.setActionError(error.message || '置顶失败');
return;
}
next[conversationId] = {
key,
id: key,
text: messagePreviewText(message),
type: message.type || 'text',
attachment: message.attachment ? {
...message.attachment
} : null,
senderName: message.senderName || message.from || '',
timestamp: Number(message.displayTimestamp || message.timestamp || Date.now())
};
this.setActionNotice('消息已置顶');
}
this.pinnedMessagesByConversation = next;
writePinnedMessages(next);
},
async clearPinnedMessage() {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, '').catch(error => this.setActionError(error.message || '取消置顶失败'));
const next = {
...this.pinnedMessagesByConversation
};
delete next[this.activeId];
this.pinnedMessagesByConversation = next;
writePinnedMessages(next);
this.setActionNotice('已取消置顶');
},
setActiveFavorite(key) {
this.activeFavoriteKey = String(key || '');
},
removeFavorite(key) {
const value = String(key || '');
if (!value) {
return;
}
this.favoriteMessages = this.favoriteMessages.filter(message => message.key !== value);
if (this.activeFavoriteKey === value) {
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
}
writeFavoriteMessages(this.favoriteMessages);
},
quoteMessage(message) {
this.quotedMessage = {
...message,
quoteText: quotePrefix(message)
};
this.setActionNotice('已引用,输入后发送');
},
cancelQuote() {
this.quotedMessage = null;
},
enterSelectionMode(message = null) {
this.selectionMode = true;
if (message) {
const key = messageStableKey(message);
this.selectedMessageIds = key ? [key] : [];
}
},
toggleSelectedMessage(message) {
const key = messageStableKey(message);
if (!key) {
return;
}
const selected = new Set(this.selectedMessageIds);
if (selected.has(key)) {
selected.delete(key);
} else {
selected.add(key);
}
this.selectedMessageIds = Array.from(selected);
this.selectionMode = this.selectedMessageIds.length > 0;
},
clearSelection() {
this.selectionMode = false;
this.selectedMessageIds = [];
},
copySelectedMessages() {
return this.copyMessages(this.selectedMessages);
},
deleteSelectedMessages() {
this.deleteMessages(this.selectedMessages);
},
startForward(messages) {
this.forwardingMessages = messages.filter(message => message?.text || message?.attachment?.url);
if (!this.forwardingMessages.length) {
this.setActionError('没有可转发的消息');
}
},
startForwardSelectedMessages() {
this.startForward(this.selectedMessages);
},
cancelForward() {
this.forwardingMessages = [];
},
startEditMessage(message) {
const isResend = isRecalledMessage(message);
if (!isResend && !message?.text) {
this.setActionError('没有可编辑的文字内容');
return;
}
this.editingMessage = message;
this.editingText = message.text || '';
this.editingMode = isResend ? 'resend' : 'edit';
},
cancelEditMessage() {
this.editingMessage = null;
this.editingText = '';
this.editingMode = '';
},
async completeEditMessage() {
const conversation = this.activeConversation;
const message = this.editingMessage;
const text = this.editingText.trim();
const isResend = this.editingMode === 'resend' || isRecalledMessage(message);
if (!conversation || !message) {
this.cancelEditMessage();
return;
}
if (!text) {
this.setActionError('编辑内容不能为空');
return;
}
if (!isResend && text === String(message.text || '').trim()) {
this.cancelEditMessage();
return;
}
try {
if (isResend) {
await this.sendTextToConversation(conversation, text);
this.cancelEditMessage();
this.setActionNotice('已重新发送');
return;
}
const editedMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.editMessage(conversation, message, text);
this.replaceLocalMessage(conversation.id, message, editedMessage);
if (messageActivityTimestamp(editedMessage) >= Number(conversation.updatedAt || 0)) {
conversation.subtitle = editedMessage.text;
conversation.updatedAt = messageActivityTimestamp(editedMessage);
writeLocalConversations(this.conversations);
}
this.cancelEditMessage();
this.setActionNotice('已编辑');
} catch (error) {
this.setActionError(error.message || '编辑失败');
}
},
async completeForward(targetConversationId) {
const target = this.conversations.find(conversation => conversation.id === targetConversationId);
if (!target || !this.forwardingMessages.length) {
return;
}
try {
for (const message of this.forwardingMessages) {
if (message.attachment?.url) {
const response = await fetch((0,_services_mediaProxy__WEBPACK_IMPORTED_MODULE_24__/* .imageDisplayUrl */ .B)(message.attachment.url));
if (!response.ok) throw new Error('图片读取失败');
const blob = await response.blob();
const type = message.attachment.type || message.type || 'file';
const file = new File([blob], message.attachment.name || (type === 'image' ? '转发图片.jpg' : '转发文件'), {
type: message.attachment.mime || blob.type || 'application/octet-stream'
});
const sent = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendAttachmentMessage(target, {
type,
file,
text: message.text || ''
});
if (sent?.status === 'failed') throw new Error(sent.error || '转发失败');
} else if (message.text) {
await this.sendTextToConversation(target, message.text);
}
}
this.forwardingMessages = [];
this.clearSelection();
this.setActionNotice('已转发');
} catch (error) {
this.setActionError(error.message || '转发失败');
}
},
async recallMessage(message) {
const conversation = this.activeConversation;
if (!conversation) {
return;
}
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.recallMessage(conversation, message);
if (message.direction !== 'out') {
this.removeMessages(conversation.id, [message]);
this.setActionNotice('已撤回');
this.syncActiveMessages();
return;
}
this.replaceLocalMessage(conversation.id, message, {
status: 'recalled',
deliveryStatus: '',
recalled: true,
recallStatus: '已撤回'
});
this.setActionNotice('已撤回');
} catch (error) {
this.setActionError(error.message || '撤回失败');
}
},
async createGroup(options = {}) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
if (!session.userId) {
this.setActionError('请先登录');
return false;
}
try {
const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.createGroup(session.userId, options);
this.upsertConversation(conversation);
this.setActiveConversation(conversation.id);
this.setActionNotice(options.channel ? '公告群已创建' : '群组已创建');
this.refreshRemoteConversations();
return true;
} catch (error) {
this.setActionError(error.message || (options.channel ? '创建公告群失败' : '创建群组失败'));
return false;
}
},
async joinGroup(groupKey) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
if (!session.userId) {
this.setActionError('请先登录');
return false;
}
try {
const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.joinGroup(session.userId, groupKey);
this.upsertConversation(conversation);
this.setActiveConversation(conversation.id);
this.setActionNotice('已加入群组');
this.refreshRemoteConversations();
return true;
} catch (error) {
this.setActionError(error.message || '加入群组失败');
return false;
}
},
async broadcastMessage(targetIds, text) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
if (!session.userId) {
this.setActionError('请先登录');
return false;
}
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.broadcastMessage(session.userId, targetIds, text);
const successCount = Number(result.successCount || 0);
const failedCount = Number(result.failedCount || 0);
this.setActionNotice(failedCount > 0 ? `已群发 ${successCount} 条,失败 ${failedCount} 条` : `已群发 ${successCount} 条`);
this.refreshRemoteConversations();
return true;
} catch (error) {
this.setActionError(error.message || '群发失败');
return false;
}
},
async leaveGroup(conversation) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
if (!session.userId || !conversation?.target) {
this.setActionError('缺少群组信息');
return false;
}
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.leaveGroup(session.userId, conversation.target);
this.removeConversation(conversation.id);
this.setActionNotice('已退出群组');
this.refreshRemoteConversations();
return true;
} catch (error) {
this.setActionError(error.message || '退出群组失败');
return false;
}
},
async dismissGroup(conversation) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
if (!session.userId || !conversation?.target) {
this.setActionError('缺少群组信息');
return false;
}
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.dismissGroup(session.userId, conversation.target);
this.removeConversation(conversation.id);
this.setActionNotice('群组已解散');
this.refreshRemoteConversations();
return true;
} catch (error) {
this.setActionError(error.message || '解散群组失败');
return false;
}
}
}
});
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "w", 0, /* binding */ useConversationStore
/* harmony export */ ]);
/***/ }),
/***/ 1414:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2261);
const useNavigationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_0__/* .defineStore */ .nY)('navigation', {
state: () => ({
section: 'messages'
}),
actions: {
showMessages() {
this.section = 'messages';
},
showContacts() {
this.section = 'contacts';
},
showFavorites() {
this.section = 'favorites';
}
}
});
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "l", 0, /* binding */ useNavigationStore
/* harmony export */ ]);
/***/ }),
/***/ 926:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5051);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2169);
const STORAGE_KEY = 'qmt-web-im-session';
function normalizeStoredPortrait(portrait) {
return portrait || '';
}
function nextProfilePortrait(profilePortrait, currentPortrait) {
return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);
}
function inferAccountType(account) {
return String(account || '').includes('@') ? 2 : 1;
}
const useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .defineStore */ .nY)('session', {
state: () => ({
isAuthenticated: false,
connecting: false,
connected: false,
connectionStatusText: '未连接',
userId: '',
token: '',
displayName: '',
portrait: '',
error: '',
sdkVersion: '',
eventsBound: false
}),
actions: {
restore() {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) {
return;
}
try {
const session = JSON.parse(raw);
if (session.appServer !== _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer) {
localStorage.removeItem(STORAGE_KEY);
return;
}
if (session.userId && session.token) {
if (!session.clientId) {
localStorage.removeItem(STORAGE_KEY);
return;
}
this.userId = session.userId;
this.token = session.token;
this.displayName = session.displayName || session.userId;
this.portrait = normalizeStoredPortrait(session.portrait);
this.isAuthenticated = true;
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.restoreClientId(session.clientId);
this.connect();
this.refreshProfile();
}
} catch (error) {
localStorage.removeItem(STORAGE_KEY);
}
},
async loginWithPassword(account, password, type = inferAccountType(account)) {
this.error = '';
this.connecting = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithPassword(account, password, type);
this.applyLoginResult(result);
await this.connect();
} catch (error) {
this.error = error.message || '登录失败';
} finally {
this.connecting = false;
}
},
async loginWithCode(account, code) {
this.error = '';
this.connecting = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithCode(account, code);
this.applyLoginResult(result);
await this.connect();
} catch (error) {
this.error = error.message || '登录失败';
} finally {
this.connecting = false;
}
},
async completePcSessionLogin(result) {
this.error = '';
this.connecting = true;
try {
this.applyLoginResult(result);
await this.connect();
} catch (error) {
this.error = error.message || '扫码登录失败';
} finally {
this.connecting = false;
}
},
async register(payload) {
this.error = '';
this.connecting = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.register(payload);
this.applyLoginResult(result);
await this.connect();
return result;
} catch (error) {
this.error = error.message || '注册失败';
return null;
} finally {
this.connecting = false;
}
},
applyLoginResult(result) {
this.userId = result.userId || result.uid || result.id || '';
this.token = result.token || result.imToken || '';
this.displayName = result.displayName || result.userName || result.name || this.userId;
this.portrait = normalizeStoredPortrait(result.portrait);
this.isAuthenticated = Boolean(this.userId && this.token);
this.persistSession();
},
persistSession() {
localStorage.setItem(STORAGE_KEY, JSON.stringify({
userId: this.userId,
token: this.token,
displayName: this.displayName,
portrait: this.portrait,
clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getClientId(),
appServer: _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer
}));
},
applyProfile(profile) {
if (!profile) {
return;
}
this.userId = profile.userId || profile.uid || this.userId;
this.displayName = profile.displayName || profile.name || this.displayName || this.userId;
this.portrait = nextProfilePortrait(profile.portrait, this.portrait);
this.persistSession();
},
async refreshProfile() {
if (!this.userId) {
return null;
}
try {
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getProfile(this.userId);
this.applyProfile(profile);
return profile;
} catch (error) {
return null;
}
},
async saveProfile({
displayName,
portraitFile
}) {
if (!this.userId) {
throw new Error('请先登录');
}
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.updateProfile(this.userId, {
displayName,
portraitFile
});
this.applyProfile(profile);
return profile;
},
async changePassword({
oldPassword,
newPassword
}) {
if (!this.userId) {
throw new Error('请先登录');
}
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.changePassword({
oldPassword,
newPassword
});
await this.logout();
return true;
},
async resetPasswordWithCode({
mobile,
resetCode,
newPassword
}) {
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.resetPasswordWithCode({
mobile,
resetCode,
newPassword
});
return true;
},
async connect() {
if (!this.userId || !this.token) {
return;
}
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.ensureSdk();
this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getSdkVersion();
this.bindImEvents();
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.connect(this.userId, this.token);
},
bindImEvents() {
if (this.eventsBound) {
return;
}
this.eventsBound = true;
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.on('connectionStatusChanged', status => {
this.connected = status.connected;
this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');
});
},
async logout() {
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.logout?.();
} catch (error) {
this.error = error.message || '退出登录失败';
} finally {
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.disconnect();
localStorage.removeItem(STORAGE_KEY);
this.$reset();
}
}
}
});
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
/* harmony export */ "B", 0, /* binding */ useSessionStore
/* harmony export */ ]);
/***/ }),
/***/ 7067:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4208);
const __exports__ = _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 9531:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6736);
const __exports__ = _ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 3727:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4524);
const __exports__ = _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 7014:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9843);
const __exports__ = _ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 1653:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5990);
const __exports__ = _MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 9847:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3172);
const __exports__ = _MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 3351:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9828);
const __exports__ = _ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 163:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1880);
const __exports__ = _FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 9123:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8040);
const __exports__ = _FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 578:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(103);
const __exports__ = _ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 371:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5896);
const __exports__ = _ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 8328:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony import */ var _NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1169);
const __exports__ = _NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
/* harmony default export */ __webpack_exports__.A = (__exports__);
/***/ }),
/***/ 4208:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4677);
/***/ }),
/***/ 6736:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2511);
/***/ }),
/***/ 4524:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8607);
/***/ }),
/***/ 9843:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7562);
/***/ }),
/***/ 5990:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6935);
/***/ }),
/***/ 3172:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4021);
/***/ }),
/***/ 9828:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3915);
/***/ }),
/***/ 1880:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9829);
/***/ }),
/***/ 8040:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6415);
/***/ }),
/***/ 103:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5684);
/***/ }),
/***/ 5896:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4621);
/***/ }),
/***/ 1169:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
/* harmony export */ });
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7420);
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/chunk loaded */
/******/ !function() {
/******/ var deferred = [];
/******/ __webpack_require__.O = function(result, chunkIds, fn, priority) {
/******/ if(chunkIds) {
/******/ priority = priority || 0;
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
/******/ deferred[i] = [chunkIds, fn, priority];
/******/ return;
/******/ }
/******/ var notFulfilled = Infinity;
/******/ for (var i = 0; i < deferred.length; i++) {
/******/ var chunkIds = deferred[i][0];
/******/ var fn = deferred[i][1];
/******/ var priority = deferred[i][2];
/******/ var fulfilled = true;
/******/ for (var j = 0; j < chunkIds.length; j++) {
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {
/******/ chunkIds.splice(j--, 1);
/******/ } else {
/******/ fulfilled = false;
/******/ if(priority < notFulfilled) notFulfilled = priority;
/******/ }
/******/ }
/******/ if(fulfilled) {
/******/ deferred.splice(i--, 1)
/******/ var r = fn();
/******/ if (r !== undefined) result = r;
/******/ }
/******/ }
/******/ return result;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter/value functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ if(Array.isArray(definition)) {
/******/ var i = 0;
/******/ while(i < definition.length) {
/******/ var key = definition[i++];
/******/ var binding = definition[i++];
/******/ if(!__webpack_require__.o(exports, key)) {
/******/ if(binding === 0) {
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
/******/ } else {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
/******/ }
/******/ } else if(binding === 0) { i++; }
/******/ }
/******/ } else {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/global */
/******/ !function() {
/******/ __webpack_require__.g = (function() {
/******/ if (typeof globalThis === 'object') return globalThis;
/******/ try {
/******/ return this || new Function('return this')();
/******/ } catch (e) {
/******/ if (typeof window === 'object') return window;
/******/ }
/******/ })();
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/set anonymous default export name */
/******/ !function() {
/******/ // set .name for anonymous default exports per ES spec
/******/ __webpack_require__.dn = function(x) {
/******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ !function() {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ 524: 0
/******/ };
/******/
/******/ // no chunk on demand loading
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/
/******/ __webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = function(parentChunkLoadingFunction, data) {
/******/ var chunkIds = data[0];
/******/ var moreModules = data[1];
/******/ var runtime = data[2];
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ return __webpack_require__.O(result);
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkjc_web_im"] = self["webpackChunkjc_web_im"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ }();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(1406); })
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/
/******/ })()
;
//# sourceMappingURL=app.1158390e.js.map