/******/ (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 import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7566);
/* harmony default export */ __webpack_exports__.A = ({
__name: 'App',
setup(__props) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)();
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_5__/* .useConversationStore */ .w)();
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
session.restore();
});
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .watch */ .wB)(() => session.userId, userId => {
if (userId && session.isAuthenticated) {
conversations.bootstrapDemoData();
return;
}
conversations.clearUserState();
});
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_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_some_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3579);
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_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 axios__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2387);
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2789);
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2169);
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(926);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_10__ = __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"
};
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 = {
key: 0
};
const _hoisted_15 = {
key: 1
};
const _hoisted_16 = {
class: "code-row"
};
const _hoisted_17 = ["disabled"];
const _hoisted_18 = ["disabled"];
const _hoisted_19 = {
key: 2,
class: "form-error"
};
const _hoisted_20 = {
key: 3,
class: "form-info"
};
const _hoisted_21 = ["onClick"];
const _hoisted_22 = {
key: 0
};
const _hoisted_23 = {
class: "label-row"
};
const _hoisted_24 = {
key: 0,
class: "field-error-badge"
};
const _hoisted_25 = {
class: "phone-row"
};
const _hoisted_26 = {
class: "country-code-field"
};
const _hoisted_27 = {
key: 1
};
const _hoisted_28 = {
key: 0,
class: "code-row"
};
const _hoisted_29 = ["disabled"];
const _hoisted_30 = {
key: 1,
class: "captcha-row"
};
const _hoisted_31 = ["src"];
const _hoisted_32 = (/* unused pure expression or super */ null && ({
key: 2
}));
const _hoisted_33 = (/* unused pure expression or super */ null && ({
key: 3
}));
const _hoisted_34 = (/* unused pure expression or super */ null && ({
class: "code-row"
}));
const _hoisted_35 = {
key: 4
};
const _hoisted_36 = {
key: 5
};
const _hoisted_37 = {
class: "phone-row"
};
const _hoisted_38 = ["value"];
const _hoisted_39 = {
key: 6
};
const _hoisted_40 = {
class: "captcha-row"
};
const _hoisted_41 = ["src"];
const _hoisted_42 = {
key: 7
};
const _hoisted_43 = {
key: 8
};
const _hoisted_44 = ["disabled"];
const _hoisted_45 = {
key: 9,
class: "form-error"
};
const _hoisted_46 = {
key: 10,
class: "form-info"
};
const _hoisted_47 = ["value"];
const _hoisted_48 = ["disabled"];
const _hoisted_49 = {
key: 0,
class: "form-error"
};
const _hoisted_50 = {
key: 1,
class: "form-info"
};
const QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/';
const pendingRegistrationStorageKey = 'qmt-web-im-pending-registration';
const defaultPlatformLogo = '/img/5IuOieu9PF8MJtp43kD2kCkdLVjVwDp7.ico';
const emailRegisterEnabled = false;
/* harmony default export */ __webpack_exports__.A = ({
__name: 'LoginView',
setup(__props) {
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_9__/* .useSessionStore */ .B)();
const view = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('login');
const mode = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('qr');
const mobile = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const password = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const code = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('66666');
const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const info = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('idle');
const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const qrPolling = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
let qrGeneration = 0;
let qrExpireTimer = null;
const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_8__/* .appConfig */ .U.appName;
const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(defaultPlatformName);
const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(defaultPlatformLogo);
const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('phone');
const registerMethods = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)({
phone: true,
email: false,
username: false
});
const mobileRealVerify = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const registerPhoneError = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const phoneCaptcha = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const phoneCaptchaImage = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const usernameCaptcha = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const usernameCaptchaImage = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
const settingRegisterPassword = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
const pendingRegistration = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
mobile: '',
result: null,
resetCode: ''
});
const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
phoneCountryCode: '86',
phone: '',
code: '',
email: '',
emailCode: '',
username: '',
usernamePhoneCountryCode: '+86',
usernamePhone: '',
usernameCode: '',
password: '',
confirmPassword: ''
});
const registerPasswordForm = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
password: '',
confirmPassword: ''
});
const countryCodeOptions = [{
value: '+86',
label: '+86'
}, {
value: '+852',
label: '+852'
}, {
value: '+853',
label: '+853'
}, {
value: '+886',
label: '+886'
}, {
value: '+1',
label: '+1'
}, {
value: '+44',
label: '+44'
}, {
value: '+60',
label: '+60'
}, {
value: '+63',
label: '+63'
}, {
value: '+65',
label: '+65'
}, {
value: '+66',
label: '+66'
}, {
value: '+81',
label: '+81'
}, {
value: '+82',
label: '+82'
}];
const registerMethodOptions = [{
key: 'phone',
label: '手机号注册'
}, {
key: 'email',
label: '邮箱注册'
}, {
key: 'username',
label: '用户名注册'
}];
const canSubmit = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
if (mode.value === 'password') {
return mobile.value.length >= 5 && password.value.length >= 1;
}
return mobile.value.length >= 5 && code.value.length >= 1;
});
const visibleRegisterMethods = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
const enabled = registerMethodOptions.filter(item => item.key !== 'email' && registerMethods.value[item.key]);
return enabled.length ? enabled : [registerMethodOptions[0]];
});
const canRegisterSubmit = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
if (registerType.value === 'phone') {
return registerForm.phone.length >= 5 && (mobileRealVerify.value ? registerForm.code.length >= 1 : phoneCaptchaMatched.value);
}
if (registerType.value === 'email') {
return false;
}
return registerForm.username.length >= 3 && registerForm.usernamePhone.length >= 5 && usernameCaptchaMatched.value && registerForm.password.length >= 1 && registerForm.password === registerForm.confirmPassword;
});
const canSetRegisterPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
return pendingRegistration.mobile && pendingRegistration.resetCode && registerPasswordForm.password.length >= 1 && registerPasswordForm.password === registerPasswordForm.confirmPassword;
});
const phoneCaptchaStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => getCaptchaStatus(registerForm.code, phoneCaptcha.value));
const phoneCaptchaMatched = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => phoneCaptchaStatus.value === 'valid');
const phoneCaptchaClass = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => getCaptchaClass(phoneCaptchaStatus.value));
const usernameCaptchaStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
return getCaptchaStatus(registerForm.usernameCode, usernameCaptcha.value);
});
const usernameCaptchaMatched = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => usernameCaptchaStatus.value === 'valid');
const usernameCaptchaClass = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => getCaptchaClass(usernameCaptchaStatus.value));
const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => {
return String(qrUserName.value || '用').slice(0, 1).toUpperCase();
});
const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .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_3__/* .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_3__/* .computed */ .EW)(() => {
if (qrStatus.value === 'loading') {
return '生成中...';
}
if (qrStatus.value === 'expired' || qrStatus.value === 'error') {
return '重新生成二维码';
}
return '刷新二维码';
});
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .watch */ .wB)(visibleRegisterMethods, methods => {
if (!methods.some(item => item.key === registerType.value)) {
registerType.value = methods[0]?.key || 'phone';
}
});
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onMounted */ .sV)(() => {
loadPlatformConfig();
loadRegisterConfig();
restorePendingRegistration();
if (view.value === 'login' && mode.value === 'qr') {
startQrLogin();
}
});
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onBeforeUnmount */ .xo)(() => {
stopQrLogin();
});
async function requestCode() {
info.value = '';
sendingCode.value = true;
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_10__/* .imClient */ .wD.requestAuthCode(mobile.value);
info.value = '验证码已发送;本地测试也可以直接使用 66666';
} catch (error) {
session.error = error.message || '验证码发送失败';
} finally {
sendingCode.value = false;
}
}
async function requestRegisterCode() {
info.value = '';
sendingCode.value = true;
try {
await _services_imClient__WEBPACK_IMPORTED_MODULE_10__/* .imClient */ .wD.requestAuthCode(formatPhoneForApi(registerForm.phoneCountryCode, registerForm.phone));
info.value = '验证码已发送;本地测试也可以直接使用 66666';
} catch (error) {
session.error = error.message || '验证码发送失败';
} finally {
sendingCode.value = false;
}
}
function submit() {
if (mode.value === 'qr') {
return;
}
if (mode.value === 'password') {
session.loginWithPassword(mobile.value, password.value);
return;
}
session.loginWithCode(mobile.value, code.value);
}
function setLoginMode(nextMode) {
session.error = '';
info.value = '';
mode.value = nextMode;
if (nextMode === 'qr') {
startQrLogin();
return;
}
stopQrLogin();
}
function resetQrState() {
qrStatus.value = 'idle';
qrCodeImage.value = '';
qrSessionToken.value = '';
qrUserName.value = '';
qrUserPortrait.value = '';
qrPolling.value = false;
}
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 (mode.value !== 'qr') {
return;
}
if (!force && qrSessionToken.value && qrCodeImage.value && qrStatus.value !== 'expired' && qrStatus.value !== 'error') {
return;
}
qrGeneration += 1;
const generation = qrGeneration;
clearQrExpireTimer();
session.error = '';
info.value = '';
qrStatus.value = 'loading';
qrCodeImage.value = '';
qrSessionToken.value = '';
qrUserName.value = '';
qrUserPortrait.value = '';
qrPolling.value = false;
try {
const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_10__/* .imClient */ .wD.createPcSession();
if (generation !== qrGeneration || mode.value !== 'qr') {
return;
}
const token = String(pcSession.token || '');
if (!token) {
throw new Error('服务器没有返回扫码登录凭证');
}
qrSessionToken.value = token;
qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_7___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) {
qrPolling.value = true;
try {
while (generation === qrGeneration && mode.value === 'qr' && !session.isAuthenticated) {
const data = await _services_imClient__WEBPACK_IMPORTED_MODULE_10__/* .imClient */ .wD.loginWithPcSession(token);
if (generation !== qrGeneration || mode.value !== 'qr') {
return;
}
const codeValue = Number(data.code);
if (codeValue === 0) {
qrStatus.value = 'confirmed';
clearQrExpireTimer();
await session.completePcSessionLogin(data.result || {});
return;
}
if (codeValue === 9) {
qrStatus.value = 'scanned';
qrUserName.value = data.result?.userName || data.result?.displayName || qrUserName.value;
qrUserPortrait.value = data.result?.portrait || qrUserPortrait.value;
await delay(800);
continue;
}
if (codeValue === 10) {
qrStatus.value = 'waiting';
await delay(1000);
continue;
}
if (codeValue === 18) {
qrStatus.value = 'expired';
session.error = '手机端已取消登录';
return;
}
if (codeValue === 8) {
qrStatus.value = 'expired';
return;
}
throw new Error(data.message || '扫码登录失败');
}
} catch (error) {
if (generation === qrGeneration && mode.value === 'qr' && !session.isAuthenticated) {
qrStatus.value = 'error';
session.error = error.message || '扫码登录失败';
}
} finally {
if (generation === qrGeneration) {
qrPolling.value = false;
}
}
}
function delay(ms) {
return new Promise(resolve => window.setTimeout(resolve, ms));
}
function normalizeUsernameCaptchaInput() {
registerForm.usernameCode = registerForm.usernameCode.replace(/\D/g, '').slice(0, 6);
}
function normalizePhoneCaptchaInput() {
registerForm.code = registerForm.code.replace(/\D/g, '').slice(0, 6);
}
function normalizeRegisterCountryCode() {
registerForm.phoneCountryCode = registerForm.phoneCountryCode.replace(/\D/g, '').slice(0, 6);
}
function showPhoneCaptcha() {
phoneCaptcha.value = randomDigits(6);
phoneCaptchaImage.value = renderCaptchaImage(phoneCaptcha.value);
registerForm.code = '';
}
function showUsernameCaptcha() {
usernameCaptcha.value = randomDigits(6);
usernameCaptchaImage.value = renderCaptchaImage(usernameCaptcha.value);
registerForm.usernameCode = '';
}
function getCaptchaStatus(inputValue, captchaValue) {
if (inputValue.length < 6) {
return '';
}
return captchaValue && inputValue === captchaValue ? 'valid' : 'invalid';
}
function getCaptchaClass(status) {
return {
'captcha-input-valid': status === 'valid',
'captcha-input-invalid': status === 'invalid'
};
}
function randomDigits(length) {
let value = '';
for (let index = 0; index < length; index += 1) {
value += Math.floor(Math.random() * 10);
}
return value;
}
function renderCaptchaImage(text) {
const width = 112;
const height = 42;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const context = canvas.getContext('2d');
context.fillStyle = '#f7fbfa';
context.fillRect(0, 0, width, height);
for (let index = 0; index < 11; index += 1) {
context.beginPath();
context.moveTo(Math.random() * width, Math.random() * height);
context.lineTo(Math.random() * width, Math.random() * height);
context.strokeStyle = `rgba(${25 + Math.random() * 60}, ${55 + Math.random() * 70}, ${55 + Math.random() * 70}, 0.82)`;
context.lineWidth = 1.4;
context.stroke();
}
context.font = '700 23px Arial, sans-serif';
context.textBaseline = 'middle';
context.textAlign = 'center';
for (let index = 0; index < text.length; index += 1) {
context.fillStyle = index % 2 === 0 ? '#153f3b' : '#1b6760';
context.fillText(text[index], 14 + index * 17, height / 2 + 1);
}
for (let index = 0; index < 70; index += 1) {
context.fillStyle = `rgba(20, 70, 65, ${0.12 + Math.random() * 0.2})`;
context.fillRect(Math.random() * width, Math.random() * height, 1.2, 1.2);
}
return canvas.toDataURL('image/png');
}
async function submitRegister() {
session.error = '';
info.value = '';
if (registerType.value === 'phone') {
clearRegisterPhoneError();
if (!mobileRealVerify.value && !phoneCaptchaMatched.value) {
session.error = '请输入正确的验证码';
return;
}
const formattedPhone = formatPhoneForApi(registerForm.phoneCountryCode, registerForm.phone);
const phoneExists = await isRegisterPhoneExists(formattedPhone);
if (phoneExists === null) {
return;
}
if (phoneExists) {
registerPhoneError.value = '该手机号已经注册过';
return;
}
const loginCode = mobileRealVerify.value ? registerForm.code : '66666';
const result = await session.registerWithPhone(formattedPhone, loginCode);
if (!result) {
return;
}
if (!result.resetCode) {
session.error = '注册成功,但没有收到设置密码凭证';
return;
}
setPendingRegistration(formattedPhone, result);
registerPasswordForm.password = '';
registerPasswordForm.confirmPassword = '';
view.value = 'setPassword';
return;
}
if (registerType.value === 'email') {
session.error = '邮箱注册已暂时关闭,请使用手机号注册';
return;
}
session.error = registerType.value === 'email' ? '邮箱注册接口还未接入,请先使用手机号注册' : '用户名注册接口还未接入,请先使用手机号注册';
}
async function submitRegisterPassword() {
session.error = '';
info.value = '';
if (!pendingRegistration.mobile || !pendingRegistration.resetCode) {
session.error = '注册状态已失效,请重新注册';
return;
}
if (!registerPasswordForm.password || !registerPasswordForm.confirmPassword) {
session.error = '请填写完整密码';
return;
}
if (registerPasswordForm.password !== registerPasswordForm.confirmPassword) {
session.error = '两次输入的密码不一致';
return;
}
settingRegisterPassword.value = true;
try {
await session.resetPasswordWithCode({
mobile: pendingRegistration.mobile,
resetCode: pendingRegistration.resetCode,
newPassword: registerPasswordForm.password
});
await session.loginWithPassword(pendingRegistration.mobile, registerPasswordForm.password);
if (!session.error) {
clearPendingRegistration();
}
} catch (error) {
session.error = error.message || '密码设置失败';
} finally {
settingRegisterPassword.value = false;
}
}
function formatPhoneForApi(countryCode, phone) {
const digits = String(countryCode || '86').replace(/\D/g, '') || '86';
const normalizedCode = `+${digits}`;
const normalizedPhone = String(phone || '').replace(/\s/g, '');
if (normalizedCode === '+86') {
return normalizedPhone;
}
return `${normalizedCode}${normalizedPhone}`;
}
async function loadRegisterConfig() {
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_8__/* .appConfig */ .U.registerConfigApi, {
withCredentials: false
});
const methods = response.data?.data?.methods;
if (methods) {
registerMethods.value = {
phone: Boolean(methods.phone),
email: false && 0,
username: Boolean(methods.username)
};
}
mobileRealVerify.value = Boolean(response.data?.data?.mobile_real_verify);
} catch (error) {
registerMethods.value = {
phone: true,
email: false,
username: false
};
mobileRealVerify.value = false;
}
}
async function loadPlatformConfig() {
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_8__/* .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_8__/* .appConfig */ .U.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_8__/* .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;
const iconUrl = platformLogo.value || defaultPlatformLogo;
setDocumentIcon('icon', iconUrl);
setDocumentIcon('shortcut icon', iconUrl);
setDocumentIcon('apple-touch-icon', iconUrl);
}
function setDocumentIcon(rel, href) {
let icon = document.querySelector(`link[rel="${rel}"]`);
if (!icon) {
icon = document.createElement('link');
icon.setAttribute('rel', rel);
document.head.appendChild(icon);
}
icon.setAttribute('href', href);
}
function handleBrandLogoError() {
if (platformLogo.value !== defaultPlatformLogo) {
platformLogo.value = defaultPlatformLogo;
applyDocumentBrand();
}
}
async function isRegisterPhoneExists(phone) {
try {
const response = await axios__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_8__/* .appConfig */ .U.registerPhoneExistsApi, {
mobile: phone
}, {
withCredentials: false
});
return Boolean(response.data?.data?.exists);
} catch (error) {
session.error = error.response?.data?.msg || error.message || '手机号检查失败,请稍后重试';
return null;
}
}
function clearRegisterPhoneError() {
registerPhoneError.value = '';
}
function clearPendingRegistration() {
pendingRegistration.mobile = '';
pendingRegistration.result = null;
pendingRegistration.resetCode = '';
registerPasswordForm.password = '';
registerPasswordForm.confirmPassword = '';
sessionStorage.removeItem(pendingRegistrationStorageKey);
}
function setPendingRegistration(phone, result) {
pendingRegistration.mobile = phone;
pendingRegistration.result = result;
pendingRegistration.resetCode = String(result.resetCode || '');
sessionStorage.setItem(pendingRegistrationStorageKey, JSON.stringify({
appServer: _config__WEBPACK_IMPORTED_MODULE_8__/* .appConfig */ .U.appServer,
mobile: pendingRegistration.mobile,
resetCode: pendingRegistration.resetCode,
result
}));
}
function restorePendingRegistration() {
try {
const pending = JSON.parse(sessionStorage.getItem(pendingRegistrationStorageKey) || 'null');
if (!pending || pending.appServer !== _config__WEBPACK_IMPORTED_MODULE_8__/* .appConfig */ .U.appServer || !pending.mobile || !pending.resetCode) {
return;
}
pendingRegistration.mobile = pending.mobile;
pendingRegistration.result = pending.result || null;
pendingRegistration.resetCode = String(pending.resetCode || '');
registerPasswordForm.password = '';
registerPasswordForm.confirmPassword = '';
view.value = 'setPassword';
} catch (error) {
sessionStorage.removeItem(pendingRegistrationStorageKey);
}
}
function openRegister() {
session.error = '';
info.value = '';
stopQrLogin();
clearRegisterPhoneError();
clearPendingRegistration();
registerForm.phone = registerForm.phone || mobile.value;
registerForm.code = '';
phoneCaptcha.value = '';
phoneCaptchaImage.value = '';
view.value = 'register';
loadRegisterConfig();
}
function backToLogin() {
session.error = '';
info.value = '';
clearRegisterPhoneError();
clearPendingRegistration();
mode.value = 'qr';
view.value = 'login';
startQrLogin();
}
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("img", {
class: "brand-mark",
src: platformLogo.value,
alt: `${platformName.value} 图标`,
onError: handleBrandLogoError
}, null, 40, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("h1", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(platformName.value), 1), _cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("p", null, "连接既有授权 IM 服务的新版 Web 客户端", -1))])]), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("form", {
key: 0,
class: "login-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(submit, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
active: mode.value === 'qr'
}),
onClick: _cache[0] || (_cache[0] = $event => setLoginMode('qr'))
}, "扫码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
active: mode.value === 'password'
}),
onClick: _cache[1] || (_cache[1] = $event => setLoginMode('password'))
}, "密码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
active: mode.value === 'code'
}),
onClick: _cache[2] || (_cache[2] = $event => setLoginMode('code'))
}, "验证码登录", 2)]), mode.value === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, {
key: 0
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["qr-login-card", {
scanned: qrStatus.value === 'scanned',
expired: qrStatus.value === 'expired',
error: qrStatus.value === 'error'
}])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "qr-code-button",
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting,
onClick: refreshQrLogin
}, [qrCodeImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
key: 0,
src: qrCodeImage.value,
alt: "手机扫码登录二维码"
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(qrStatus.value === 'loading' ? '生成中' : '点击刷新'), 1))], 8, _hoisted_6), qrStatus.value === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", _hoisted_9, [qrUserPortrait.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
key: 0,
src: qrUserPortrait.value,
alt: ""
}, null, 8, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(qrUserInitial.value), 1))])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(qrStatusTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(qrStatusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-action",
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting,
onClick: refreshQrLogin
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(qrRefreshText.value), 9, _hoisted_13)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, {
key: 1
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[21] || (_cache[21] = (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 => mobile.value = $event),
autocomplete: "username",
inputmode: "tel",
placeholder: "请输入手机号"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, mobile.value, void 0, {
trim: true
}]])]), mode.value === 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_14, [_cache[22] || (_cache[22] = (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 => password.value = $event),
autocomplete: "current-password",
type: "password",
placeholder: "请输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, password.value]])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_15, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_16, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => code.value = $event),
autocomplete: "one-time-code",
inputmode: "numeric",
placeholder: "本地测试请输入 66666"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, code.value, void 0, {
trim: true
}]]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "code-action",
disabled: sendingCode.value || mobile.value.length < 5,
onClick: requestCode
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_17)])])), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "primary-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting || !canSubmit.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting ? '登录中...' : '登录'), 9, _hoisted_18)], 64)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_20, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 32)) : view.value === 'register' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("form", {
key: 1,
class: "login-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(submitRegister, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
class: "login-tabs register-tabs",
style: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeStyle */ .Tr)({
gridTemplateColumns: `repeat(${visibleRegisterMethods.value.length || 1}, minmax(0, 1fr))`
})
}, [((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .renderList */ .pI)(visibleRegisterMethods.value, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: item.key,
type: "button",
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
active: registerType.value === item.key
}),
onClick: $event => registerType.value = item.key
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(item.label), 11, _hoisted_21);
}), 128))], 4), registerType.value === 'phone' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_22, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", _hoisted_23, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "手机号", -1)), registerPhoneError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(registerPhoneError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_26, [_cache[25] || (_cache[25] = (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[6] || (_cache[6] = $event => registerForm.phoneCountryCode = $event),
"aria-label": "手机号国码",
autocomplete: "tel-country-code",
inputmode: "numeric",
maxlength: "6",
onInput: normalizeRegisterCountryCode
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.phoneCountryCode, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[7] || (_cache[7] = $event => registerForm.phone = $event),
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
'field-input-error': registerPhoneError.value
}),
autocomplete: "tel",
inputmode: "tel",
placeholder: "请输入手机号",
onInput: clearRegisterPhoneError
}, null, 34), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.phone, void 0, {
trim: true
}]])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'phone' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_27, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "验证码", -1)), mobileRealVerify.value ? ((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__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .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_2__/* .vModelText */ .Jo, registerForm.code, void 0, {
trim: true
}]]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "code-action",
disabled: sendingCode.value || registerForm.phone.length < 5,
onClick: requestRegisterCode
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_29)])) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", _hoisted_30, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => registerForm.code = $event),
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(phoneCaptchaClass.value),
autocomplete: "off",
inputmode: "numeric",
maxlength: "6",
placeholder: "请输入验证码",
onInput: normalizePhoneCaptchaInput
}, null, 34), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.code, void 0, {
trim: true
}]]), !phoneCaptchaImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "code-action",
onClick: showPhoneCaptcha
}, " 发送验证码 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "captcha-button",
title: "点击更换验证码",
onClick: showPhoneCaptcha
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("img", {
src: phoneCaptchaImage.value,
alt: "6位数字验证码"
}, null, 8, _hoisted_31)]))]))])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), false ? (0) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), false ? (0) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'username' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_35, [_cache[30] || (_cache[30] = (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[12] || (_cache[12] = $event => registerForm.username = $event),
autocomplete: "username",
placeholder: "请输入用户名"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.username, void 0, {
trim: true
}]])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'username' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_36, [_cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_37, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("select", {
"onUpdate:modelValue": _cache[13] || (_cache[13] = $event => registerForm.usernamePhoneCountryCode = $event),
"aria-label": "用户名注册手机号国码"
}, [((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)(countryCodeOptions, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("option", {
key: item.value,
value: item.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(item.label), 9, _hoisted_38);
}), 64))], 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelSelect */ .u1, registerForm.usernamePhoneCountryCode]]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[14] || (_cache[14] = $event => registerForm.usernamePhone = $event),
autocomplete: "tel",
inputmode: "tel",
placeholder: "请输入手机号"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.usernamePhone, void 0, {
trim: true
}]])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'username' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_39, [_cache[32] || (_cache[32] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_40, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
"onUpdate:modelValue": _cache[15] || (_cache[15] = $event => registerForm.usernameCode = $event),
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(usernameCaptchaClass.value),
autocomplete: "off",
inputmode: "numeric",
maxlength: "6",
placeholder: "请输入验证码",
onInput: normalizeUsernameCaptchaInput
}, null, 34), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.usernameCode, void 0, {
trim: true
}]]), !usernameCaptchaImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "code-action",
onClick: showUsernameCaptcha
}, " 显示验证码 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "captcha-button",
title: "点击更换验证码",
onClick: showUsernameCaptcha
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("img", {
src: usernameCaptchaImage.value,
alt: "6位数字验证码"
}, null, 8, _hoisted_41)]))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'username' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_42, [_cache[33] || (_cache[33] = (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[16] || (_cache[16] = $event => registerForm.password = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.password]])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), registerType.value === 'username' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("label", _hoisted_43, [_cache[34] || (_cache[34] = (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[17] || (_cache[17] = $event => registerForm.confirmPassword = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请再次输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerForm.confirmPassword]])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "primary-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting || !canRegisterSubmit.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting ? '注册中...' : '注册'), 9, _hoisted_44), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_45, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_46, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("form", {
key: 2,
class: "login-form",
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(submitRegisterPassword, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[35] || (_cache[35] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
value: pendingRegistration.mobile,
autocomplete: "username",
readonly: ""
}, null, 8, _hoisted_47)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[36] || (_cache[36] = (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[18] || (_cache[18] = $event => registerPasswordForm.password = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请输入登录密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerPasswordForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[37] || (_cache[37] = (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[19] || (_cache[19] = $event => registerPasswordForm.confirmPassword = $event),
autocomplete: "new-password",
type: "password",
placeholder: "请再次输入密码"
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, registerPasswordForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
class: "primary-action",
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting || settingRegisterPassword.value || !canSetRegisterPassword.value
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(settingRegisterPassword.value || (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).connecting ? '保存中...' : '保存并进入'), 9, _hoisted_48), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_49, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("p", _hoisted_50, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 32)), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 3,
class: "ghost-action",
type: "button",
onClick: openRegister
}, " 新用户注册 ")) : view.value === 'register' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("button", {
key: 4,
class: "ghost-action",
type: "button",
onClick: backToLogin
}, " 返回登录 ")) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)])]);
};
}
});
/***/ }),
/***/ 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);
const _hoisted_1 = {
class: "chat-panel"
};
const _hoisted_2 = {
class: "chat-header"
};
const _hoisted_3 = ["src"];
const _hoisted_4 = {
key: 1,
class: "chat-title-avatar"
};
const _hoisted_5 = {
class: "chat-title-copy"
};
const _hoisted_6 = ["src"];
const _hoisted_7 = {
key: 1,
class: "chat-title-avatar"
};
const _hoisted_8 = {
class: "chat-title-copy"
};
const _hoisted_9 = {
key: 2
};
const _hoisted_10 = {
class: "header-actions chat-header-actions"
};
const _hoisted_11 = {
key: 0,
class: "empty-chat"
};
const _hoisted_12 = {
key: 2,
class: "selection-toolbar"
};
const _hoisted_13 = {
class: "forward-dialog"
};
const _hoisted_14 = ["onClick"];
const _hoisted_15 = {
class: "conversation-avatar"
};
const _hoisted_16 = {
type: "submit"
};
const _hoisted_17 = {
class: "group-dialog message-detail-dialog"
};
const _hoisted_18 = {
key: 0,
class: "group-loading"
};
const _hoisted_19 = {
class: "group-profile message-detail-meta"
};
const _hoisted_20 = {
key: 0
};
const _hoisted_21 = {
key: 0,
class: "inline-save-status error"
};
const _hoisted_22 = {
class: "message-detail-summary"
};
const _hoisted_23 = {
class: "message-detail-groups"
};
const _hoisted_24 = {
class: "message-detail-section"
};
const _hoisted_25 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_26 = ["src"];
const _hoisted_27 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_28 = {
class: "message-detail-member-main"
};
const _hoisted_29 = {
class: "message-detail-member-time"
};
const _hoisted_30 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_31 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_32 = {
class: "message-detail-section"
};
const _hoisted_33 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_34 = ["src"];
const _hoisted_35 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_36 = {
class: "message-detail-member-main"
};
const _hoisted_37 = {
class: "message-detail-member-time"
};
const _hoisted_38 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_39 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_40 = {
class: "message-detail-section"
};
const _hoisted_41 = {
key: 0,
class: "message-detail-member-list"
};
const _hoisted_42 = ["src"];
const _hoisted_43 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_44 = {
class: "message-detail-member-main"
};
const _hoisted_45 = {
key: 2,
class: "message-detail-role"
};
const _hoisted_46 = {
key: 1,
class: "contact-picker-empty"
};
const _hoisted_47 = {
class: "group-dialog single-profile-dialog"
};
const _hoisted_48 = {
class: "single-profile-summary"
};
const _hoisted_49 = ["src"];
const _hoisted_50 = {
key: 1,
class: "profile-avatar"
};
const _hoisted_51 = {
class: "group-profile"
};
const _hoisted_52 = {
class: "single-profile-footer"
};
const _hoisted_53 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_54 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_55 = ["disabled"];
const _hoisted_56 = ["disabled"];
const _hoisted_57 = {
key: 0,
class: "group-dialog"
};
const _hoisted_58 = {
key: 0,
class: "group-loading"
};
const _hoisted_59 = {
key: 1,
class: "group-profile"
};
const _hoisted_60 = ["disabled"];
const _hoisted_61 = ["disabled"];
const _hoisted_62 = ["disabled"];
const _hoisted_63 = {
key: 1,
class: "group-dialog"
};
const _hoisted_64 = {
key: 0,
class: "group-loading"
};
const _hoisted_65 = {
key: 1,
class: "group-member-list"
};
const _hoisted_66 = ["src"];
const _hoisted_67 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_68 = {
key: 0,
class: "group-member-role"
};
const _hoisted_69 = {
key: 1
};
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 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,
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 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 sortedGroupMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
const roleOrder = {
owner: 0,
admin: 1,
member: 2
};
return groupMembers.value.map((member, index) => ({
member,
index
})).sort((left, right) => {
const leftOrder = roleOrder[left.member.role] ?? 3;
const rightOrder = roleOrder[right.member.role] ?? 3;
return leftOrder - rightOrder || left.index - right.index;
}).map(item => item.member);
});
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", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(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: activeConversation.value.portrait,
alt: ""
}, null, 8, _hoisted_3)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_4, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.avatarText || '?'), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_5, [(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: singleProfile.value.portrait,
alt: ""
}, null, 8, _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_8, [(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_9, "未选择会话")), (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_10, [_cache[29] || (_cache[29] = (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_11, _cache[30] || (_cache[30] = [(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__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createBlock */ .Wv)(_MessageList_vue__WEBPACK_IMPORTED_MODULE_16__/* ["default"] */ .A, {
key: 1,
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,
"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", "attention-message-id", "can-recall-others", "onMessageAction", "onToggleSelect"])), (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_12, [(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[1] || (_cache[1] = (...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[2] || (_cache[2] = (...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[3] || (_cache[3] = (...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[4] || (_cache[4] = (...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: 3,
class: "modal-backdrop",
onClick: _cache[6] || (_cache[6] = (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_13, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[31] || (_cache[31] = (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[5] || (_cache[5] = (...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_15, (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_14);
}), 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: 4,
class: "modal-backdrop",
onClick: _cache[11] || (_cache[11] = (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[10] || (_cache[10] = (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[7] || (_cache[7] = (...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[8] || (_cache[8] = $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[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__/* .createElementVNode */ .Lk)("button", _hoisted_16, (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: 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).closeMessageDetail && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail(...args), ["self"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[32] || (_cache[32] = (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[12] || (_cache[12] = (...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_18, "正在加载")) : ((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_19, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[33] || (_cache[33] = (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_20, [_cache[34] || (_cache[34] = (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[35] || (_cache[35] = (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[36] || (_cache[36] = (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[37] || (_cache[37] = (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[38] || (_cache[38] = (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_21, (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_22, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[39] || (_cache[39] = (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[40] || (_cache[40] = (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[41] || (_cache[41] = (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[42] || (_cache[42] = (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_23, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[43] || (_cache[43] = (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_25, [((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: member.portrait,
alt: ""
}, null, 8, _hoisted_26)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_27, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_28, [(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_29, (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_30, (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_31, "暂无已读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_32, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[44] || (_cache[44] = (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_33, [((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: member.portrait,
alt: ""
}, null, 8, _hoisted_34)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_35, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_36, [(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_37, "送达 " + (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_38, (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_39, "暂无未读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_40, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[45] || (_cache[45] = (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_41, [((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: member.portrait,
alt: ""
}, null, 8, _hoisted_42)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_43, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_44, [(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[46] || (_cache[46] = (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_45, (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_46, "暂无未送达成员"))])])], 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: 6,
class: "modal-backdrop",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(closeSingleProfile, ["self"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_47, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[47] || (_cache[47] = (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_48, [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: singleProfile.value.portrait,
alt: ""
}, null, 8, _hoisted_49)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_50, (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_51, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[48] || (_cache[48] = (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.uid || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[49] || (_cache[49] = (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[50] || (_cache[50] = (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[51] || (_cache[51] = (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[52] || (_cache[52] = (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[14] || (_cache[14] = $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_52, [singleProfileNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_53, (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_54, (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_55), (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_56)])])])) : (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: 7,
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_57, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[53] || (_cache[53] = (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_58, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("dl", _hoisted_59, [(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_)(groupDetail.value?.name || activeConversation.value?.title || '-'), 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, "群ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.groupId || activeConversation.value?.target || '-'), 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_)(groupDetail.value?.announcement || '未设置'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[57] || (_cache[57] = (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_60), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: groupBusy.value,
onClick: openTransferGroup
}, "转让群组", 8, _hoisted_61)], 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_62))])])) : groupPanel.value === 'members' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_63, [(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_64, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_65, [((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)(sortedGroupMembers.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: member.portrait,
alt: ""
}, null, 8, _hoisted_66)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_67, (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), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("small", _hoisted_68, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("small", _hoisted_69, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(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[59] || (_cache[59] = (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[60] || (_cache[60] = (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[15] || (_cache[15] = $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[61] || (_cache[61] = (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: 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[62] || (_cache[62] = (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[16] || (_cache[16] = $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[17] || (_cache[17] = $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[18] || (_cache[18] = $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[19] || (_cache[19] = $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: 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[63] || (_cache[63] = (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[20] || (_cache[20] = $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[64] || (_cache[64] = (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[21] || (_cache[21] = $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[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)("textarea", {
"onUpdate:modelValue": _cache[22] || (_cache[22] = $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: 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[67] || (_cache[67] = (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[23] || (_cache[23] = $event => muteDraft.value.mode = $event),
onChange: clearMuteSaveFeedback
}, _cache[66] || (_cache[66] = [(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[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)("select", {
"onUpdate:modelValue": _cache[24] || (_cache[24] = $event => muteDraft.value.scheduleType = $event),
onChange: clearMuteSaveFeedback
}, _cache[68] || (_cache[68] = [(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[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)("input", {
"onUpdate:modelValue": _cache[25] || (_cache[25] = $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[71] || (_cache[71] = (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[26] || (_cache[26] = $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[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)("input", {
"onUpdate:modelValue": _cache[27] || (_cache[27] = $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[73] || (_cache[73] = (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.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: 8,
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)]);
};
}
});
/***/ }),
/***/ 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_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_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 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__(5187);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_9__ = __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 = {
key: 1,
class: "composer-attachment-preview"
};
const _hoisted_8 = ["src", "alt"];
const _hoisted_9 = {
key: 1,
class: "composer-attachment-file-icon"
};
const _hoisted_10 = {
class: "composer-attachment-name"
};
const _hoisted_11 = ["onClick"];
const _hoisted_12 = ["disabled", "onKeydown"];
const _hoisted_13 = {
class: "composer-footer"
};
const _hoisted_14 = ["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_9__/* .ref */ .KR)('');
const emojiOpen = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)(false);
const dropActive = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)(false);
const textareaEl = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)(null);
const imageInput = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)(null);
const fileInput = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)(null);
const pendingAttachments = (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .ref */ .KR)([]);
let dragDepth = 0;
const emojiList = ['😀', '😄', '😂', '😊', '😍', '😘', '😎', '😢', '😡', '👍', '🙏', '👏', '💪', '🎉', '❤️', '🔥', '🌹', '☕', '✅', '⭐', '💰', '🎁', '🤝', '👌'];
function submit() {
const value = text.value.trim();
const attachments = [...pendingAttachments.value];
if (!value && !attachments.length) {
return;
}
if (attachments.length) {
attachments.forEach((attachment, index) => {
emit('send-attachment', {
type: attachment.type,
file: attachment.file,
text: index === 0 ? value : ''
});
});
clearPendingAttachments();
} else {
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;
}
validFiles.forEach(file => {
const type = attachmentTypeForFile(file, fallbackType);
pendingAttachments.value.push({
id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
type,
file,
previewUrl: type === 'image' ? URL.createObjectURL(file) : ''
});
});
emojiOpen.value = false;
}
function releasePendingAttachment(attachment) {
if (attachment?.previewUrl) {
URL.revokeObjectURL(attachment.previewUrl);
}
}
function removePendingAttachment(index) {
const [attachment] = pendingAttachments.value.splice(index, 1);
releasePendingAttachment(attachment);
}
function clearPendingAttachments() {
pendingAttachments.value.forEach(releasePendingAttachment);
pendingAttachments.value = [];
}
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');
}
;(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .onBeforeUnmount */ .xo)(clearPendingAttachments);
return (_ctx, _cache) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("form", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeClass */ .C4)(["message-composer", {
'drop-active': dropActive.value
}]),
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(submit, ["prevent"]),
onDragenter: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(handleDragEnter, ["prevent"]),
onDragover: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(handleDragOver, ["prevent"]),
onDragleave: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(handleDragLeave, ["prevent"]),
onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(handleDrop, ["prevent"]),
onPaste: handlePaste
}, [__props.quoteMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, "引用", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createTextVNode */ .eW)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(__props.quoteMessage.quoteText || __props.quoteMessage.text), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "取消引用",
onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('cancel-quote'))
}, "×")])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "表情",
"aria-label": "表情",
disabled: __props.disabled,
onClick: toggleEmojiPicker
}, "☺", 8, _hoisted_3), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "composer-tool-button image-tool",
title: "图片",
"aria-label": "图片",
disabled: __props.disabled,
onClick: chooseImage
}, _cache[6] || (_cache[6] = [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("svg", {
class: "composer-tool-icon",
viewBox: "0 0 24 24",
"aria-hidden": "true"
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("rect", {
x: "3",
y: "5",
width: "18",
height: "14",
rx: "2.5"
}), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("circle", {
cx: "8.2",
cy: "9.2",
r: "1.6"
}), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("path", {
d: "M6.5 17l4.2-4.7 3.1 3.4 1.8-2 2.9 3.3"
})], -1)]), 8, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "composer-tool-button file-tool",
title: "文件",
"aria-label": "文件",
disabled: __props.disabled,
onClick: chooseFile
}, _cache[7] || (_cache[7] = [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createStaticVNode */ .Fv)("", 1)]), 8, _hoisted_5), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .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_7__/* .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_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "emoji-picker",
onClick: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .renderList */ .pI)(emojiList, emoji => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
key: emoji,
type: "button",
onClick: $event => insertEmoji(emoji)
}, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(emoji), 9, _hoisted_6);
}), 64))])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)]), pendingAttachments.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_7, [((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)(pendingAttachments.value, (attachment, index) => {
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("article", {
key: attachment.id,
class: "composer-attachment-item"
}, [attachment.type === 'image' ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("img", {
key: 0,
src: attachment.previewUrl,
alt: attachment.file.name || '待发送图片'
}, null, 8, _hoisted_8)) : ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_9, "▤")), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(attachment.file.name), 1), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "移除",
"aria-label": "移除待发送文件",
onClick: $event => removePendingAttachment(index)
}, "×", 8, _hoisted_11)]);
}), 128))])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .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_6__/* .withKeys */ .jR)((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(submit, ["exact", "prevent"]), ["enter"])
}, null, 40, _hoisted_12), [[vue__WEBPACK_IMPORTED_MODULE_6__/* .vModelText */ .Jo, text.value]]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_13, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, "Enter 发送,Shift + Enter 换行", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
class: "send-button",
disabled: __props.disabled || !text.value.trim() && !pendingAttachments.value.length
}, "发送", 8, _hoisted_14)])], 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_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 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__(144);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5187);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(9045);
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(446);
const _hoisted_1 = ["data-message-key", "onClick"];
const _hoisted_2 = {
key: 0,
class: "message-select"
};
const _hoisted_3 = ["checked", "onChange"];
const _hoisted_4 = ["title", "onClick"];
const _hoisted_5 = ["src"];
const _hoisted_6 = {
key: 1
};
const _hoisted_7 = {
class: "message-stack"
};
const _hoisted_8 = ["onClick"];
const _hoisted_9 = {
key: 0,
class: "message-sender-role"
};
const _hoisted_10 = ["onContextmenu"];
const _hoisted_11 = ["onClick"];
const _hoisted_12 = ["src", "alt"];
const _hoisted_13 = ["href"];
const _hoisted_14 = {
class: "message-file-main"
};
const _hoisted_15 = {
key: 2
};
const _hoisted_16 = {
key: 0,
class: "recall-mark"
};
const _hoisted_17 = {
key: 1,
class: "edit-mark"
};
const _hoisted_18 = {
key: 2,
class: "favorite-mark",
title: "已收藏",
"aria-label": "已收藏"
};
const _hoisted_19 = ["title", "aria-label"];
const _hoisted_20 = {
key: 0,
class: "delivery-check delivery-check-second"
};
const _hoisted_21 = {
key: 4,
class: "delivery-error"
};
const _hoisted_22 = ["onClick"];
const _hoisted_23 = {
class: "image-viewer-toolbar"
};
const _hoisted_24 = {
class: "image-viewer-title"
};
const _hoisted_25 = ["src", "alt"];
const _hoisted_26 = {
class: "sender-profile-main"
};
const _hoisted_27 = ["src"];
const _hoisted_28 = {
key: 1,
class: "profile-avatar"
};
const _hoisted_29 = {
key: 2
};
const _hoisted_30 = {
class: "sender-profile-fields"
};
const _hoisted_31 = {
class: "sender-profile-alias"
};
const _hoisted_32 = ["disabled"];
const _hoisted_33 = {
class: "sender-profile-actions"
};
const _hoisted_34 = {
key: 0,
class: "inline-save-status"
};
const _hoisted_35 = {
key: 1,
class: "inline-save-status error"
};
const _hoisted_36 = ["disabled"];
const _hoisted_37 = ["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: () => []
},
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_9__/* .useContactStore */ .p)();
const listEl = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .ref */ .KR)(null);
const viewerStage = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .ref */ .KR)(null);
const contextMenu = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .reactive */ .Kh)({
visible: false,
x: 0,
y: 0,
message: null
});
const messageTimeFormatter = new Intl.DateTimeFormat('zh-CN', {
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
});
const imageViewer = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .reactive */ .Kh)({
visible: false,
url: '',
name: '',
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_7__/* .reactive */ .Kh)({
visible: false,
uid: '',
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_6__/* .computed */ .EW)(() => ({
transform: `translate3d(${imageViewer.offsetX}px, ${imageViewer.offsetY}px, 0) scale(${imageViewer.scale}) rotate(${imageViewer.rotation}deg)`
}));
const menuItems = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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 items = [{
action: 'copy',
label: '复制'
}, {
action: 'delete',
label: '删除'
}, {
action: 'forward',
label: '转发'
}, {
action: 'favorite',
label: favoriteLabel
}, {
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_6__/* .nextTick */ .dY)(() => {
requestAnimationFrame(() => {
if (listEl.value) {
listEl.value.scrollTop = listEl.value.scrollHeight;
}
});
});
}
function isNearBottom() {
const element = listEl.value;
if (!element) {
return true;
}
return element.scrollHeight - element.scrollTop - element.clientHeight < 120;
}
function scrollToMessage(messageId) {
;(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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_6__/* .watch */ .wB)(() => props.messages.map(messageIdentity).join('|'), (nextKeys, previousKeys) => {
if (!previousKeys || nextKeys !== previousKeys && isNearBottom()) {
scrollToBottom();
}
}, {
immediate: true
});
(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .watch */ .wB)(() => props.attentionMessageId, scrollToMessage);
(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .onMounted */ .sV)(() => {
document.addEventListener('click', closeMenu);
document.addEventListener('keydown', closeMenuOnEscape);
document.addEventListener('pointermove', moveImageDrag);
document.addEventListener('pointerup', stopImageDrag);
});
(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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 displayMessageText(message) {
const text = String(message?.text || '').replace(/^引用:.*(?:\r?\n|$)/, '').trim();
const contentType = Number(message?.contentType || 0);
if (!text) {
return '';
}
if (contentType !== 1 && text === '[暂不支持的消息类型]') {
return '';
}
if ((contentType === 3 || message?.type === 'image') && (text === '[图片]' || text === '图片')) {
return '';
}
return text;
}
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 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.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 retryImageLoad(event) {
const image = event.currentTarget;
if (!(image instanceof HTMLImageElement)) {
return;
}
const attempts = Number(image.dataset.loadRetries || 0);
if (attempts >= 2) {
return;
}
const originalUrl = image.dataset.originalUrl || image.getAttribute('src') || '';
if (!originalUrl) {
return;
}
image.dataset.originalUrl = originalUrl;
image.dataset.loadRetries = String(attempts + 1);
window.setTimeout(() => {
if (!image.isConnected) {
return;
}
const separator = originalUrl.includes('?') ? '&' : '?';
image.src = `${originalUrl}${separator}_image_retry=${attempts + 1}`;
}, 500 * (attempts + 1));
}
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;
imageViewer.url = attachment.url;
imageViewer.name = attachment.name || 'image';
resetImageViewer();
}
function closeImageViewer() {
imageViewer.visible = false;
imageViewer.dragging = false;
}
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.url) {
return;
}
const downloadUrl = new URL('/api/media_download.php', window.location.origin);
downloadUrl.searchParams.set('url', imageViewer.url);
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 (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 messageTimeFormatter.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_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
ref_key: "listEl",
ref: listEl,
class: "message-list"
}, [((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .renderList */ .pI)(__props.messages, message => {
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("article", {
key: message.id,
class: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeClass */ .C4)(["message-row", [message.direction, {
selected: isSelected(message),
attention: isAttention(message),
recalled: message.recalled || message.status === 'recalled'
}]]),
"data-message-key": messageIdentity(message),
onClick: $event => handleMessageClick(message)
}, [__props.selectionMode ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("label", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("input", {
type: "checkbox",
checked: isSelected(message),
onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"])),
onChange: $event => emit('toggle-select', message)
}, null, 40, _hoisted_3)])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("button", {
key: 1,
type: "button",
class: "message-sender-avatar",
title: groupSenderName(message),
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
}, [message.senderPortrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("img", {
key: 0,
src: message.senderPortrait,
alt: ""
}, null, 8, _hoisted_5)) : ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_6, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(groupSenderAvatarText(message)), 1))], 8, _hoisted_4)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_7, [showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "message-sender-name",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createTextVNode */ .eW)((0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(groupSenderName(message)) + " ", 1), senderRoleLabel(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderRoleLabel(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)], 8, _hoisted_8)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", {
class: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeClass */ .C4)(["message-bubble", roleBubbleClass(message)]),
onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)($event => openMenu($event, message), ["prevent"])
}, [isImageMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("button", {
key: 0,
type: "button",
class: "message-image",
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)($event => handleImageClick(message), ["stop"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("img", {
src: (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_10__/* .imageDisplayUrl */ .B)(message.attachment.url),
alt: message.attachment.name || '图片',
loading: "lazy",
decoding: "async",
onError: retryImageLoad
}, null, 40, _hoisted_12)], 8, _hoisted_11)) : isFileMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("a", {
key: 1,
class: "message-file",
href: message.attachment.url,
target: "_blank",
rel: "noreferrer",
download: ""
}, [_cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", {
class: "message-file-icon"
}, "▤", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(message.attachment.name || '文件'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(formatFileSize(message.attachment.size)), 1)])], 8, _hoisted_13)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), displayMessageText(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("p", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(displayMessageText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("time", null, [isRecallNotice(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(message.recallStatus || '已撤回'), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(formatTime(message.displayTimestamp || message.timestamp)), 1), message.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_17, "【edit " + (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(formatTime(message.editedAt)) + "】", 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), isFavorite(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_18, "★")) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), deliveryState(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", {
key: 3,
class: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeClass */ .C4)(["delivery-mark", `delivery-mark-${deliveryState(message)}`]),
title: deliveryTitle(message),
"aria-label": deliveryTitle(message)
}, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", {
class: "delivery-check"
}, "✓", -1)), deliveryState(message) !== 'sent' ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_20, "✓")) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_19)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), message.status === 'failed' ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(failureText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)])], 42, _hoisted_10)])], 10, _hoisted_1);
}), 128)), contextMenu.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "message-context-menu",
style: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeStyle */ .Tr)({
left: `${contextMenu.x}px`,
top: `${contextMenu.y}px`
}),
onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .renderList */ .pI)(menuItems.value, item => {
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("button", {
key: item.action,
type: "button",
onClick: $event => chooseMenuAction(item.action)
}, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(item.label), 9, _hoisted_22);
}), 128))], 4)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Teleport */ .Im, {
to: "body"
}, [imageViewer.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "image-viewer-backdrop",
onClick: closeImageViewer
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", {
class: "image-viewer-dialog",
onClick: _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_23, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(imageViewer.name || '图片'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "缩小",
"aria-label": "缩小",
onClick: _cache[2] || (_cache[2] = $event => zoomImage(-0.25))
}, "−"), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "放大",
"aria-label": "放大",
onClick: _cache[3] || (_cache[3] = $event => zoomImage(0.25))
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "还原",
"aria-label": "还原",
onClick: resetImageViewer
}, "1:1"), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "旋转",
"aria-label": "旋转",
onClick: rotateImage
}, "⟳"), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "保存",
"aria-label": "保存",
onClick: saveViewerImage
}, "⇩"), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
title: "关闭",
"aria-label": "关闭",
onClick: closeImageViewer
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", {
ref_key: "viewerStage",
ref: viewerStage,
class: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeClass */ .C4)(["image-viewer-stage", {
dragging: imageViewer.dragging,
zoomed: imageViewer.scale > 1
}]),
onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleImageWheel, ["prevent"]),
onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(startImageDrag, ["prevent"])
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("img", {
class: "image-viewer-img",
src: (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_10__/* .imageDisplayUrl */ .B)(imageViewer.url),
alt: imageViewer.name || '图片',
style: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .normalizeStyle */ .Tr)(imageViewerStyle.value),
decoding: "async",
onError: retryImageLoad,
draggable: "false"
}, null, 44, _hoisted_25)], 34)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)])), ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Teleport */ .Im, {
to: "body"
}, [senderProfile.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
key: 0,
class: "sender-profile-backdrop",
onClick: closeSenderProfile
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("section", {
class: "sender-profile-dialog",
onClick: _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"]))
}, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("header", null, [_cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("strong", null, "用户资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "icon-button",
title: "关闭",
onClick: closeSenderProfile
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_26, [senderProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("img", {
key: 0,
class: "profile-avatar image-avatar",
src: senderProfile.portrait,
alt: ""
}, null, 8, _hoisted_27)) : ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.displayName || senderProfile.uid), 1), senderProfile.roleLabel ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_29, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.roleLabel), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dl", _hoisted_30, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", null, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dt", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.uid || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", null, [_cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dt", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.rawName || senderProfile.displayName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.mobile || '未知'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.address || '未知'), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("label", _hoisted_31, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, "备注名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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_32), [[vue__WEBPACK_IMPORTED_MODULE_5__/* .vModelText */ .Jo, senderProfile.aliasDraft, void 0, {
trim: true
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("footer", _hoisted_33, [senderProfile.notice ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_34, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.notice), 1)) : senderProfile.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("span", _hoisted_35, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), !senderProfile.isContact ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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_8__/* .toDisplayString */ .v_)(senderProfile.adding ? '添加中...' : '添加为好友'), 9, _hoisted_36)) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
disabled: senderProfile.saving || senderProfile.adding || !senderProfile.uid,
onClick: saveSenderAlias
}, (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .toDisplayString */ .v_)(senderProfile.saving ? '保存中...' : '保存备注'), 9, _hoisted_37)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .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);
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: 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: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__/* .imageDisplayUrl */ .B)(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);
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: 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);
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"];
const _hoisted_7 = ["src"];
const _hoisted_8 = {
key: 1,
class: "conversation-avatar"
};
const _hoisted_9 = {
class: "conversation-copy"
};
const _hoisted_10 = ["aria-label"];
const _hoisted_11 = {
key: 0,
class: "empty-list"
};
const _hoisted_12 = {
key: 1,
class: "empty-list"
};
const _hoisted_13 = {
class: "empty-list-actions"
};
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 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(() => {});
});
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);
(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .onBeforeUnmount */ .xo)(() => {
document.removeEventListener('click', closeActionMenu);
});
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[20] || (_cache[20] = (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)
}]),
onClick: $event => selectListItem(item)
}, [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: 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, (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_10)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_6);
}), 128)), !filteredConversationItems.value.length && searchKeyword.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", _hoisted_11, _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_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_12, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, "暂无会话", -1)), _cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "收到或发起消息后会出现在这里", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "primary-inline-action",
onClick: _cache[7] || (_cache[7] = $event => openAction('createGroup'))
}, "新建群组"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
type: "button",
class: "ghost-inline-action",
onClick: _cache[8] || (_cache[8] = $event => openAction('joinGroup'))
}, "加入群组")])])) : (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[24] || (_cache[24] = (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[9] || (_cache[9] = $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[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)("input", {
"onUpdate:modelValue": _cache[10] || (_cache[10] = $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[26] || (_cache[26] = (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 => 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[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[12] || (_cache[12] = $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[13] || (_cache[13] = $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[28] || (_cache[28] = (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[14] || (_cache[14] = $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[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[15] || (_cache[15] = $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[16] || (_cache[16] = $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[30] || (_cache[30] = (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[17] || (_cache[17] = $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[31] || (_cache[31] = (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[18] || (_cache[18] = $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[19] || (_cache[19] = $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 _stores_navigation__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1414);
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_8__ = __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_7__/* .useNavigationStore */ .l)();
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_8__/* .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)(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)("", 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}:18888`;
const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;
const appConfig = {
appName: 'Web IM',
adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin,
appServer: runtimeConfig.appServer || undefined || appServerOrigin,
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}/change_pwd`,
resetPasswordApi: runtimeConfig.resetPasswordApi || undefined || `${appServerOrigin}/reset_pwd`,
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 || 15000),
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');
/***/ }),
/***/ 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);
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 deviceId = getUniqueEquipment(mobile, this.getClientId());
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
mobile,
password,
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
clientId: deviceId,
uniqueEquipment: deviceId
}, {
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 deviceId = getUniqueEquipment(mobile, this.getClientId());
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;
}
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)
}, {
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
}));
const userId = this.currentUser?.userId || '';
const messagesByConversation = readLocalMessages(userId);
messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);
writeLocalMessages(messagesByConversation, userId);
return messagesByConversation[conversation.id];
}
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 ? '创建公告群失败' : '创建群组失败'));
}
const result = response.data?.result || {};
const conversation = this.normalizeConversation(result.conversation || {});
conversation.nativeStatus = result.nativeStatus || '';
conversation.nativeError = result.nativeError || '';
conversation.raw = {
...(conversation.raw || {}),
nativeStatus: conversation.nativeStatus,
nativeError: conversation.nativeError
};
return 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 || '加入群组失败');
}
const result = response.data?.result || {};
const conversation = this.normalizeConversation(result.conversation || {});
conversation.nativeStatus = result.nativeStatus || '';
conversation.nativeError = result.nativeError || '';
conversation.raw = {
...(conversation.raw || {}),
nativeStatus: conversation.nativeStatus,
nativeError: conversation.nativeError
};
return 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);
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() : new _httpImClient__WEBPACK_IMPORTED_MODULE_1__/* .HttpImClient */ .Y();
/* 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_iterator_map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1701);
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7642);
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8004);
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3853);
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5876);
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2475);
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5024);
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(1698);
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9__);
function configuredProxyHosts() {
const configured = window.JC_WEB_IM_CONFIG?.mediaProxyHosts;
const values = Array.isArray(configured) ? configured : String(configured || '').split(/[\s,]+/);
return new Set(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);
const LOCAL_CONVERSATION_STORAGE_KEY = 'qmt-web-im-local-conversations-v2';
const LOCAL_FAVORITE_MESSAGES_KEY = 'qmt-web-im-favorite-messages-v1';
const recentRealtimeNotifications = new Map();
function isDuplicateRealtimeNotification(payload) {
const messageId = String(payload?.messageId || '');
if (!messageId) {
return false;
}
const key = `${payload?.kind || 'message'}:${messageId}`;
const now = Date.now();
const previousAt = Number(recentRealtimeNotifications.get(key) || 0);
recentRealtimeNotifications.set(key, now);
if (recentRealtimeNotifications.size > 200) {
recentRealtimeNotifications.forEach((seenAt, seenKey) => {
if (now - seenAt > 30000) {
recentRealtimeNotifications.delete(seenKey);
}
});
}
return now - previousAt < 5000;
}
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 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 hasSameRenderState(left, right) {
if (left === right) {
return true;
}
try {
return JSON.stringify(left) === JSON.stringify(right);
} catch (error) {
return false;
}
}
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 cleanPlaceholderText(text, message = {}) {
const value = String(text || '').replace(/\s+/g, ' ').trim();
const contentType = Number(message?.contentType || 0);
if (!value) {
return '';
}
if (contentType !== 1 && value === '[暂不支持的消息类型]') {
return '';
}
if ((contentType === 3 || message?.type === 'image') && (value === '[图片]' || value === '图片')) {
return '';
}
return value;
}
function messagePreviewText(message) {
if (isRecalledMessage(message)) {
return `[${message?.recallStatus || '已撤回'}]`;
}
const text = cleanPlaceholderText(message?.text, message);
return text || attachmentLabel(message);
}
function sanitizeConversation(conversation) {
if (!conversation) {
return conversation;
}
return {
...conversation,
subtitle: cleanPlaceholderText(conversation.subtitle, conversation)
};
}
function isHttpUrl(value) {
try {
const url = new URL(String(value || '').trim());
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (error) {
return false;
}
}
function fileNameFromUrl(url, fallback = '图片') {
try {
const path = new URL(url).pathname;
const name = decodeURIComponent(path.split('/').filter(Boolean).pop() || '');
return name || fallback;
} catch (error) {
return fallback;
}
}
function normalizeMessageForDisplay(message) {
if (!message || message.attachment) {
return message;
}
const contentType = Number(message.contentType || 0);
const text = String(message.text || '').trim();
if ((contentType === 3 || message.type === 'image') && isHttpUrl(text)) {
return {
...message,
type: 'image',
text: '',
attachment: {
type: 'image',
url: text,
name: fileNameFromUrl(text, '图片'),
mime: 'image/*',
size: 0
}
};
}
return 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 isPageVisible() {
return typeof document === 'undefined' || document.visibilityState === 'visible';
}
function activeMessageSyncIntervalMs() {
const configured = Number(_config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.syncIntervalMs || 0);
return Math.max(15000, Number.isFinite(configured) && configured > 0 ? configured : 15000);
}
function conversationListSyncIntervalMs() {
return Math.max(30000, activeMessageSyncIntervalMs() * 2);
}
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,
messageSyncTimer: null,
messageSyncQueuedAt: 0,
pendingMessageSyncOptions: {},
lastReadSyncByConversation: {},
optimisticMessagesByConversation: {},
quotedMessage: null,
forwardingMessages: [],
editingMessage: null,
editingText: '',
editingMode: '',
messageDetailOpen: false,
messageDetailLoading: false,
messageDetailError: '',
messageDetail: null,
attentionMessageId: '',
attentionMessageTimer: null,
selectionMode: false,
selectedMessageIds: [],
favoriteMessages: [],
activeFavoriteKey: '',
actionNotice: '',
actionError: '',
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;
},
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 = readLocalConversations().map(sanitizeConversation);
this.favoriteMessages = readFavoriteMessages();
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
this.activeId = this.conversations[0]?.id || '';
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 = [];
if (this.activeId) {
this.loadActiveMessages({
allowReadReceipt: true
});
}
},
clearUserState() {
window.clearInterval(this.syncTimer);
window.clearInterval(this.conversationSyncTimer);
window.clearTimeout(this.messageSyncTimer);
window.clearTimeout(this.attentionMessageTimer);
window.clearTimeout(this.realtimeSyncTimer);
_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.stop();
this.syncTimer = null;
this.conversationSyncTimer = null;
this.messageSyncTimer = null;
this.messageSyncQueuedAt = 0;
this.pendingMessageSyncOptions = {};
this.attentionMessageTimer = null;
this.realtimeSyncTimer = null;
this.syncInFlight = false;
this.conversationSyncInFlight = false;
this.pendingReadReceiptConversationId = '';
this.lastReadSyncByConversation = {};
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
}, 700);
}
});
_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) {
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);
this.scheduleActiveMessagesSync({}, 700);
},
sendAttachment({
type,
file,
text = ''
}) {
const conversation = this.activeConversation;
if (!conversation || !file || !['image', 'file'].includes(type)) {
return;
}
let value = text.trim();
if (this.quotedMessage) {
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);
this.scheduleActiveMessagesSync({}, 700);
},
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) {
conversation = sanitizeConversation(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 previousActiveId = this.activeId;
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) || {}),
...sanitizeConversation(conversation),
unread
});
});
const nextConversations = Array.from(merged.values()).map(sanitizeConversation).sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0)).slice(0, 100);
const conversationsChanged = !hasSameRenderState(this.conversations, nextConversations);
if (conversationsChanged) {
this.conversations = nextConversations;
}
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;
}
if (conversationsChanged) {
writeLocalConversations(this.conversations);
}
if (previousActiveId !== this.activeId || !this.messagesByConversation[this.activeId]) {
this.loadActiveMessages();
}
},
appendMessage(conversationId, message) {
message = normalizeMessageForDisplay(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 = messagePreviewText(message) || cleanPlaceholderText(conversation.subtitle, conversation);
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) {
message = normalizeMessageForDisplay(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) {
message = normalizeMessageForDisplay(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) {
const currentMessages = this.visibleMessagesByConversation[conversationId] || [];
const nextMessages = mergeVisibleMessages(this.optimisticMessagesByConversation[conversationId] || [], this.messagesByConversation[conversationId] || []);
if (!hasSameRenderState(currentMessages, nextMessages)) {
this.visibleMessagesByConversation = {
...this.visibleMessagesByConversation,
[conversationId]: nextMessages
};
}
},
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);
const nextMessages = mergeVisibleMessages(this.messagesByConversation[conversation.id] || [], messages);
if (!hasSameRenderState(this.messagesByConversation[conversation.id] || [], nextMessages)) {
this.messagesByConversation = {
...this.messagesByConversation,
[conversation.id]: nextMessages
};
}
this.syncVisibleMessages(conversation.id);
this.loading = false;
this.syncActiveMessages(syncOptions);
},
async syncActiveMessages(options = {}) {
const conversation = this.activeConversation;
if (!conversation) {
return;
}
if (options.skipWhenHidden !== false && !isPageVisible()) {
return;
}
const wantsReadReceipt = Boolean(options.allowReadReceipt);
const explicitReadReceipt = wantsReadReceipt && canMarkReadNow({
userAction: Boolean(options.userAction)
});
const now = Date.now();
const previousReadSyncAt = Number(this.lastReadSyncByConversation[conversation.id] || 0);
const pollingReadReceipt = canMarkReadNow() && now - previousReadSyncAt >= 10000;
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
});
if (markRead) {
this.lastReadSyncByConversation = {
...this.lastReadSyncByConversation,
[syncedConversationId]: Date.now()
};
}
const editedIncomingMessages = incomingEditedMessages(previousMessages, messages);
this.pruneOptimisticMessages(syncedConversationId, messages);
const nextMessages = mergeVisibleMessages(this.messagesByConversation[syncedConversationId] || [], messages);
if (!hasSameRenderState(this.messagesByConversation[syncedConversationId] || [], nextMessages)) {
this.messagesByConversation = {
...this.messagesByConversation,
[syncedConversationId]: nextMessages
};
}
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) {
const nextSubtitle = messagePreviewText(latest);
const nextUpdatedAt = messageActivityTimestamp(latest);
if (conversation.subtitle !== nextSubtitle || Number(conversation.updatedAt || 0) !== nextUpdatedAt) {
conversation.subtitle = nextSubtitle;
conversation.updatedAt = nextUpdatedAt;
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 = '';
this.scheduleActiveMessagesSync({
allowReadReceipt: true
}, 700);
}
}
},
scheduleActiveMessagesSync(options = {}, delay = 700) {
if (!this.activeId || !isPageVisible()) {
return;
}
const now = Date.now();
if (!this.messageSyncQueuedAt) {
this.messageSyncQueuedAt = now;
}
this.pendingMessageSyncOptions = {
...this.pendingMessageSyncOptions,
allowReadReceipt: Boolean(this.pendingMessageSyncOptions.allowReadReceipt || options.allowReadReceipt),
userAction: Boolean(this.pendingMessageSyncOptions.userAction || options.userAction)
};
const maxWait = 1200;
const runAt = Math.min(now + Math.max(0, Number(delay) || 0), this.messageSyncQueuedAt + maxWait);
window.clearTimeout(this.messageSyncTimer);
this.messageSyncTimer = window.setTimeout(() => {
const pendingOptions = this.pendingMessageSyncOptions;
this.messageSyncTimer = null;
this.messageSyncQueuedAt = 0;
this.pendingMessageSyncOptions = {};
this.syncActiveMessages(pendingOptions);
}, Math.max(0, runAt - now));
},
startMessageSync() {
this.bindReadPresenceEvents();
if (!this.syncTimer) {
this.syncTimer = window.setInterval(() => {
if (isPageVisible() && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
this.syncActiveMessages();
}
}, activeMessageSyncIntervalMs());
}
if (!this.conversationSyncTimer) {
this.conversationSyncTimer = window.setInterval(() => {
if (isPageVisible() && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
this.refreshRemoteConversations();
}
}, conversationListSyncIntervalMs());
this.refreshRemoteConversations();
}
},
handleRealtimeNotification(payload) {
if (isDuplicateRealtimeNotification(payload)) {
return;
}
window.clearTimeout(this.realtimeSyncTimer);
this.realtimeSyncTimer = window.setTimeout(() => {
this.refreshRemoteConversations();
if (this.activeId) {
this.scheduleActiveMessagesSync({
allowReadReceipt: canMarkReadNow()
}, 700);
}
}, 500);
},
bindReadPresenceEvents() {
if (this.readPresenceEventsBound || typeof window === 'undefined' || typeof document === 'undefined') {
return;
}
this.readPresenceEventsBound = true;
const syncWhenReadable = () => {
if (canMarkReadNow()) {
this.refreshRemoteConversations();
this.scheduleActiveMessagesSync({
allowReadReceipt: true
}, 300);
}
};
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 = '';
}, 1800);
},
setActionError(message) {
this.actionError = message;
this.actionNotice = '';
window.clearTimeout(this.actionErrorTimer);
this.actionErrorTimer = window.setTimeout(() => {
this.actionError = '';
}, 2400);
},
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 === '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);
},
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);
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 = messagePreviewText(editedMessage);
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;
}
const text = this.forwardingMessages.map(message => `转发:${message.text || ''}`).join('\n\n');
try {
await this.sendTextToConversation(target, 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);
const nativeStatus = conversation.nativeStatus || conversation.raw?.nativeStatus || '';
if (nativeStatus && nativeStatus !== 'ok') {
this.setActionNotice(options.channel ? '公告群已创建,仅网页可见' : '群组已创建,仅网页可见');
} else {
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);
const nativeStatus = conversation.nativeStatus || conversation.raw?.nativeStatus || '';
this.setActionNotice(nativeStatus && nativeStatus !== 'ok' ? '已加入群组,仅网页可见' : '已加入群组');
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 pinia__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2261);
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5051);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2169);
const STORAGE_KEY = 'qmt-web-im-session';
function normalizeStoredPortrait(portrait) {
return portrait || '';
}
function nextProfilePortrait(profilePortrait, currentPortrait) {
return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);
}
const useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_0__/* .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_2__/* .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_1__/* .imClient */ .wD.restoreClientId(session.clientId);
if (session.localOnly) {
this.connectionStatusText = '本地调试登录';
}
this.connect();
this.refreshProfile();
}
} catch (error) {
localStorage.removeItem(STORAGE_KEY);
}
},
async loginWithPassword(mobile, password) {
this.error = '';
this.connecting = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.loginWithPassword(mobile, password);
this.applyLoginResult(result);
await this.connect();
} catch (error) {
this.error = error.message || '登录失败';
} finally {
this.connecting = false;
}
},
async loginWithCode(mobile, code) {
this.error = '';
this.connecting = true;
try {
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.loginWithCode(mobile, 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 registerWithPhone(mobile, code) {
this.error = '';
this.connecting = true;
try {
return await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.registerWithPhone(mobile, code);
} 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);
if (result.localOnly) {
this.connectionStatusText = '本地调试登录';
}
this.persistSession(Boolean(result.localOnly));
},
persistSession(localOnly = false) {
localStorage.setItem(STORAGE_KEY, JSON.stringify({
userId: this.userId,
token: this.token,
displayName: this.displayName,
portrait: this.portrait,
clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.getClientId(),
localOnly,
appServer: _config__WEBPACK_IMPORTED_MODULE_2__/* .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_1__/* .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_1__/* .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_1__/* .imClient */ .wD.changePassword({
oldPassword,
newPassword
});
return true;
},
async resetPasswordWithCode({
mobile,
resetCode,
newPassword
}) {
await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.resetPasswordWithCode({
mobile,
resetCode,
newPassword
});
return true;
},
async connect() {
if (!this.userId || !this.token) {
return;
}
await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.ensureSdk();
this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.getSdkVersion();
this.bindImEvents();
await _services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.connect(this.userId, this.token);
},
bindImEvents() {
if (this.eventsBound) {
return;
}
this.eventsBound = true;
_services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .imClient */ .wD.on('connectionStatusChanged', status => {
this.connected = status.connected;
this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');
});
},
logout() {
_services_imClient__WEBPACK_IMPORTED_MODULE_1__/* .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
/******/ // skipped when the property is non-configurable (pre-ES2015 engines),
/******/ // where Object.defineProperty would throw
/******/ __webpack_require__.dn = function(x) {
/******/ var descriptor = Object.getOwnPropertyDescriptor(x, "name");
/******/ if (!descriptor || (!descriptor.writable && descriptor.configurable)) 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.a89973f7.js.map