9928 lines
512 KiB
JavaScript
9928 lines
512 KiB
JavaScript
/******/ (function() { // webpackBootstrap
|
||
/******/ "use strict";
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ 4677:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144);
|
||
/* harmony import */ var _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3727);
|
||
/* harmony import */ var _components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9531);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(926);
|
||
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'App',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_4__/* .useSessionStore */ .B)();
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
|
||
session.restore();
|
||
});
|
||
return (_ctx, _cache) => {
|
||
return !(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(session).isAuthenticated ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_LoginView_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, {
|
||
key: 0
|
||
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
|
||
key: 1
|
||
}));
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 2511:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144);
|
||
/* harmony import */ var _sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8328);
|
||
/* harmony import */ var _sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(371);
|
||
/* harmony import */ var _sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(578);
|
||
/* harmony import */ var _chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7014);
|
||
/* harmony import */ var _contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3351);
|
||
/* harmony import */ var _favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(163);
|
||
/* harmony import */ var _favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9123);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7566);
|
||
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1414);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9045);
|
||
|
||
const _hoisted_1 = {
|
||
class: "app-shell"
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'ChatShell',
|
||
setup(__props) {
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_9__/* .useConversationStore */ .w)();
|
||
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_10__/* .useNavigationStore */ .l)();
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_11__/* .useContactStore */ .p)();
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .onMounted */ .sV)(() => {
|
||
conversations.refreshRemoteConversations();
|
||
contacts.refreshContacts();
|
||
});
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createVNode */ .bF)(_sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
|
||
key: 0
|
||
})) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A, {
|
||
key: 1
|
||
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A, {
|
||
key: 2
|
||
})), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A, {
|
||
key: 3
|
||
})) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .unref */ .R1)(navigation).section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A, {
|
||
key: 4
|
||
})) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createBlock */ .Wv)(_contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A, {
|
||
key: 5
|
||
}))]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 8607:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2387);
|
||
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2789);
|
||
/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2169);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(926);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5051);
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "login-page"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "login-panel"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "brand-lockup"
|
||
};
|
||
const _hoisted_4 = ["src", "alt"];
|
||
const _hoisted_5 = {
|
||
class: "login-tabs register-tabs",
|
||
style: {
|
||
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))'
|
||
}
|
||
};
|
||
const _hoisted_6 = ["disabled"];
|
||
const _hoisted_7 = ["src"];
|
||
const _hoisted_8 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_9 = {
|
||
key: 0,
|
||
class: "qr-scan-user"
|
||
};
|
||
const _hoisted_10 = ["src"];
|
||
const _hoisted_11 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_12 = {
|
||
class: "qr-login-status"
|
||
};
|
||
const _hoisted_13 = ["disabled"];
|
||
const _hoisted_14 = ["autocomplete", "inputmode", "placeholder"];
|
||
const _hoisted_15 = ["disabled"];
|
||
const _hoisted_16 = {
|
||
key: 2,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_17 = {
|
||
key: 3,
|
||
class: "form-info"
|
||
};
|
||
const _hoisted_18 = {
|
||
class: "login-tabs register-tabs",
|
||
style: {
|
||
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))'
|
||
}
|
||
};
|
||
const _hoisted_19 = ["autocomplete", "inputmode", "placeholder"];
|
||
const _hoisted_20 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_21 = {
|
||
class: "code-row"
|
||
};
|
||
const _hoisted_22 = ["disabled"];
|
||
const _hoisted_23 = ["disabled"];
|
||
const _hoisted_24 = {
|
||
key: 1,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_25 = {
|
||
key: 2,
|
||
class: "form-info"
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/';
|
||
const defaultPlatformLogo = '/favicon.ico';
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'LoginView',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_8__/* .useSessionStore */ .B)();
|
||
const view = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('login');
|
||
const loginMode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('phone');
|
||
const loginAccount = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const loginPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(1);
|
||
const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .reactive */ .Kh)({
|
||
number: '',
|
||
code: '',
|
||
password: '',
|
||
confirmPassword: '',
|
||
invitationCode: ''
|
||
});
|
||
const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(false);
|
||
const info = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('idle');
|
||
const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
let qrGeneration = 0;
|
||
let qrExpireTimer = null;
|
||
const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.appName;
|
||
const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformName);
|
||
const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)(defaultPlatformLogo);
|
||
const canSubmitLogin = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => loginAccount.value.length >= 3 && loginPassword.value.length >= 1);
|
||
const canRequestEmailCode = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => registerType.value === 2 && /\S+@\S+\.\S+/.test(registerForm.number));
|
||
const canSubmitRegister = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (registerForm.password.length < 1 || registerForm.password !== registerForm.confirmPassword) {
|
||
return false;
|
||
}
|
||
if (registerType.value === 2) {
|
||
return canRequestEmailCode.value && registerForm.code.length >= 1;
|
||
}
|
||
return registerForm.number.length >= 5;
|
||
});
|
||
const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => String(qrUserName.value || 'U').slice(0, 1).toUpperCase());
|
||
const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (session.connecting || qrStatus.value === 'confirmed') {
|
||
return '正在进入';
|
||
}
|
||
if (qrStatus.value === 'loading') {
|
||
return '正在生成二维码';
|
||
}
|
||
if (qrStatus.value === 'scanned') {
|
||
return qrUserName.value ? `${qrUserName.value} 已扫码` : '已扫码,待确认';
|
||
}
|
||
if (qrStatus.value === 'expired') {
|
||
return '二维码已过期';
|
||
}
|
||
if (qrStatus.value === 'error') {
|
||
return '二维码加载失败';
|
||
}
|
||
return '扫码登录';
|
||
});
|
||
const qrStatusText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (session.connecting || qrStatus.value === 'confirmed') {
|
||
return '登录信息已确认,正在建立连接';
|
||
}
|
||
if (qrStatus.value === 'loading') {
|
||
return '正在创建扫码登录会话';
|
||
}
|
||
if (qrStatus.value === 'scanned') {
|
||
return '请在手机 App 上确认登录';
|
||
}
|
||
if (qrStatus.value === 'expired') {
|
||
return '请刷新二维码后重新扫码';
|
||
}
|
||
if (qrStatus.value === 'error') {
|
||
return '请稍后重试';
|
||
}
|
||
return '使用已登录的手机 App 扫描二维码';
|
||
});
|
||
const qrRefreshText = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => {
|
||
if (qrStatus.value === 'loading') {
|
||
return '生成中...';
|
||
}
|
||
if (qrStatus.value === 'expired' || qrStatus.value === 'error') {
|
||
return '重新生成二维码';
|
||
}
|
||
return '刷新二维码';
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onMounted */ .sV)(() => {
|
||
loadPlatformConfig();
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .onBeforeUnmount */ .xo)(() => {
|
||
stopQrLogin();
|
||
});
|
||
function clearFormMessage() {
|
||
session.error = '';
|
||
info.value = '';
|
||
}
|
||
function setLoginMode(mode) {
|
||
loginMode.value = mode;
|
||
loginAccount.value = '';
|
||
loginPassword.value = '';
|
||
clearFormMessage();
|
||
if (mode === 'qr') {
|
||
startQrLogin();
|
||
return;
|
||
}
|
||
stopQrLogin();
|
||
}
|
||
async function submitLogin() {
|
||
clearFormMessage();
|
||
const type = loginMode.value === 'email' ? 2 : 1;
|
||
await session.loginWithPassword(loginAccount.value, loginPassword.value, type);
|
||
}
|
||
function switchRegisterType(type) {
|
||
registerType.value = type;
|
||
registerForm.number = '';
|
||
registerForm.code = '';
|
||
registerForm.password = '';
|
||
registerForm.confirmPassword = '';
|
||
registerForm.invitationCode = '';
|
||
clearFormMessage();
|
||
}
|
||
async function requestEmailCode() {
|
||
clearFormMessage();
|
||
sendingCode.value = true;
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.requestAuthCode(registerForm.number);
|
||
info.value = '邮箱验证码已发送,请在当前注册表单中填写后继续。';
|
||
} catch (error) {
|
||
session.error = error.message || '验证码发送失败';
|
||
} finally {
|
||
sendingCode.value = false;
|
||
}
|
||
}
|
||
async function submitRegister() {
|
||
clearFormMessage();
|
||
if (registerForm.password !== registerForm.confirmPassword) {
|
||
session.error = '两次输入的密码不一致';
|
||
return;
|
||
}
|
||
const result = await session.register({
|
||
type: registerType.value,
|
||
number: registerForm.number,
|
||
code: registerType.value === 2 ? registerForm.code : '',
|
||
password: registerForm.password,
|
||
invitationCode: registerForm.invitationCode
|
||
});
|
||
if (result) {
|
||
info.value = '注册成功,正在进入系统。';
|
||
}
|
||
}
|
||
function openRegister() {
|
||
clearFormMessage();
|
||
stopQrLogin();
|
||
view.value = 'register';
|
||
}
|
||
function backToLogin() {
|
||
clearFormMessage();
|
||
loginMode.value = 'phone';
|
||
stopQrLogin();
|
||
view.value = 'login';
|
||
}
|
||
function resetQrState() {
|
||
qrStatus.value = 'idle';
|
||
qrCodeImage.value = '';
|
||
qrSessionToken.value = '';
|
||
qrUserName.value = '';
|
||
qrUserPortrait.value = '';
|
||
}
|
||
function clearQrExpireTimer() {
|
||
if (qrExpireTimer) {
|
||
window.clearTimeout(qrExpireTimer);
|
||
qrExpireTimer = null;
|
||
}
|
||
}
|
||
function stopQrLogin() {
|
||
qrGeneration += 1;
|
||
clearQrExpireTimer();
|
||
resetQrState();
|
||
}
|
||
function refreshQrLogin() {
|
||
startQrLogin(true);
|
||
}
|
||
async function startQrLogin(force = false) {
|
||
if (loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
if (!force && qrSessionToken.value && qrCodeImage.value && !['expired', 'error'].includes(qrStatus.value)) {
|
||
return;
|
||
}
|
||
qrGeneration += 1;
|
||
const generation = qrGeneration;
|
||
clearQrExpireTimer();
|
||
clearFormMessage();
|
||
qrStatus.value = 'loading';
|
||
qrCodeImage.value = '';
|
||
qrSessionToken.value = '';
|
||
qrUserName.value = '';
|
||
qrUserPortrait.value = '';
|
||
try {
|
||
const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.createPcSession();
|
||
if (generation !== qrGeneration || loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
const token = String(pcSession.token || '');
|
||
if (!token) {
|
||
throw new Error('服务端没有返回扫码 token');
|
||
}
|
||
qrSessionToken.value = token;
|
||
qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_6___default().getQrBase64(QR_CODE_PREFIX_PC_SESSION + token);
|
||
qrStatus.value = 'waiting';
|
||
const expireMs = Math.max(30000, Math.min(Number(pcSession.expired || 300000), 300000));
|
||
qrExpireTimer = window.setTimeout(() => {
|
||
if (generation === qrGeneration && qrStatus.value !== 'confirmed' && !session.isAuthenticated) {
|
||
qrStatus.value = 'expired';
|
||
}
|
||
}, expireMs);
|
||
pollQrLogin(generation, token);
|
||
} catch (error) {
|
||
if (generation !== qrGeneration) {
|
||
return;
|
||
}
|
||
qrStatus.value = 'error';
|
||
session.error = error.message || '二维码加载失败';
|
||
}
|
||
}
|
||
async function pollQrLogin(generation, token) {
|
||
try {
|
||
while (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
|
||
const payload = await _services_imClient__WEBPACK_IMPORTED_MODULE_9__/* .imClient */ .wD.loginWithPcSession(token);
|
||
if (generation !== qrGeneration || loginMode.value !== 'qr') {
|
||
return;
|
||
}
|
||
const code = Number(payload.code);
|
||
const data = payload.data || payload.result || {};
|
||
const status = Number(data.status);
|
||
if (code === 0 && data.imToken) {
|
||
qrStatus.value = 'confirmed';
|
||
clearQrExpireTimer();
|
||
await session.completePcSessionLogin(data);
|
||
return;
|
||
}
|
||
if (code === 20042 || status === 1 || status === 3) {
|
||
qrStatus.value = 'scanned';
|
||
qrUserName.value = data.userName || data.displayName || qrUserName.value;
|
||
qrUserPortrait.value = data.portrait || qrUserPortrait.value;
|
||
await delay(1000);
|
||
continue;
|
||
}
|
||
if (status === 0 || code === 13) {
|
||
qrStatus.value = 'waiting';
|
||
await delay(1000);
|
||
continue;
|
||
}
|
||
if (status === 4) {
|
||
qrStatus.value = 'expired';
|
||
session.error = payload.message || '扫码登录已取消';
|
||
return;
|
||
}
|
||
if (payload.message) {
|
||
throw new Error(payload.message);
|
||
}
|
||
await delay(1000);
|
||
}
|
||
} catch (error) {
|
||
if (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {
|
||
qrStatus.value = 'error';
|
||
session.error = error.message || '扫码登录失败';
|
||
}
|
||
}
|
||
}
|
||
function delay(ms) {
|
||
return new Promise(resolve => window.setTimeout(resolve, ms));
|
||
}
|
||
async function loadPlatformConfig() {
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A.get(_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.platformConfigApi, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '平台配置加载失败');
|
||
}
|
||
const config = response.data?.result || {};
|
||
const name = String(config.platformName || '').trim();
|
||
const logo = String(config.logoUrl || config.logo || '').trim();
|
||
const version = String(config.version || '').trim();
|
||
platformName.value = name || defaultPlatformName;
|
||
platformLogo.value = resolveBrandLogo(logo, version);
|
||
} catch (error) {
|
||
platformName.value = defaultPlatformName;
|
||
platformLogo.value = defaultPlatformLogo;
|
||
}
|
||
applyDocumentBrand();
|
||
}
|
||
function resolveBrandLogo(value, version = '') {
|
||
const logo = String(value || '').trim();
|
||
if (!logo) {
|
||
return defaultPlatformLogo;
|
||
}
|
||
if (/^(https?:|data:|blob:)/i.test(logo)) {
|
||
return appendBrandVersion(logo, version);
|
||
}
|
||
if (logo.startsWith('//')) {
|
||
return appendBrandVersion(`${window.location.protocol}${logo}`, version);
|
||
}
|
||
const base = logo.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_7__/* .appConfig */ .U.adminServer}/`;
|
||
return appendBrandVersion(new URL(logo, base).toString(), version);
|
||
}
|
||
function appendBrandVersion(url, version) {
|
||
if (!version || /^(data:|blob:)/i.test(url)) {
|
||
return url;
|
||
}
|
||
const parsed = new URL(url, window.location.href);
|
||
parsed.searchParams.set('v', version);
|
||
return parsed.toString();
|
||
}
|
||
function applyDocumentBrand() {
|
||
if (typeof document === 'undefined') {
|
||
return;
|
||
}
|
||
document.title = platformName.value || defaultPlatformName;
|
||
let icon = document.querySelector('link[rel="icon"]');
|
||
if (!icon) {
|
||
icon = document.createElement('link');
|
||
icon.setAttribute('rel', 'icon');
|
||
document.head.appendChild(icon);
|
||
}
|
||
icon.setAttribute('href', platformLogo.value || defaultPlatformLogo);
|
||
}
|
||
function handleBrandLogoError() {
|
||
if (platformLogo.value !== defaultPlatformLogo) {
|
||
platformLogo.value = defaultPlatformLogo;
|
||
applyDocumentBrand();
|
||
}
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("main", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("section", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", {
|
||
class: "brand-mark",
|
||
src: platformLogo.value,
|
||
alt: `${platformName.value} logo`,
|
||
onError: handleBrandLogoError
|
||
}, null, 40, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h1", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(platformName.value), 1)])]), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
|
||
key: 0,
|
||
class: "login-form",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitLogin, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'qr'
|
||
}),
|
||
onClick: _cache[0] || (_cache[0] = $event => setLoginMode('qr'))
|
||
}, "扫码登录", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'phone'
|
||
}),
|
||
onClick: _cache[1] || (_cache[1] = $event => setLoginMode('phone'))
|
||
}, "手机号", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: loginMode.value === 'email'
|
||
}),
|
||
onClick: _cache[2] || (_cache[2] = $event => setLoginMode('email'))
|
||
}, "邮箱", 2)]), loginMode.value === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
|
||
key: 0
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["qr-login-card", {
|
||
scanned: qrStatus.value === 'scanned',
|
||
expired: qrStatus.value === 'expired',
|
||
error: qrStatus.value === 'error'
|
||
}])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "qr-code-button",
|
||
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
|
||
onClick: refreshQrLogin
|
||
}, [qrCodeImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: qrCodeImage.value,
|
||
alt: "扫码登录二维码"
|
||
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatus.value === 'loading' ? '生成中' : '点击刷新'), 1))], 8, _hoisted_6), qrStatus.value === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_9, [qrUserPortrait.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: qrUserPortrait.value,
|
||
alt: ""
|
||
}, null, 8, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrUserInitial.value), 1))])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrStatusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-action",
|
||
disabled: qrStatus.value === 'loading' || (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting,
|
||
onClick: refreshQrLogin
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(qrRefreshText.value), 9, _hoisted_13)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(loginMode.value === 'phone' ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => loginAccount.value = $event),
|
||
autocomplete: loginMode.value === 'phone' ? 'username' : 'email',
|
||
inputmode: loginMode.value === 'phone' ? 'tel' : 'email',
|
||
placeholder: loginMode.value === 'phone' ? '请输入手机号' : '请输入邮箱'
|
||
}, null, 8, _hoisted_14), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginAccount.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => loginPassword.value = $event),
|
||
autocomplete: "current-password",
|
||
type: "password",
|
||
placeholder: "请输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, loginPassword.value]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-action",
|
||
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitLogin.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '登录中...' : '登录'), 9, _hoisted_15)], 64)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("form", {
|
||
key: 1,
|
||
class: "login-form",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withModifiers */ .D$)(submitRegister, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: registerType.value === 1
|
||
}),
|
||
onClick: _cache[5] || (_cache[5] = $event => switchRegisterType(1))
|
||
}, "手机号注册", 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)({
|
||
active: registerType.value === 2
|
||
}),
|
||
onClick: _cache[6] || (_cache[6] = $event => switchRegisterType(2))
|
||
}, "邮箱注册", 2)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(registerType.value === 1 ? '手机号' : '邮箱'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = $event => registerForm.number = $event),
|
||
autocomplete: registerType.value === 1 ? 'tel' : 'email',
|
||
inputmode: registerType.value === 1 ? 'tel' : 'email',
|
||
placeholder: registerType.value === 1 ? '请输入手机号' : '请输入邮箱'
|
||
}, null, 8, _hoisted_19), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.number, void 0, {
|
||
trim: true
|
||
}]])]), registerType.value === 2 ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("label", _hoisted_20, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邮箱验证码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[8] || (_cache[8] = $event => registerForm.code = $event),
|
||
autocomplete: "one-time-code",
|
||
inputmode: "numeric",
|
||
placeholder: "请输入邮箱验证码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.code, void 0, {
|
||
trim: true
|
||
}]]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "code-action",
|
||
disabled: sendingCode.value || !canRequestEmailCode.value,
|
||
onClick: requestEmailCode
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(sendingCode.value ? '发送中' : '发送验证码'), 9, _hoisted_22)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => registerForm.password = $event),
|
||
autocomplete: "new-password",
|
||
type: "password",
|
||
placeholder: "请输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "确认密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => registerForm.confirmPassword = $event),
|
||
autocomplete: "new-password",
|
||
type: "password",
|
||
placeholder: "请再次输入密码"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("label", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "邀请码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[11] || (_cache[11] = $event => registerForm.invitationCode = $event),
|
||
autocomplete: "off",
|
||
placeholder: "没有可留空"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_1__/* .vModelText */ .Jo, registerForm.invitationCode, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-action",
|
||
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting || !canSubmitRegister.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).connecting ? '注册中...' : '注册并登录'), 9, _hoisted_23), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(session).error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), info.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(info.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)], 32)), view.value === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
|
||
key: 2,
|
||
class: "ghost-action",
|
||
type: "button",
|
||
onClick: openRegister
|
||
}, " 新用户注册 ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
|
||
key: 3,
|
||
class: "ghost-action",
|
||
type: "button",
|
||
onClick: backToLogin
|
||
}, " 返回登录 "))])]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7562:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5187);
|
||
/* harmony import */ var _MessageList_vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(9847);
|
||
/* harmony import */ var _MessageComposer_vue__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(1653);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(5051);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(7566);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(9045);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(926);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "chat-header"
|
||
};
|
||
const _hoisted_2 = ["src"];
|
||
const _hoisted_3 = {
|
||
key: 1,
|
||
class: "chat-title-avatar"
|
||
};
|
||
const _hoisted_4 = {
|
||
class: "chat-title-copy"
|
||
};
|
||
const _hoisted_5 = ["src"];
|
||
const _hoisted_6 = {
|
||
key: 1,
|
||
class: "chat-title-avatar"
|
||
};
|
||
const _hoisted_7 = {
|
||
class: "chat-title-copy"
|
||
};
|
||
const _hoisted_8 = {
|
||
key: 2
|
||
};
|
||
const _hoisted_9 = {
|
||
class: "header-actions chat-header-actions"
|
||
};
|
||
const _hoisted_10 = {
|
||
key: 0,
|
||
class: "empty-chat"
|
||
};
|
||
const _hoisted_11 = {
|
||
class: "pinned-message-preview"
|
||
};
|
||
const _hoisted_12 = ["src"];
|
||
const _hoisted_13 = {
|
||
key: 3,
|
||
class: "selection-toolbar"
|
||
};
|
||
const _hoisted_14 = {
|
||
class: "forward-dialog"
|
||
};
|
||
const _hoisted_15 = ["onClick"];
|
||
const _hoisted_16 = {
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_17 = {
|
||
type: "submit"
|
||
};
|
||
const _hoisted_18 = {
|
||
class: "group-dialog message-detail-dialog"
|
||
};
|
||
const _hoisted_19 = {
|
||
key: 0,
|
||
class: "group-loading"
|
||
};
|
||
const _hoisted_20 = {
|
||
class: "group-profile message-detail-meta"
|
||
};
|
||
const _hoisted_21 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_22 = {
|
||
key: 0,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_23 = {
|
||
class: "message-detail-summary"
|
||
};
|
||
const _hoisted_24 = {
|
||
class: "message-detail-groups"
|
||
};
|
||
const _hoisted_25 = {
|
||
class: "message-detail-section"
|
||
};
|
||
const _hoisted_26 = {
|
||
key: 0,
|
||
class: "message-detail-member-list"
|
||
};
|
||
const _hoisted_27 = ["src"];
|
||
const _hoisted_28 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_29 = {
|
||
class: "message-detail-member-main"
|
||
};
|
||
const _hoisted_30 = {
|
||
class: "message-detail-member-time"
|
||
};
|
||
const _hoisted_31 = {
|
||
key: 2,
|
||
class: "message-detail-role"
|
||
};
|
||
const _hoisted_32 = {
|
||
key: 1,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_33 = {
|
||
class: "message-detail-section"
|
||
};
|
||
const _hoisted_34 = {
|
||
key: 0,
|
||
class: "message-detail-member-list"
|
||
};
|
||
const _hoisted_35 = ["src"];
|
||
const _hoisted_36 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_37 = {
|
||
class: "message-detail-member-main"
|
||
};
|
||
const _hoisted_38 = {
|
||
class: "message-detail-member-time"
|
||
};
|
||
const _hoisted_39 = {
|
||
key: 2,
|
||
class: "message-detail-role"
|
||
};
|
||
const _hoisted_40 = {
|
||
key: 1,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_41 = {
|
||
class: "message-detail-section"
|
||
};
|
||
const _hoisted_42 = {
|
||
key: 0,
|
||
class: "message-detail-member-list"
|
||
};
|
||
const _hoisted_43 = ["src"];
|
||
const _hoisted_44 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_45 = {
|
||
class: "message-detail-member-main"
|
||
};
|
||
const _hoisted_46 = {
|
||
key: 2,
|
||
class: "message-detail-role"
|
||
};
|
||
const _hoisted_47 = {
|
||
key: 1,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_48 = {
|
||
class: "group-dialog single-profile-dialog"
|
||
};
|
||
const _hoisted_49 = {
|
||
class: "single-profile-summary"
|
||
};
|
||
const _hoisted_50 = ["src"];
|
||
const _hoisted_51 = {
|
||
key: 1,
|
||
class: "profile-avatar"
|
||
};
|
||
const _hoisted_52 = {
|
||
class: "group-profile"
|
||
};
|
||
const _hoisted_53 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_54 = {
|
||
class: "single-profile-footer"
|
||
};
|
||
const _hoisted_55 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_56 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_57 = ["disabled"];
|
||
const _hoisted_58 = ["disabled"];
|
||
const _hoisted_59 = {
|
||
key: 0,
|
||
class: "group-dialog"
|
||
};
|
||
const _hoisted_60 = {
|
||
key: 0,
|
||
class: "group-loading"
|
||
};
|
||
const _hoisted_61 = {
|
||
key: 1,
|
||
class: "group-profile"
|
||
};
|
||
const _hoisted_62 = ["disabled"];
|
||
const _hoisted_63 = ["disabled"];
|
||
const _hoisted_64 = ["disabled"];
|
||
const _hoisted_65 = {
|
||
key: 1,
|
||
class: "group-dialog"
|
||
};
|
||
const _hoisted_66 = {
|
||
key: 0,
|
||
class: "group-loading"
|
||
};
|
||
const _hoisted_67 = {
|
||
key: 1,
|
||
class: "group-member-list"
|
||
};
|
||
const _hoisted_68 = ["src"];
|
||
const _hoisted_69 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_70 = {
|
||
key: 0,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_71 = ["disabled"];
|
||
const _hoisted_72 = {
|
||
key: 3,
|
||
class: "group-dialog"
|
||
};
|
||
const _hoisted_73 = {
|
||
key: 0,
|
||
class: "group-loading"
|
||
};
|
||
const _hoisted_74 = {
|
||
key: 1,
|
||
class: "group-member-list"
|
||
};
|
||
const _hoisted_75 = ["onClick"];
|
||
const _hoisted_76 = ["src"];
|
||
const _hoisted_77 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_78 = {
|
||
key: 0,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_79 = ["disabled"];
|
||
const _hoisted_80 = {
|
||
key: 4,
|
||
class: "group-dialog group-management-dialog"
|
||
};
|
||
const _hoisted_81 = {
|
||
class: "group-management-tabs"
|
||
};
|
||
const _hoisted_82 = {
|
||
key: 0,
|
||
class: "group-loading"
|
||
};
|
||
const _hoisted_83 = {
|
||
key: 1,
|
||
class: "group-manage-section"
|
||
};
|
||
const _hoisted_84 = {
|
||
class: "group-member-list"
|
||
};
|
||
const _hoisted_85 = ["checked", "onChange"];
|
||
const _hoisted_86 = ["src"];
|
||
const _hoisted_87 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_88 = {
|
||
key: 0,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_89 = {
|
||
key: 2,
|
||
class: "group-manage-section"
|
||
};
|
||
const _hoisted_90 = {
|
||
key: 3,
|
||
class: "group-manage-section"
|
||
};
|
||
const _hoisted_91 = {
|
||
class: "group-member-list"
|
||
};
|
||
const _hoisted_92 = ["checked", "onChange"];
|
||
const _hoisted_93 = ["src"];
|
||
const _hoisted_94 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_95 = {
|
||
key: 0,
|
||
class: "contact-picker-empty"
|
||
};
|
||
const _hoisted_96 = ["disabled"];
|
||
const _hoisted_97 = {
|
||
key: 4,
|
||
class: "group-manage-section"
|
||
};
|
||
const _hoisted_98 = {
|
||
key: 0,
|
||
class: "mute-time-grid"
|
||
};
|
||
const _hoisted_99 = {
|
||
key: 1,
|
||
class: "mute-time-grid"
|
||
};
|
||
const _hoisted_100 = {
|
||
class: "mute-save-footer"
|
||
};
|
||
const _hoisted_101 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_102 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_103 = ["disabled"];
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'ChatPanel',
|
||
setup(__props) {
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_19__/* .useConversationStore */ .w)();
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_20__/* .useContactStore */ .p)();
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_21__/* .useSessionStore */ .B)();
|
||
const activeConversation = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => conversations.activeConversation);
|
||
const pinnedMessageIsImage = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
const message = conversations.activePinnedMessage;
|
||
return message?.attachment?.url && (message.type === 'image' || message.attachment.type === 'image');
|
||
});
|
||
const pinnedMessageText = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
const message = conversations.activePinnedMessage;
|
||
if (!message) return '';
|
||
const text = String(message.text || '').trim();
|
||
if (text && text !== '[消息]') return text;
|
||
const attachment = message.attachment || {};
|
||
if (message.type === 'image' || attachment.type === 'image') return attachment.name || '图片';
|
||
if (message.type === 'video' || attachment.type === 'video') return attachment.name || '视频';
|
||
if (attachment.url) return attachment.name || '文件';
|
||
return '[消息]';
|
||
});
|
||
const groupMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
|
||
const singleProfileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
|
||
const singleAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const singleProfileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
|
||
const singleProfileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const singleProfileError = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const groupPanel = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const groupBusy = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(false);
|
||
const groupDetail = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)(null);
|
||
const groupMembers = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
|
||
const groupAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const manageSection = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const selectedAdminIds = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
|
||
const selectedKickIds = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)([]);
|
||
const transferTargetId = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)({
|
||
name: '',
|
||
announcement: '',
|
||
welcomeText: ''
|
||
});
|
||
const muteDraft = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)({
|
||
mode: 'off',
|
||
scheduleType: 'once',
|
||
startsAtLocal: '',
|
||
endsAtLocal: '',
|
||
dailyStart: '09:00',
|
||
dailyEnd: '18:00'
|
||
});
|
||
const muteSaveNotice = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const muteSaveError = (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .ref */ .KR)('');
|
||
const singlePeerId = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
if (!activeConversation.value || isGroupConversation.value) {
|
||
return '';
|
||
}
|
||
return String(activeConversation.value.target || activeConversation.value.raw?.target || activeConversation.value.id?.replace(/^single-/, '') || '');
|
||
});
|
||
const singleContact = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
const peerId = singlePeerId.value;
|
||
if (!peerId) {
|
||
return null;
|
||
}
|
||
return contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || null;
|
||
});
|
||
const singleProfile = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
const contact = singleContact.value;
|
||
const conversation = activeConversation.value || {};
|
||
const rawUser = contact?.rawUser || {};
|
||
const displayName = contact?.alias || rawUser.displayName || rawUser.name || contact?.title || conversation.title || singlePeerId.value || '未知用户';
|
||
const rawName = rawUser.displayName || rawUser.name || contact?.title || conversation.title || '';
|
||
return {
|
||
uid: singlePeerId.value,
|
||
userId: rawUser.name || conversation.raw?.userId || singlePeerId.value,
|
||
displayName,
|
||
rawName,
|
||
mobile: rawUser.mobile || conversation.raw?.mobile || '',
|
||
address: rawUser.address || conversation.raw?.address || '',
|
||
portrait: contact?.portrait || conversation.portrait || '',
|
||
avatarText: String(displayName || '?').slice(0, 1).toUpperCase(),
|
||
alias: contact?.alias || ''
|
||
};
|
||
});
|
||
const groupDisplayId = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return String(groupDetail.value?.groupId || activeConversation.value?.raw?.groupId || activeConversation.value?.raw?.target || activeConversation.value?.target || activeConversation.value?.id?.replace(/^group-/, '') || '-');
|
||
});
|
||
const isGroupConversation = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return ['group', 'channel'].includes(activeConversation.value?.type) || activeConversation.value?.raw?.type === 'group';
|
||
});
|
||
const currentGroupRole = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return groupDetail.value?.myRole || activeConversation.value?.role || activeConversation.value?.raw?.role || '';
|
||
});
|
||
const isGroupOwner = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => currentGroupRole.value === 'owner');
|
||
const canManageGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => ['owner', 'admin'].includes(currentGroupRole.value));
|
||
const adminCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => groupMembers.value.filter(member => member.role !== 'owner'));
|
||
const transferableMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => groupMembers.value.filter(member => member.role !== 'owner'));
|
||
const messageDetail = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => conversations.messageDetail || null);
|
||
const messageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => messageDetail.value?.group || null);
|
||
const isMessageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return messageDetail.value?.conversationType === 'group' || Boolean(messageDetail.value?.group);
|
||
});
|
||
const messageDetailCounts = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return messageDetailGroup.value?.counts || {
|
||
read: 0,
|
||
unread: 0,
|
||
undelivered: 0,
|
||
total: 0
|
||
};
|
||
});
|
||
const kickCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
return groupMembers.value.filter(member => {
|
||
if (member.uid === session.userId || member.role === 'owner') {
|
||
return false;
|
||
}
|
||
if (currentGroupRole.value === 'admin') {
|
||
return member.role === 'member';
|
||
}
|
||
return currentGroupRole.value === 'owner';
|
||
});
|
||
});
|
||
const statusText = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .computed */ .EW)(() => {
|
||
if (activeConversation.value?.type === 'channel' && !conversations.canSendActiveConversation) {
|
||
return '公告群,仅管理员可发言';
|
||
}
|
||
return session.connectionStatusText || (session.connected ? '已连接' : '未连接');
|
||
});
|
||
function formatDetailTime(value) {
|
||
const timestamp = Number(value || 0);
|
||
if (!timestamp) {
|
||
return '暂无';
|
||
}
|
||
return new Intl.DateTimeFormat('zh-CN', {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
second: '2-digit',
|
||
hour12: false,
|
||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
||
}).format(timestamp);
|
||
}
|
||
function detailMemberName(member) {
|
||
return member?.name || member?.displayName || member?.rawName || member?.uid || '-';
|
||
}
|
||
function detailMemberAvatar(member) {
|
||
return String(detailMemberName(member) || '?').slice(0, 1).toUpperCase();
|
||
}
|
||
function detailRoleLabel(role) {
|
||
if (role === 'owner') {
|
||
return '群主';
|
||
}
|
||
if (role === 'admin') {
|
||
return '管理员';
|
||
}
|
||
return '';
|
||
}
|
||
function closeGroupMenu() {
|
||
groupMenuOpen.value = false;
|
||
}
|
||
function toggleGroupMenu() {
|
||
if (!isGroupConversation.value) {
|
||
return;
|
||
}
|
||
groupMenuOpen.value = !groupMenuOpen.value;
|
||
}
|
||
async function openSingleProfile() {
|
||
if (!activeConversation.value || isGroupConversation.value) {
|
||
return;
|
||
}
|
||
closeGroupMenu();
|
||
singleProfileNotice.value = '';
|
||
singleProfileError.value = '';
|
||
singleAliasDraft.value = singleProfile.value.alias || '';
|
||
singleProfileOpen.value = true;
|
||
contacts.refreshContacts().then(() => {
|
||
if (singleProfileOpen.value) {
|
||
singleAliasDraft.value = singleProfile.value.alias || '';
|
||
}
|
||
}).catch(() => {});
|
||
}
|
||
function closeSingleProfile() {
|
||
if (singleProfileSaving.value) {
|
||
return;
|
||
}
|
||
singleProfileOpen.value = false;
|
||
singleProfileNotice.value = '';
|
||
singleProfileError.value = '';
|
||
}
|
||
async function saveSingleAlias() {
|
||
const peerId = singleProfile.value.uid;
|
||
if (!peerId || singleProfileSaving.value) {
|
||
return;
|
||
}
|
||
singleProfileSaving.value = true;
|
||
singleProfileNotice.value = '';
|
||
singleProfileError.value = '';
|
||
try {
|
||
const ok = await contacts.updateContactAlias(peerId, singleAliasDraft.value);
|
||
if (!ok) {
|
||
singleProfileError.value = contacts.actionError || '备注名修改失败';
|
||
return;
|
||
}
|
||
await contacts.refreshContacts({
|
||
force: true
|
||
}).catch(() => {});
|
||
const refreshedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || singleContact.value;
|
||
const nextTitle = refreshedContact?.title || singleAliasDraft.value || singleProfile.value.rawName || singleProfile.value.displayName || peerId;
|
||
conversations.upsertConversation({
|
||
...activeConversation.value,
|
||
title: nextTitle,
|
||
portrait: refreshedContact?.portrait || activeConversation.value?.portrait || '',
|
||
avatarText: String(nextTitle || '?').slice(0, 1).toUpperCase(),
|
||
raw: {
|
||
...(activeConversation.value?.raw || {}),
|
||
target: peerId,
|
||
mobile: refreshedContact?.rawUser?.mobile || activeConversation.value?.raw?.mobile || '',
|
||
address: refreshedContact?.rawUser?.address || activeConversation.value?.raw?.address || '',
|
||
alias: refreshedContact?.alias || singleAliasDraft.value
|
||
}
|
||
});
|
||
singleAliasDraft.value = refreshedContact?.alias || singleAliasDraft.value;
|
||
singleProfileNotice.value = '备注名已保存';
|
||
} catch (error) {
|
||
singleProfileError.value = error.message || '备注名修改失败';
|
||
} finally {
|
||
singleProfileSaving.value = false;
|
||
}
|
||
}
|
||
function handleSenderProfileUpdated() {
|
||
contacts.refreshContacts({
|
||
force: true
|
||
}).catch(() => {});
|
||
conversations.syncActiveMessages({
|
||
allowReadReceipt: true
|
||
});
|
||
if (groupPanel.value === 'members') {
|
||
loadGroupMembers();
|
||
}
|
||
}
|
||
function closeGroupPanel() {
|
||
groupPanel.value = '';
|
||
groupBusy.value = false;
|
||
clearMuteSaveFeedback();
|
||
}
|
||
async function loadGroupDetail() {
|
||
if (!session.userId || !activeConversation.value?.target) {
|
||
return null;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
groupDetail.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.getGroupDetail(session.userId, activeConversation.value.target);
|
||
return groupDetail.value;
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '群资料加载失败');
|
||
return null;
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function openGroupOverview() {
|
||
if (!isGroupConversation.value) {
|
||
return;
|
||
}
|
||
closeGroupMenu();
|
||
groupPanel.value = 'overview';
|
||
await loadGroupDetail();
|
||
}
|
||
async function openGroupMembers() {
|
||
closeGroupMenu();
|
||
groupPanel.value = 'members';
|
||
await loadGroupMembers();
|
||
}
|
||
async function loadGroupMembers() {
|
||
groupBusy.value = true;
|
||
try {
|
||
groupMembers.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.getGroupMembers(session.userId, activeConversation.value.target);
|
||
selectedAdminIds.value = groupMembers.value.filter(member => member.role === 'admin').map(member => member.uid);
|
||
return groupMembers.value;
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '群员加载失败');
|
||
return [];
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function openGroupAlias() {
|
||
closeGroupMenu();
|
||
groupPanel.value = 'alias';
|
||
const detail = await loadGroupDetail();
|
||
groupAliasDraft.value = detail?.myAlias || '';
|
||
}
|
||
function msToLocalInput(value) {
|
||
const timestamp = Number(value || 0);
|
||
if (!timestamp) {
|
||
return '';
|
||
}
|
||
const date = new Date(timestamp);
|
||
const local = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
|
||
return local.toISOString().slice(0, 16);
|
||
}
|
||
function localInputToMs(value) {
|
||
return value ? new Date(value).getTime() : 0;
|
||
}
|
||
function prepareManagementDrafts() {
|
||
clearMuteSaveFeedback();
|
||
profileDraft.value = {
|
||
name: groupDetail.value?.name || activeConversation.value?.title || '',
|
||
announcement: groupDetail.value?.announcement || '',
|
||
welcomeText: groupDetail.value?.welcomeText || ''
|
||
};
|
||
const setting = groupDetail.value?.muteSetting || {};
|
||
muteDraft.value = {
|
||
mode: setting.mode || 'off',
|
||
scheduleType: setting.scheduleType || 'once',
|
||
startsAtLocal: msToLocalInput(setting.startsAtMs),
|
||
endsAtLocal: msToLocalInput(setting.endsAtMs),
|
||
dailyStart: setting.dailyStart || '09:00',
|
||
dailyEnd: setting.dailyEnd || '18:00'
|
||
};
|
||
}
|
||
function clearMuteSaveFeedback() {
|
||
muteSaveNotice.value = '';
|
||
muteSaveError.value = '';
|
||
}
|
||
async function openGroupManage() {
|
||
if (!canManageGroup.value) {
|
||
return;
|
||
}
|
||
closeGroupMenu();
|
||
groupPanel.value = 'manage';
|
||
manageSection.value = isGroupOwner.value ? 'admins' : 'profile';
|
||
await loadGroupDetail();
|
||
prepareManagementDrafts();
|
||
await loadGroupMembers();
|
||
}
|
||
async function openTransferGroup() {
|
||
groupPanel.value = 'transfer';
|
||
transferTargetId.value = '';
|
||
await loadGroupMembers();
|
||
}
|
||
async function saveGroupAlias() {
|
||
if (!activeConversation.value?.target || groupBusy.value) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
const alias = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupAlias(session.userId, activeConversation.value.target, groupAliasDraft.value);
|
||
groupDetail.value = {
|
||
...(groupDetail.value || {}),
|
||
myAlias: alias
|
||
};
|
||
conversations.setActionNotice('本群昵称已保存');
|
||
closeGroupPanel();
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '本群昵称保存失败');
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
function toggleAdmin(userId) {
|
||
const selected = new Set(selectedAdminIds.value);
|
||
if (selected.has(userId)) {
|
||
selected.delete(userId);
|
||
} else {
|
||
selected.add(userId);
|
||
}
|
||
selectedAdminIds.value = Array.from(selected);
|
||
}
|
||
function toggleKick(userId) {
|
||
const selected = new Set(selectedKickIds.value);
|
||
if (selected.has(userId)) {
|
||
selected.delete(userId);
|
||
} else {
|
||
selected.add(userId);
|
||
}
|
||
selectedKickIds.value = Array.from(selected);
|
||
}
|
||
async function saveGroupAdmins() {
|
||
if (!activeConversation.value?.target || groupBusy.value) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.setGroupAdmins(session.userId, activeConversation.value.target, selectedAdminIds.value);
|
||
groupMembers.value = groupMembers.value.map(member => {
|
||
if (member.role === 'owner') {
|
||
return member;
|
||
}
|
||
return {
|
||
...member,
|
||
role: selectedAdminIds.value.includes(member.uid) ? 'admin' : 'member'
|
||
};
|
||
});
|
||
conversations.setActionNotice('管理员已更新');
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '管理员设置失败');
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function saveGroupProfile() {
|
||
if (!activeConversation.value?.target || groupBusy.value) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupProfile(session.userId, activeConversation.value.target, profileDraft.value);
|
||
groupDetail.value = {
|
||
...(groupDetail.value || {}),
|
||
name: result.name,
|
||
announcement: result.announcement,
|
||
welcomeText: result.welcomeText
|
||
};
|
||
conversations.upsertConversation({
|
||
...activeConversation.value,
|
||
title: result.name,
|
||
avatarText: String(result.name || '?').slice(0, 1).toUpperCase(),
|
||
updatedAt: Number(result.updatedAt || Date.now())
|
||
});
|
||
conversations.setActionNotice('群资料已保存');
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '群资料保存失败');
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function kickSelectedMembers() {
|
||
if (!selectedKickIds.value.length || groupBusy.value) {
|
||
return;
|
||
}
|
||
if (!window.confirm('确认将所选成员移出群组?')) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.kickGroupMembers(session.userId, activeConversation.value.target, selectedKickIds.value);
|
||
const removed = new Set(result.removedIds || selectedKickIds.value);
|
||
groupMembers.value = groupMembers.value.filter(member => !removed.has(member.uid));
|
||
selectedKickIds.value = [];
|
||
conversations.setActionNotice('已移出群组');
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '踢人失败');
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function saveMuteSetting() {
|
||
if (!activeConversation.value?.target || groupBusy.value) {
|
||
return;
|
||
}
|
||
clearMuteSaveFeedback();
|
||
groupBusy.value = true;
|
||
try {
|
||
const setting = await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.updateGroupMuteSetting(session.userId, activeConversation.value.target, {
|
||
mode: muteDraft.value.mode,
|
||
scheduleType: muteDraft.value.scheduleType,
|
||
startsAtMs: localInputToMs(muteDraft.value.startsAtLocal),
|
||
endsAtMs: localInputToMs(muteDraft.value.endsAtLocal),
|
||
dailyStart: muteDraft.value.dailyStart,
|
||
dailyEnd: muteDraft.value.dailyEnd
|
||
});
|
||
groupDetail.value = {
|
||
...(groupDetail.value || {}),
|
||
muteSetting: setting
|
||
};
|
||
muteSaveNotice.value = '禁言设置已保存';
|
||
} catch (error) {
|
||
muteSaveError.value = error.message || '禁言设置保存失败';
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
async function leaveCurrentGroup() {
|
||
if (!activeConversation.value || groupBusy.value) {
|
||
return;
|
||
}
|
||
if (!window.confirm('确认退出该群组?')) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
const ok = await conversations.leaveGroup(activeConversation.value);
|
||
groupBusy.value = false;
|
||
if (ok) {
|
||
closeGroupPanel();
|
||
}
|
||
}
|
||
async function dismissCurrentGroup() {
|
||
if (!activeConversation.value || groupBusy.value) {
|
||
return;
|
||
}
|
||
if (!window.confirm('确认解散该群组?所有成员都将不可继续使用该群。')) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
const ok = await conversations.dismissGroup(activeConversation.value);
|
||
groupBusy.value = false;
|
||
if (ok) {
|
||
closeGroupPanel();
|
||
}
|
||
}
|
||
async function transferCurrentGroup() {
|
||
if (!activeConversation.value?.target || !transferTargetId.value || groupBusy.value) {
|
||
return;
|
||
}
|
||
if (!window.confirm('确认将群主转让给该成员?')) {
|
||
return;
|
||
}
|
||
groupBusy.value = true;
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_18__/* .imClient */ .wD.transferGroup(session.userId, activeConversation.value.target, transferTargetId.value);
|
||
groupDetail.value = {
|
||
...(groupDetail.value || {}),
|
||
myRole: 'member'
|
||
};
|
||
activeConversation.value.role = 'member';
|
||
if (activeConversation.value.raw) {
|
||
activeConversation.value.raw.role = 'member';
|
||
}
|
||
conversations.setActionNotice('群组已转让');
|
||
closeGroupPanel();
|
||
conversations.refreshRemoteConversations();
|
||
} catch (error) {
|
||
conversations.setActionError(error.message || '转让群组失败');
|
||
} finally {
|
||
groupBusy.value = false;
|
||
}
|
||
}
|
||
function memberAvatar(member) {
|
||
return String(member.displayName || member.uid || '?').slice(0, 1).toUpperCase();
|
||
}
|
||
document.addEventListener('click', closeGroupMenu);
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .onBeforeUnmount */ .xo)(() => {
|
||
document.removeEventListener('click', closeGroupMenu);
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .watch */ .wB)(() => activeConversation.value?.id, () => {
|
||
closeGroupMenu();
|
||
closeSingleProfile();
|
||
closeGroupPanel();
|
||
groupDetail.value = null;
|
||
groupMembers.value = [];
|
||
groupAliasDraft.value = '';
|
||
selectedAdminIds.value = [];
|
||
selectedKickIds.value = [];
|
||
transferTargetId.value = '';
|
||
manageSection.value = '';
|
||
});
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["chat-panel", {
|
||
'has-pinned-message': Boolean((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage)
|
||
}])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [isGroupConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 0,
|
||
type: "button",
|
||
class: "chat-title-button",
|
||
onClick: openGroupOverview
|
||
}, [activeConversation.value?.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "chat-title-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(activeConversation.value.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_2)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.avatarText || '?'), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.title || '未选择会话'), 1)])])) : activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 1,
|
||
type: "button",
|
||
class: "chat-title-button",
|
||
onClick: openSingleProfile
|
||
}, [singleProfile.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "chat-title-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(singleProfile.value.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_5)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_6, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(activeConversation.value?.title || '未选择会话'), 1)])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("h2", _hoisted_8, "未选择会话")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(statusText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_9, [_cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
class: "icon-button",
|
||
title: "搜索"
|
||
}, "⌕", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
class: "icon-button",
|
||
title: "更多",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(toggleGroupMenu, ["stop"])
|
||
}, "⋯"), groupMenuOpen.value && isGroupConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "quick-action-menu chat-more-menu",
|
||
onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: openGroupMembers
|
||
}, "查看群员"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: openGroupAlias
|
||
}, "我在本群的昵称"), canManageGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 0,
|
||
type: "button",
|
||
onClick: openGroupManage
|
||
}, "群组管理")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])]), !activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_10, _cache[32] || (_cache[32] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "选择一个会话", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "真实会话同步完成后,可以在左侧打开聊天", -1)]))) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), activeConversation.value && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 1,
|
||
type: "button",
|
||
class: "pinned-message-banner",
|
||
title: "点击定位该消息",
|
||
onClick: _cache[2] || (_cache[2] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).focusMessage((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage))
|
||
}, [_cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "📌", -1)), _cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "置顶消息", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_11, [pinnedMessageIsImage.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage.attachment.url),
|
||
alt: "置顶图片"
|
||
}, null, 8, _hoisted_12)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(pinnedMessageText.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", {
|
||
class: "pinned-message-close",
|
||
title: "取消置顶",
|
||
onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearPinnedMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearPinnedMessage(...args), ["stop"]))
|
||
}, "×")])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), activeConversation.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createBlock */ .Wv)(_MessageList_vue__WEBPACK_IMPORTED_MODULE_16__/* ["default"] */ .A, {
|
||
key: 2,
|
||
messages: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activeMessages,
|
||
"selection-mode": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectionMode,
|
||
"selected-message-ids": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectedMessageIds,
|
||
"favorite-message-ids": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).favoriteMessageIds,
|
||
"pinned-message-id": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).activePinnedMessage?.key || '',
|
||
"attention-message-id": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).attentionMessageId,
|
||
"can-recall-others": canManageGroup.value && isGroupConversation.value,
|
||
onMessageAction: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).handleMessageAction,
|
||
onToggleSelect: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).toggleSelectedMessage,
|
||
onSenderProfileUpdated: handleSenderProfileUpdated
|
||
}, null, 8, ["messages", "selection-mode", "selected-message-ids", "favorite-message-ids", "pinned-message-id", "attention-message-id", "can-recall-others", "onMessageAction", "onToggleSelect"])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectionMode ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "已选 " + (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).selectedMessageIds.length) + " 条", 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[3] || (_cache[3] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).copySelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).copySelectedMessages(...args))
|
||
}, "复制"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[4] || (_cache[4] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).deleteSelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).deleteSelectedMessages(...args))
|
||
}, "删除"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[5] || (_cache[5] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).startForwardSelectedMessages && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).startForwardSelectedMessages(...args))
|
||
}, "转发"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[6] || (_cache[6] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearSelection && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).clearSelection(...args))
|
||
}, "取消")])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createVNode */ .bF)(_MessageComposer_vue__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A, {
|
||
disabled: !activeConversation.value || !(0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(session).isAuthenticated || !(0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).canSendActiveConversation,
|
||
"quote-message": (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).quotedMessage,
|
||
onCancelQuote: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelQuote,
|
||
onSend: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).sendText,
|
||
onSendAttachment: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).sendAttachment
|
||
}, null, 8, ["disabled", "quote-message", "onCancelQuote", "onSend", "onSendAttachment"]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).forwardingMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 4,
|
||
class: "modal-backdrop",
|
||
onClick: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward(...args), ["self"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[35] || (_cache[35] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "转发给", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: _cache[7] || (_cache[7] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelForward(...args))
|
||
}, "×")]), ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).conversations, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: item.id,
|
||
type: "button",
|
||
class: "forward-target",
|
||
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeForward(item.id)
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(item.avatarText), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(item.title), 1)], 8, _hoisted_15);
|
||
}), 128))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 5,
|
||
class: "modal-backdrop",
|
||
onClick: _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args), ["self"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("form", {
|
||
class: "edit-dialog",
|
||
onSubmit: _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).completeEditMessage(...args), ["prevent"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMode === 'resend' ? '重新编辑' : '编辑消息'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: _cache[9] || (_cache[9] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args))
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingText = $event),
|
||
maxlength: "5000",
|
||
rows: "5",
|
||
autofocus: ""
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingText]]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[11] || (_cache[11] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).cancelEditMessage(...args))
|
||
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).editingMode === 'resend' ? '发送' : '保存'), 1)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 6,
|
||
class: "modal-backdrop",
|
||
onClick: _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)((...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail(...args), ["self"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "消息详情", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: _cache[14] || (_cache[14] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail && (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).closeMessageDetail(...args))
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailLoading ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_19, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dl", _hoisted_20, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[37] || (_cache[37] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "发送时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(messageDetail.value?.sentAt)), 1)]), messageDetail.value?.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_21, [_cache[38] || (_cache[38] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "编辑时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(messageDetail.value.editedAt)), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[39] || (_cache[39] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "发送人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(messageDetail.value?.sender)), 1)]), !isMessageDetailGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[40] || (_cache[40] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "接收人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(messageDetail.value?.receiver)), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[41] || (_cache[41] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "送达时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
'message-detail-muted': !messageDetail.value?.deliveredAt
|
||
})
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetail.value?.deliveredAt ? formatDetailTime(messageDetail.value.deliveredAt) : '未送达'), 3)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[42] || (_cache[42] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "已读时间", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
'message-detail-muted': !messageDetail.value?.readAt
|
||
})
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetail.value?.readAt ? formatDetailTime(messageDetail.value.readAt) : '未读'), 3)])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailError ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_22, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).messageDetailError), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), isMessageDetailGroup.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_23, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[43] || (_cache[43] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("已读 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.read || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[44] || (_cache[44] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("未读 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.unread || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[45] || (_cache[45] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("未送达 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.undelivered || 0), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [_cache[46] || (_cache[46] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createTextVNode */ .eW)("成员 ")), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.total || 0), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[47] || (_cache[47] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "已读", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.read || 0) + " 人", 1)]), messageDetailGroup.value?.read?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_26, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.read, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: `read-${member.uid}`,
|
||
class: "message-detail-member-row"
|
||
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_27)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_29, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_30, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(member.time)), 1), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_31, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
|
||
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_32, "暂无已读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_33, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[48] || (_cache[48] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "未读", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.unread || 0) + " 人", 1)]), messageDetailGroup.value?.unread?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_34, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.unread, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: `unread-${member.uid}`,
|
||
class: "message-detail-member-row"
|
||
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_35)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_36, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_37, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_38, "送达 " + (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(formatDetailTime(member.time)), 1), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_39, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
|
||
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_40, "暂无未读成员"))]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_41, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[49] || (_cache[49] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, "未送达", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(messageDetailCounts.value.undelivered || 0) + " 人", 1)]), messageDetailGroup.value?.undelivered?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_42, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(messageDetailGroup.value.undelivered, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: `undelivered-${member.uid}`,
|
||
class: "message-detail-member-row"
|
||
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_43)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_44, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", _hoisted_45, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailMemberName(member)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.uid), 1)]), _cache[50] || (_cache[50] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", {
|
||
class: "message-detail-member-time message-detail-muted"
|
||
}, "未送达", -1)), detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_46, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(detailRoleLabel(member.role)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]);
|
||
}), 128))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_47, "暂无未送达成员"))])])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)], 64))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), singleProfileOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 7,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(closeSingleProfile, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("section", _hoisted_48, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[51] || (_cache[51] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "联系人资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeSingleProfile
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_49, [singleProfile.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "profile-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(singleProfile.value.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_50)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_51, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.displayName), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dl", _hoisted_52, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[52] || (_cache[52] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.userId || '-'), 1)]), singleProfile.value.uid && singleProfile.value.uid !== singleProfile.value.userId ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_53, [_cache[53] || (_cache[53] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "用户UID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.uid), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[54] || (_cache[54] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.rawName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[55] || (_cache[55] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.mobile || '未知'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[56] || (_cache[56] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfile.value.address || '未知'), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[57] || (_cache[57] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "备注名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[16] || (_cache[16] = $event => singleAliasDraft.value = $event),
|
||
maxlength: "32",
|
||
autocomplete: "off",
|
||
placeholder: "留空使用对方昵称"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, singleAliasDraft.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", _hoisted_54, [singleProfileNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_55, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileNotice.value), 1)) : singleProfileError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_56, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
disabled: singleProfileSaving.value,
|
||
onClick: closeSingleProfile
|
||
}, "取消", 8, _hoisted_57), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: singleProfileSaving.value || !singleProfile.value.uid,
|
||
onClick: saveSingleAlias
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(singleProfileSaving.value ? '保存中...' : '保存备注'), 9, _hoisted_58)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), groupPanel.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 8,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(closeGroupPanel, ["self"])
|
||
}, [groupPanel.value === 'overview' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_59, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[58] || (_cache[58] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群概况", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeGroupPanel
|
||
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_60, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("dl", _hoisted_61, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[59] || (_cache[59] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.name || activeConversation.value?.title || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[60] || (_cache[60] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDisplayId.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[61] || (_cache[61] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.announcement || '未设置'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", null, [_cache[62] || (_cache[62] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dt", null, "群主昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupDetail.value?.ownerName || '-'), 1)])])), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [isGroupOwner.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, {
|
||
key: 0
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "danger-inline-action",
|
||
disabled: groupBusy.value,
|
||
onClick: dismissCurrentGroup
|
||
}, "解散群组", 8, _hoisted_62), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: groupBusy.value,
|
||
onClick: openTransferGroup
|
||
}, "转让群组", 8, _hoisted_63)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 1,
|
||
type: "button",
|
||
class: "danger-inline-action",
|
||
disabled: groupBusy.value,
|
||
onClick: leaveCurrentGroup
|
||
}, "退出群组", 8, _hoisted_64))])])) : groupPanel.value === 'members' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_65, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[63] || (_cache[63] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群员", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeGroupPanel
|
||
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_66, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_67, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(groupMembers.value, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: member.uid,
|
||
class: "group-member-row"
|
||
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_68)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_69, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.role === 'owner' ? '群主' : member.rawDisplayName), 1)])]);
|
||
}), 128)), !groupMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_70, "暂无群员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]))])) : groupPanel.value === 'alias' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("form", {
|
||
key: 2,
|
||
class: "group-dialog",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_12__/* .withModifiers */ .D$)(saveGroupAlias, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[64] || (_cache[64] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "我在本群的昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeGroupPanel
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[65] || (_cache[65] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[17] || (_cache[17] = $event => groupAliasDraft.value = $event),
|
||
maxlength: "64",
|
||
autocomplete: "off",
|
||
placeholder: "留空使用个人昵称"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, groupAliasDraft.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: closeGroupPanel
|
||
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-inline-action",
|
||
disabled: groupBusy.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(groupBusy.value ? '保存中...' : '保存'), 9, _hoisted_71)])], 32)) : groupPanel.value === 'transfer' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_72, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[66] || (_cache[66] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "转让群组", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeGroupPanel
|
||
}, "×")]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_73, "正在加载")) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_74, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(transferableMembers.value, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: member.uid,
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["group-member-row selectable", {
|
||
selected: transferTargetId.value === member.uid
|
||
}]),
|
||
onClick: $event => transferTargetId.value = member.uid
|
||
}, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_76)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_77, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.rawDisplayName), 1)])], 10, _hoisted_75);
|
||
}), 128)), !transferableMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_78, "暂无可转让成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: closeGroupPanel
|
||
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: groupBusy.value || !transferTargetId.value,
|
||
onClick: transferCurrentGroup
|
||
}, "确认转让", 8, _hoisted_79)])])) : groupPanel.value === 'manage' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_80, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("header", null, [_cache[67] || (_cache[67] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("h3", null, "群组管理", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeGroupPanel
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("nav", _hoisted_81, [isGroupOwner.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("button", {
|
||
key: 0,
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
active: manageSection.value === 'admins'
|
||
}),
|
||
onClick: _cache[18] || (_cache[18] = $event => manageSection.value = 'admins')
|
||
}, "管理员设置", 2)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
active: manageSection.value === 'profile'
|
||
}),
|
||
onClick: _cache[19] || (_cache[19] = $event => manageSection.value = 'profile')
|
||
}, "修改群资料", 2), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
active: manageSection.value === 'kick'
|
||
}),
|
||
onClick: _cache[20] || (_cache[20] = $event => manageSection.value = 'kick')
|
||
}, "踢人", 2), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)({
|
||
active: manageSection.value === 'mute'
|
||
}),
|
||
onClick: _cache[21] || (_cache[21] = $event => manageSection.value = 'mute')
|
||
}, "禁言设置", 2)]), groupBusy.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_82, "正在加载")) : manageSection.value === 'admins' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_83, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_84, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(adminCandidateMembers.value, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("label", {
|
||
key: member.uid,
|
||
class: "group-member-row selectable with-check"
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
type: "checkbox",
|
||
checked: selectedAdminIds.value.includes(member.uid),
|
||
onChange: $event => toggleAdmin(member.uid)
|
||
}, null, 40, _hoisted_85), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_86)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_87, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.rawDisplayName), 1)])]);
|
||
}), 128)), !adminCandidateMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_88, "暂无可设置成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
onClick: saveGroupAdmins
|
||
}, "保存管理员")])])) : manageSection.value === 'profile' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_89, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[68] || (_cache[68] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[22] || (_cache[22] = $event => profileDraft.value.name = $event),
|
||
maxlength: "128",
|
||
autocomplete: "off"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.name, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[69] || (_cache[69] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[23] || (_cache[23] = $event => profileDraft.value.announcement = $event),
|
||
maxlength: "1000",
|
||
rows: "3"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.announcement, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[70] || (_cache[70] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "欢迎词", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[24] || (_cache[24] = $event => profileDraft.value.welcomeText = $event),
|
||
maxlength: "1000",
|
||
rows: "3"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, profileDraft.value.welcomeText, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
onClick: saveGroupProfile
|
||
}, "保存资料")])])) : manageSection.value === 'kick' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_90, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("div", _hoisted_91, [((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_13__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .renderList */ .pI)(kickCandidateMembers.value, member => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("label", {
|
||
key: member.uid,
|
||
class: "group-member-row selectable with-check"
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
type: "checkbox",
|
||
checked: selectedKickIds.value.includes(member.uid),
|
||
onChange: $event => toggleKick(member.uid)
|
||
}, null, 40, _hoisted_92), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(member.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_93)) : ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_94, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(memberAvatar(member)), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.displayName), 1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(member.role === 'admin' ? '管理员' : member.rawDisplayName), 1)])]);
|
||
}), 128)), !kickCandidateMembers.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_95, "暂无可移除成员")) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", null, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "danger-inline-action",
|
||
disabled: !selectedKickIds.value.length,
|
||
onClick: kickSelectedMembers
|
||
}, "移出群组", 8, _hoisted_96)])])) : manageSection.value === 'mute' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("section", _hoisted_97, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[72] || (_cache[72] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "禁言模式", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("select", {
|
||
"onUpdate:modelValue": _cache[25] || (_cache[25] = $event => muteDraft.value.mode = $event),
|
||
onChange: clearMuteSaveFeedback
|
||
}, _cache[71] || (_cache[71] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "off"
|
||
}, "关闭禁言", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "all_include_admins"
|
||
}, "全体禁言包含管理员", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "all_except_admins"
|
||
}, "除管理员外全体禁言", -1)]), 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelSelect */ .u1, muteDraft.value.mode]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[74] || (_cache[74] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "时段类型", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("select", {
|
||
"onUpdate:modelValue": _cache[26] || (_cache[26] = $event => muteDraft.value.scheduleType = $event),
|
||
onChange: clearMuteSaveFeedback
|
||
}, _cache[73] || (_cache[73] = [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "manual"
|
||
}, "立即禁言直到管理解除", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "once"
|
||
}, "单次", -1), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("option", {
|
||
value: "daily"
|
||
}, "每天固定时段", -1)]), 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelSelect */ .u1, muteDraft.value.scheduleType]])]), muteDraft.value.mode !== 'off' && muteDraft.value.scheduleType === 'once' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_98, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[75] || (_cache[75] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "开始", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[27] || (_cache[27] = $event => muteDraft.value.startsAtLocal = $event),
|
||
type: "datetime-local",
|
||
onInput: clearMuteSaveFeedback
|
||
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.startsAtLocal]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[76] || (_cache[76] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "结束", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[28] || (_cache[28] = $event => muteDraft.value.endsAtLocal = $event),
|
||
type: "datetime-local",
|
||
onInput: clearMuteSaveFeedback
|
||
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.endsAtLocal]])])])) : muteDraft.value.mode !== 'off' && muteDraft.value.scheduleType === 'daily' ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", _hoisted_99, [(0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[77] || (_cache[77] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "开始", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[29] || (_cache[29] = $event => muteDraft.value.dailyStart = $event),
|
||
type: "time",
|
||
onInput: clearMuteSaveFeedback
|
||
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.dailyStart]])]), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("label", null, [_cache[78] || (_cache[78] = (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("span", null, "结束", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[30] || (_cache[30] = $event => muteDraft.value.dailyEnd = $event),
|
||
type: "time",
|
||
onInput: clearMuteSaveFeedback
|
||
}, null, 544), [[vue__WEBPACK_IMPORTED_MODULE_12__/* .vModelText */ .Jo, muteDraft.value.dailyEnd]])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("footer", _hoisted_100, [muteSaveNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_101, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(muteSaveNotice.value), 1)) : muteSaveError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("span", _hoisted_102, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)(muteSaveError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: groupBusy.value,
|
||
onClick: saveMuteSetting
|
||
}, "保存禁言", 8, _hoisted_103)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionNotice || (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_13__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createElementBlock */ .CE)("div", {
|
||
key: 9,
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .normalizeClass */ .C4)(["chat-toast", {
|
||
error: (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError
|
||
}])
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_15__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionError || (0,vue__WEBPACK_IMPORTED_MODULE_14__/* .unref */ .R1)(conversations).actionNotice), 3)) : (0,vue__WEBPACK_IMPORTED_MODULE_13__/* .createCommentVNode */ .Q3)("", true)], 2);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 6935:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5187);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(144);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
key: 0,
|
||
class: "quote-preview"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "composer-tools"
|
||
};
|
||
const _hoisted_3 = ["disabled"];
|
||
const _hoisted_4 = ["disabled"];
|
||
const _hoisted_5 = ["disabled"];
|
||
const _hoisted_6 = ["onClick"];
|
||
const _hoisted_7 = ["disabled", "onKeydown"];
|
||
const _hoisted_8 = {
|
||
class: "composer-footer"
|
||
};
|
||
const _hoisted_9 = ["disabled"];
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'MessageComposer',
|
||
props: {
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
quoteMessage: {
|
||
type: Object,
|
||
default: null
|
||
}
|
||
},
|
||
emits: ['send', 'send-attachment', 'cancel-quote'],
|
||
setup(__props, {
|
||
emit: __emit
|
||
}) {
|
||
const props = __props;
|
||
const emit = __emit;
|
||
const text = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)('');
|
||
const emojiOpen = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(false);
|
||
const dropActive = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(false);
|
||
const textareaEl = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
|
||
const imageInput = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
|
||
const fileInput = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
|
||
let dragDepth = 0;
|
||
const emojiList = ['😀', '😄', '😂', '😊', '😍', '😘', '😎', '😢', '😡', '👍', '🙏', '👏', '💪', '🎉', '❤️', '🔥', '🌹', '☕', '✅', '⭐', '💰', '🎁', '🤝', '👌'];
|
||
function submit() {
|
||
const value = text.value.trim();
|
||
if (!value) {
|
||
return;
|
||
}
|
||
emit('send', value);
|
||
text.value = '';
|
||
emojiOpen.value = false;
|
||
}
|
||
function toggleEmojiPicker() {
|
||
emojiOpen.value = !emojiOpen.value;
|
||
}
|
||
function insertEmoji(emoji) {
|
||
const element = textareaEl.value;
|
||
if (!element) {
|
||
text.value += emoji;
|
||
return;
|
||
}
|
||
const start = element.selectionStart ?? text.value.length;
|
||
const end = element.selectionEnd ?? text.value.length;
|
||
text.value = `${text.value.slice(0, start)}${emoji}${text.value.slice(end)}`;
|
||
requestAnimationFrame(() => {
|
||
element.focus();
|
||
const cursor = start + emoji.length;
|
||
element.setSelectionRange(cursor, cursor);
|
||
});
|
||
}
|
||
function chooseImage() {
|
||
imageInput.value?.click();
|
||
}
|
||
function chooseFile() {
|
||
fileInput.value?.click();
|
||
}
|
||
function attachmentTypeForFile(file, fallbackType = 'file') {
|
||
if (file?.type?.startsWith('image/')) {
|
||
return 'image';
|
||
}
|
||
return fallbackType === 'image' ? 'image' : 'file';
|
||
}
|
||
function emitFiles(files, fallbackType = 'file') {
|
||
if (props.disabled) {
|
||
return;
|
||
}
|
||
const validFiles = Array.from(files || []).filter(file => file instanceof File && file.size > 0);
|
||
if (!validFiles.length) {
|
||
return;
|
||
}
|
||
const caption = text.value.trim();
|
||
validFiles.forEach((file, index) => {
|
||
emit('send-attachment', {
|
||
type: attachmentTypeForFile(file, fallbackType),
|
||
file,
|
||
text: index === 0 ? caption : ''
|
||
});
|
||
});
|
||
text.value = '';
|
||
emojiOpen.value = false;
|
||
}
|
||
function selectAttachment(event, type) {
|
||
const input = event.target;
|
||
const files = input.files ? Array.from(input.files) : [];
|
||
input.value = '';
|
||
if (!files.length || props.disabled) {
|
||
return;
|
||
}
|
||
emitFiles(files, type);
|
||
}
|
||
function hasDraggedFiles(event) {
|
||
const types = Array.from(event.dataTransfer?.types || []);
|
||
return types.includes('Files');
|
||
}
|
||
function handleDragEnter(event) {
|
||
if (props.disabled || !hasDraggedFiles(event)) {
|
||
return;
|
||
}
|
||
dragDepth += 1;
|
||
dropActive.value = true;
|
||
event.dataTransfer.dropEffect = 'copy';
|
||
}
|
||
function handleDragOver(event) {
|
||
if (props.disabled || !hasDraggedFiles(event)) {
|
||
return;
|
||
}
|
||
dropActive.value = true;
|
||
event.dataTransfer.dropEffect = 'copy';
|
||
}
|
||
function handleDragLeave() {
|
||
dragDepth = Math.max(0, dragDepth - 1);
|
||
if (dragDepth === 0) {
|
||
dropActive.value = false;
|
||
}
|
||
}
|
||
function filesFromDataTransfer(dataTransfer) {
|
||
const items = Array.from(dataTransfer?.items || []);
|
||
const files = items.filter(item => item.kind === 'file' && !item.webkitGetAsEntry?.()?.isDirectory).map(item => item.getAsFile()).filter(Boolean);
|
||
if (files.length) {
|
||
return files;
|
||
}
|
||
return Array.from(dataTransfer?.files || []);
|
||
}
|
||
function handleDrop(event) {
|
||
dragDepth = 0;
|
||
dropActive.value = false;
|
||
if (props.disabled) {
|
||
return;
|
||
}
|
||
emitFiles(filesFromDataTransfer(event.dataTransfer));
|
||
}
|
||
function imageFilesFromClipboard(clipboardData) {
|
||
return Array.from(clipboardData?.items || []).filter(item => item.kind === 'file' && item.type.startsWith('image/')).map(item => item.getAsFile()).filter(Boolean);
|
||
}
|
||
function handlePaste(event) {
|
||
if (props.disabled) {
|
||
return;
|
||
}
|
||
const imageFiles = imageFilesFromClipboard(event.clipboardData);
|
||
if (!imageFiles.length) {
|
||
return;
|
||
}
|
||
event.preventDefault();
|
||
emitFiles(imageFiles, 'image');
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("form", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .normalizeClass */ .C4)(["message-composer", {
|
||
'drop-active': dropActive.value
|
||
}]),
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(submit, ["prevent"]),
|
||
onDragenter: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragEnter, ["prevent"]),
|
||
onDragover: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragOver, ["prevent"]),
|
||
onDragleave: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDragLeave, ["prevent"]),
|
||
onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(handleDrop, ["prevent"]),
|
||
onPaste: handlePaste
|
||
}, [__props.quoteMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("strong", null, "引用", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createTextVNode */ .eW)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .toDisplayString */ .v_)(__props.quoteMessage.quoteText || __props.quoteMessage.text), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "取消引用",
|
||
onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('cancel-quote'))
|
||
}, "×")])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "表情",
|
||
disabled: __props.disabled,
|
||
onClick: toggleEmojiPicker
|
||
}, "☺", 8, _hoisted_3), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "图片",
|
||
disabled: __props.disabled,
|
||
onClick: chooseImage
|
||
}, "▧", 8, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "文件",
|
||
disabled: __props.disabled,
|
||
onClick: chooseFile
|
||
}, "▤", 8, _hoisted_5), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("input", {
|
||
ref_key: "imageInput",
|
||
ref: imageInput,
|
||
type: "file",
|
||
accept: "image/*",
|
||
multiple: "",
|
||
onChange: _cache[1] || (_cache[1] = $event => selectAttachment($event, 'image'))
|
||
}, null, 544), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("input", {
|
||
ref_key: "fileInput",
|
||
ref: fileInput,
|
||
type: "file",
|
||
multiple: "",
|
||
onChange: _cache[2] || (_cache[2] = $event => selectAttachment($event, 'file'))
|
||
}, null, 544), emojiOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "emoji-picker",
|
||
onClick: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_6__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .renderList */ .pI)(emojiList, emoji => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
key: emoji,
|
||
type: "button",
|
||
onClick: $event => insertEmoji(emoji)
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .toDisplayString */ .v_)(emoji), 9, _hoisted_6);
|
||
}), 64))])) : (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("textarea", {
|
||
ref_key: "textareaEl",
|
||
ref: textareaEl,
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => text.value = $event),
|
||
disabled: __props.disabled,
|
||
placeholder: "输入消息",
|
||
rows: "3",
|
||
onKeydown: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withKeys */ .jR)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .withModifiers */ .D$)(submit, ["exact", "prevent"]), ["enter"])
|
||
}, null, 40, _hoisted_7), [[vue__WEBPACK_IMPORTED_MODULE_5__/* .vModelText */ .Jo, text.value]]), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("div", _hoisted_8, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("span", null, "Enter 发送,Shift + Enter 换行", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .createElementVNode */ .Lk)("button", {
|
||
class: "send-button",
|
||
disabled: __props.disabled || !text.value.trim()
|
||
}, "发送", 8, _hoisted_9)])], 34);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4021:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(9045);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const _hoisted_1 = ["data-message-key", "onClick"];
|
||
const _hoisted_2 = {
|
||
key: 0,
|
||
class: "system-message-pill"
|
||
};
|
||
const _hoisted_3 = {
|
||
key: 1,
|
||
class: "message-select"
|
||
};
|
||
const _hoisted_4 = ["checked", "onChange"];
|
||
const _hoisted_5 = ["title", "onClick"];
|
||
const _hoisted_6 = ["src"];
|
||
const _hoisted_7 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_8 = {
|
||
key: 3,
|
||
class: "message-stack"
|
||
};
|
||
const _hoisted_9 = ["onClick"];
|
||
const _hoisted_10 = {
|
||
key: 0,
|
||
class: "message-sender-role"
|
||
};
|
||
const _hoisted_11 = ["onContextmenu"];
|
||
const _hoisted_12 = {
|
||
key: 0,
|
||
class: "red-packet-card"
|
||
};
|
||
const _hoisted_13 = {
|
||
class: "red-packet-card-main"
|
||
};
|
||
const _hoisted_14 = {
|
||
key: 1,
|
||
class: "red-packet-receipt"
|
||
};
|
||
const _hoisted_15 = ["onClick"];
|
||
const _hoisted_16 = ["src", "alt"];
|
||
const _hoisted_17 = ["src"];
|
||
const _hoisted_18 = ["href"];
|
||
const _hoisted_19 = {
|
||
class: "message-file-main"
|
||
};
|
||
const _hoisted_20 = {
|
||
key: 5
|
||
};
|
||
const _hoisted_21 = {
|
||
key: 0,
|
||
class: "recall-mark"
|
||
};
|
||
const _hoisted_22 = {
|
||
key: 1,
|
||
class: "edit-mark"
|
||
};
|
||
const _hoisted_23 = {
|
||
key: 2,
|
||
class: "favorite-mark",
|
||
title: "已收藏",
|
||
"aria-label": "已收藏"
|
||
};
|
||
const _hoisted_24 = ["title", "aria-label"];
|
||
const _hoisted_25 = {
|
||
key: 0,
|
||
class: "delivery-check delivery-check-second"
|
||
};
|
||
const _hoisted_26 = {
|
||
key: 4,
|
||
class: "delivery-error"
|
||
};
|
||
const _hoisted_27 = ["onClick"];
|
||
const _hoisted_28 = ["src", "alt"];
|
||
const _hoisted_29 = {
|
||
class: "sender-profile-main"
|
||
};
|
||
const _hoisted_30 = ["src"];
|
||
const _hoisted_31 = {
|
||
key: 1,
|
||
class: "profile-avatar"
|
||
};
|
||
const _hoisted_32 = {
|
||
key: 2
|
||
};
|
||
const _hoisted_33 = {
|
||
class: "sender-profile-fields"
|
||
};
|
||
const _hoisted_34 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_35 = {
|
||
class: "sender-profile-alias"
|
||
};
|
||
const _hoisted_36 = ["disabled"];
|
||
const _hoisted_37 = {
|
||
class: "sender-profile-actions"
|
||
};
|
||
const _hoisted_38 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_39 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_40 = ["disabled"];
|
||
const _hoisted_41 = ["disabled"];
|
||
|
||
|
||
|
||
const IMAGE_MIN_SCALE = 0.5;
|
||
const IMAGE_MAX_SCALE = 6;
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'MessageList',
|
||
props: {
|
||
messages: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
selectionMode: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
selectedMessageIds: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
favoriteMessageIds: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
pinnedMessageId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
attentionMessageId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
canRecallOthers: {
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
},
|
||
emits: ['message-action', 'toggle-select', 'sender-profile-updated'],
|
||
setup(__props, {
|
||
emit: __emit
|
||
}) {
|
||
const props = __props;
|
||
const emit = __emit;
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_10__/* .useContactStore */ .p)();
|
||
const listEl = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
|
||
const viewerStage = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .ref */ .KR)(null);
|
||
const contextMenu = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
|
||
visible: false,
|
||
x: 0,
|
||
y: 0,
|
||
message: null
|
||
});
|
||
const imageViewer = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
|
||
visible: false,
|
||
url: '',
|
||
name: '',
|
||
sourceUrl: '',
|
||
index: 0,
|
||
scale: 1,
|
||
rotation: 0,
|
||
offsetX: 0,
|
||
offsetY: 0,
|
||
dragging: false,
|
||
dragStartX: 0,
|
||
dragStartY: 0,
|
||
dragOffsetX: 0,
|
||
dragOffsetY: 0
|
||
});
|
||
const senderProfile = (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .reactive */ .Kh)({
|
||
visible: false,
|
||
uid: '',
|
||
userId: '',
|
||
displayName: '',
|
||
rawName: '',
|
||
mobile: '',
|
||
address: '',
|
||
portrait: '',
|
||
avatarText: '',
|
||
role: '',
|
||
roleLabel: '',
|
||
contactAlias: '',
|
||
groupAlias: '',
|
||
isContact: false,
|
||
aliasDraft: '',
|
||
saving: false,
|
||
adding: false,
|
||
notice: '',
|
||
error: ''
|
||
});
|
||
const imageViewerStyle = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => ({
|
||
transform: `translate3d(${imageViewer.offsetX}px, ${imageViewer.offsetY}px, 0) scale(${imageViewer.scale}) rotate(${imageViewer.rotation}deg)`
|
||
}));
|
||
const viewerImages = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => props.messages.filter(message => isImageMessage(message)));
|
||
const menuItems = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .computed */ .EW)(() => {
|
||
if (!contextMenu.message) {
|
||
return [];
|
||
}
|
||
const isOwnMessage = contextMenu.message.direction === 'out';
|
||
if (isRecalledMessage(contextMenu.message)) {
|
||
return [...(isOwnMessage ? [{
|
||
action: 'edit',
|
||
label: '编辑'
|
||
}] : []), {
|
||
action: 'copy',
|
||
label: '复制'
|
||
}, {
|
||
action: 'delete',
|
||
label: '删除'
|
||
}, {
|
||
action: 'detail',
|
||
label: '详情'
|
||
}];
|
||
}
|
||
const favoriteLabel = isFavorite(contextMenu.message) ? '取消收藏' : '收藏';
|
||
const pinnedLabel = props.pinnedMessageId === messageIdentity(contextMenu.message) ? '取消置顶' : '置顶';
|
||
const items = [{
|
||
action: 'copy',
|
||
label: '复制'
|
||
}, {
|
||
action: 'delete',
|
||
label: '删除'
|
||
}, {
|
||
action: 'forward',
|
||
label: '转发'
|
||
}, {
|
||
action: 'favorite',
|
||
label: favoriteLabel
|
||
}, {
|
||
action: 'pin',
|
||
label: pinnedLabel
|
||
}, {
|
||
action: 'quote',
|
||
label: '引用'
|
||
}, {
|
||
action: 'select',
|
||
label: '多选'
|
||
}, {
|
||
action: 'detail',
|
||
label: '详情'
|
||
}];
|
||
if (isOwnMessage) {
|
||
items.unshift({
|
||
action: 'edit',
|
||
label: '编辑'
|
||
});
|
||
items.push({
|
||
action: 'recall',
|
||
label: '撤回'
|
||
});
|
||
} else if (props.canRecallOthers) {
|
||
items.push({
|
||
action: 'recall',
|
||
label: '撤回'
|
||
});
|
||
}
|
||
return items;
|
||
});
|
||
function scrollToBottom() {
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .nextTick */ .dY)(() => {
|
||
if (listEl.value) {
|
||
listEl.value.scrollTop = listEl.value.scrollHeight;
|
||
}
|
||
});
|
||
}
|
||
function scrollToMessage(messageId) {
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .nextTick */ .dY)(() => {
|
||
if (!listEl.value || !messageId) {
|
||
return;
|
||
}
|
||
const row = Array.from(listEl.value.querySelectorAll('.message-row')).find(element => element.dataset.messageKey === messageId);
|
||
if (row) {
|
||
row.scrollIntoView({
|
||
block: 'center',
|
||
behavior: 'smooth'
|
||
});
|
||
}
|
||
});
|
||
}
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .watch */ .wB)(() => props.messages.map(message => `${message.id}:${message.status}:${message.deliveryStatus || ''}:${message.messageUid || ''}:${message.recalled ? '1' : ''}`).join('|'), scrollToBottom, {
|
||
immediate: true
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .watch */ .wB)(() => props.attentionMessageId, scrollToMessage);
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .onMounted */ .sV)(() => {
|
||
document.addEventListener('click', closeMenu);
|
||
document.addEventListener('keydown', closeMenuOnEscape);
|
||
document.addEventListener('pointermove', moveImageDrag);
|
||
document.addEventListener('pointerup', stopImageDrag);
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .onBeforeUnmount */ .xo)(() => {
|
||
document.removeEventListener('click', closeMenu);
|
||
document.removeEventListener('keydown', closeMenuOnEscape);
|
||
document.removeEventListener('pointermove', moveImageDrag);
|
||
document.removeEventListener('pointerup', stopImageDrag);
|
||
});
|
||
function messageIdentity(message) {
|
||
return String(message.messageUid || message.id || '');
|
||
}
|
||
function canOpenMessageMenu(message) {
|
||
return message && message.status !== 'failed' && message.status !== 'sending';
|
||
}
|
||
function isSelected(message) {
|
||
return props.selectedMessageIds.includes(messageIdentity(message));
|
||
}
|
||
function isFavorite(message) {
|
||
return props.favoriteMessageIds.includes(messageIdentity(message));
|
||
}
|
||
function isAttention(message) {
|
||
return props.attentionMessageId === messageIdentity(message);
|
||
}
|
||
function isRecallNotice(message) {
|
||
return message.direction === 'out' && (message.recalled || message.status === 'recalled');
|
||
}
|
||
function isRecalledMessage(message) {
|
||
return message.recalled || message.status === 'recalled';
|
||
}
|
||
function isImageMessage(message) {
|
||
return message?.type === 'image' && message?.attachment?.url;
|
||
}
|
||
function isFileMessage(message) {
|
||
return message?.type === 'file' && message?.attachment?.url;
|
||
}
|
||
function isVideoMessage(message) {
|
||
return (message?.type === 'video' || Number(message?.contentType || 0) === 6) && message?.attachment?.url;
|
||
}
|
||
function isRedPacketMessage(message) {
|
||
return Number(message?.contentType || 0) === 90 || Boolean(redPacketPayload(message));
|
||
}
|
||
function isRedPacketReceipt(message) {
|
||
return Number(message?.contentType || 0) === 105;
|
||
}
|
||
function isSystemMessage(message) {
|
||
return [92, 93].includes(Number(message?.contentType || 0));
|
||
}
|
||
function systemMessageText(message) {
|
||
const contentType = Number(message?.contentType || 0);
|
||
if (contentType === 92) {
|
||
return '以上是打招呼的内容';
|
||
}
|
||
if (contentType === 93) {
|
||
return '你们已经是好友了,可以开始聊天了。';
|
||
}
|
||
return String(message?.text || '');
|
||
}
|
||
function redPacketReceiptText(message) {
|
||
const text = String(message?.text || '').trim();
|
||
if (text && text !== '[领取了红包]') {
|
||
return text;
|
||
}
|
||
const receiverName = message?.direction === 'out' ? '你' : message?.senderName || '对方';
|
||
const packetSenderName = message?.redPacketSenderName || nearestRedPacketSenderName(message);
|
||
return packetSenderName ? `${receiverName}领取了${packetSenderName}的红包` : `${receiverName}领取了红包`;
|
||
}
|
||
function nearestRedPacketSenderName(receiptMessage) {
|
||
const receiptIndex = props.messages.findIndex(item => messageIdentity(item) === messageIdentity(receiptMessage));
|
||
for (let index = receiptIndex - 1; index >= 0; index -= 1) {
|
||
const candidate = props.messages[index];
|
||
if (isRedPacketMessage(candidate)) {
|
||
return candidate?.direction === 'out' ? '你' : candidate?.senderName || '对方';
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
function redPacketPayload(message) {
|
||
if (message?.redPacket && typeof message.redPacket === 'object') {
|
||
return message.redPacket;
|
||
}
|
||
const text = String(message?.text || '').trim();
|
||
if (!text.startsWith('{')) {
|
||
return null;
|
||
}
|
||
try {
|
||
const payload = JSON.parse(text);
|
||
return payload?.redPackets || payload?.redPacket || null;
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
}
|
||
function redPacketBlessing(message) {
|
||
return String(redPacketPayload(message)?.blessing || '恭喜发财,大吉大利');
|
||
}
|
||
function isGroupMessage(message) {
|
||
return ['group', 'channel'].includes(message?.conversationType || '');
|
||
}
|
||
function showGroupSender(message) {
|
||
return isGroupMessage(message) && message?.direction === 'in';
|
||
}
|
||
function senderRoleLabel(message) {
|
||
const role = message?.senderProfile?.role || message?.senderRole || '';
|
||
if (role === 'owner') {
|
||
return '群主';
|
||
}
|
||
if (role === 'admin') {
|
||
return '管理员';
|
||
}
|
||
return '';
|
||
}
|
||
function groupSenderName(message) {
|
||
return message?.senderName || message?.senderProfile?.displayName || message?.from || '未知用户';
|
||
}
|
||
function groupSenderAvatarText(message) {
|
||
return String(groupSenderName(message) || '?').slice(0, 1).toUpperCase();
|
||
}
|
||
function openSenderProfile(message) {
|
||
const profile = message?.senderProfile || {};
|
||
const uid = profile.uid || message?.from || '';
|
||
const cachedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === uid) || null;
|
||
const cachedAlias = String(cachedContact?.alias || '').trim();
|
||
const contactAlias = String(profile.contactAlias || cachedAlias || profile.remarkAlias || '').trim();
|
||
const groupAlias = String(profile.groupAlias || '').trim();
|
||
const rawName = profile.rawName || cachedContact?.rawUser?.displayName || cachedContact?.rawUser?.name || cachedContact?.title || groupSenderName(message);
|
||
const displayName = contactAlias || groupAlias || rawName || uid;
|
||
senderProfile.visible = true;
|
||
senderProfile.uid = uid;
|
||
senderProfile.userId = profile.userId || profile.name || cachedContact?.rawUser?.name || uid;
|
||
senderProfile.displayName = displayName;
|
||
senderProfile.rawName = rawName || '';
|
||
senderProfile.mobile = profile.mobile || cachedContact?.rawUser?.mobile || '';
|
||
senderProfile.address = profile.address || cachedContact?.address || cachedContact?.rawUser?.address || '';
|
||
senderProfile.portrait = profile.portrait || cachedContact?.portrait || message?.senderPortrait || '';
|
||
senderProfile.avatarText = String(displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();
|
||
senderProfile.role = profile.role || message?.senderRole || '';
|
||
senderProfile.roleLabel = senderRoleLabel(message);
|
||
senderProfile.contactAlias = contactAlias;
|
||
senderProfile.groupAlias = groupAlias;
|
||
senderProfile.isContact = Boolean(profile.isContact || cachedContact);
|
||
senderProfile.aliasDraft = contactAlias;
|
||
senderProfile.saving = false;
|
||
senderProfile.adding = false;
|
||
senderProfile.notice = '';
|
||
senderProfile.error = '';
|
||
closeMenu();
|
||
}
|
||
function closeSenderProfile() {
|
||
if (senderProfile.saving || senderProfile.adding) {
|
||
return;
|
||
}
|
||
senderProfile.visible = false;
|
||
}
|
||
async function addSenderAsContact() {
|
||
if (!senderProfile.uid || senderProfile.adding || senderProfile.saving) {
|
||
return;
|
||
}
|
||
senderProfile.adding = true;
|
||
senderProfile.notice = '';
|
||
senderProfile.error = '';
|
||
const ok = await contacts.addContact(senderProfile.uid);
|
||
if (ok || String(contacts.actionError || '').includes('已经是联系人')) {
|
||
senderProfile.isContact = true;
|
||
const alias = senderProfile.aliasDraft.trim();
|
||
let aliasSaved = false;
|
||
if (alias) {
|
||
aliasSaved = await contacts.updateContactAlias(senderProfile.uid, alias);
|
||
if (aliasSaved) {
|
||
senderProfile.contactAlias = alias;
|
||
senderProfile.displayName = alias;
|
||
senderProfile.avatarText = String(alias || senderProfile.uid || '?').slice(0, 1).toUpperCase();
|
||
}
|
||
}
|
||
await contacts.refreshContacts({
|
||
force: true
|
||
}).catch(() => {});
|
||
if (alias && !aliasSaved) {
|
||
senderProfile.notice = '';
|
||
senderProfile.error = contacts.actionError ? `已添加为好友,但${contacts.actionError}` : '已添加为好友,但备注名同步失败';
|
||
} else {
|
||
senderProfile.notice = alias ? '已添加为好友,备注名已保存' : ok ? '已添加为好友' : '已是好友';
|
||
}
|
||
emit('sender-profile-updated', {
|
||
userId: senderProfile.uid
|
||
});
|
||
} else {
|
||
senderProfile.error = contacts.actionError || '添加好友失败';
|
||
}
|
||
senderProfile.adding = false;
|
||
}
|
||
async function saveSenderAlias() {
|
||
if (!senderProfile.uid || senderProfile.saving || senderProfile.adding) {
|
||
return;
|
||
}
|
||
senderProfile.saving = true;
|
||
senderProfile.notice = '';
|
||
senderProfile.error = '';
|
||
const ok = await contacts.updateContactAlias(senderProfile.uid, senderProfile.aliasDraft);
|
||
if (ok) {
|
||
await contacts.refreshContacts({
|
||
force: true
|
||
}).catch(() => {});
|
||
const alias = senderProfile.aliasDraft.trim();
|
||
senderProfile.contactAlias = alias;
|
||
senderProfile.displayName = alias || senderProfile.groupAlias || senderProfile.rawName || senderProfile.uid;
|
||
senderProfile.avatarText = String(senderProfile.displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();
|
||
senderProfile.notice = '备注名已保存';
|
||
emit('sender-profile-updated', {
|
||
userId: senderProfile.uid
|
||
});
|
||
} else {
|
||
senderProfile.error = contacts.actionError || '备注名修改失败';
|
||
}
|
||
senderProfile.saving = false;
|
||
}
|
||
function roleBubbleClass(message) {
|
||
const role = message?.senderRole || '';
|
||
if (role === 'owner') {
|
||
return 'role-bubble-owner';
|
||
}
|
||
if (role === 'admin') {
|
||
return 'role-bubble-admin';
|
||
}
|
||
return '';
|
||
}
|
||
function formatFileSize(size) {
|
||
const bytes = Number(size || 0);
|
||
if (bytes >= 1024 * 1024) {
|
||
return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;
|
||
}
|
||
if (bytes >= 1024) {
|
||
return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;
|
||
}
|
||
return bytes > 0 ? `${bytes} B` : '';
|
||
}
|
||
function handleMessageClick(message) {
|
||
if (props.selectionMode) {
|
||
emit('toggle-select', message);
|
||
}
|
||
}
|
||
function handleImageClick(message) {
|
||
if (props.selectionMode) {
|
||
emit('toggle-select', message);
|
||
return;
|
||
}
|
||
openImageViewer(message);
|
||
}
|
||
function openImageViewer(message) {
|
||
const attachment = message?.attachment || {};
|
||
if (!attachment.url) {
|
||
return;
|
||
}
|
||
closeMenu();
|
||
imageViewer.visible = true;
|
||
const index = viewerImages.value.findIndex(item => messageIdentity(item) === messageIdentity(message));
|
||
showViewerImage(index >= 0 ? index : 0);
|
||
}
|
||
function showViewerImage(index) {
|
||
const images = viewerImages.value;
|
||
if (!images.length) {
|
||
closeImageViewer();
|
||
return;
|
||
}
|
||
const normalizedIndex = (index + images.length) % images.length;
|
||
const attachment = images[normalizedIndex]?.attachment || {};
|
||
imageViewer.index = normalizedIndex;
|
||
imageViewer.sourceUrl = attachment.url || '';
|
||
imageViewer.url = (0,_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(attachment.url || '');
|
||
imageViewer.name = attachment.name || `图片 ${normalizedIndex + 1}`;
|
||
resetImageViewer();
|
||
}
|
||
function showPreviousImage() {
|
||
showViewerImage(imageViewer.index - 1);
|
||
}
|
||
function showNextImage() {
|
||
showViewerImage(imageViewer.index + 1);
|
||
}
|
||
function closeImageViewer() {
|
||
imageViewer.visible = false;
|
||
imageViewer.dragging = false;
|
||
imageViewer.sourceUrl = '';
|
||
}
|
||
function resetImageViewer() {
|
||
imageViewer.scale = 1;
|
||
imageViewer.rotation = 0;
|
||
imageViewer.offsetX = 0;
|
||
imageViewer.offsetY = 0;
|
||
}
|
||
function clampImageScale(value) {
|
||
return Math.min(IMAGE_MAX_SCALE, Math.max(IMAGE_MIN_SCALE, Number(value.toFixed(2))));
|
||
}
|
||
function setImageScale(value, originX = null, originY = null) {
|
||
const previousScale = imageViewer.scale;
|
||
const nextScale = clampImageScale(value);
|
||
if (nextScale === previousScale) {
|
||
return;
|
||
}
|
||
if (originX !== null && originY !== null && viewerStage.value) {
|
||
const rect = viewerStage.value.getBoundingClientRect();
|
||
const centerX = rect.left + rect.width / 2;
|
||
const centerY = rect.top + rect.height / 2;
|
||
const ratio = nextScale / previousScale - 1;
|
||
imageViewer.offsetX -= (originX - centerX - imageViewer.offsetX) * ratio;
|
||
imageViewer.offsetY -= (originY - centerY - imageViewer.offsetY) * ratio;
|
||
}
|
||
imageViewer.scale = nextScale;
|
||
if (nextScale <= 1) {
|
||
imageViewer.offsetX = 0;
|
||
imageViewer.offsetY = 0;
|
||
}
|
||
}
|
||
function zoomImage(delta) {
|
||
setImageScale(imageViewer.scale + delta);
|
||
}
|
||
function rotateImage() {
|
||
imageViewer.rotation = (imageViewer.rotation + 90) % 360;
|
||
}
|
||
function handleImageWheel(event) {
|
||
const factor = event.deltaY < 0 ? 1.12 : 1 / 1.12;
|
||
setImageScale(imageViewer.scale * factor, event.clientX, event.clientY);
|
||
}
|
||
function startImageDrag(event) {
|
||
if (!imageViewer.visible || imageViewer.scale <= 1) {
|
||
return;
|
||
}
|
||
imageViewer.dragging = true;
|
||
imageViewer.dragStartX = event.clientX;
|
||
imageViewer.dragStartY = event.clientY;
|
||
imageViewer.dragOffsetX = imageViewer.offsetX;
|
||
imageViewer.dragOffsetY = imageViewer.offsetY;
|
||
}
|
||
function moveImageDrag(event) {
|
||
if (!imageViewer.dragging) {
|
||
return;
|
||
}
|
||
imageViewer.offsetX = imageViewer.dragOffsetX + event.clientX - imageViewer.dragStartX;
|
||
imageViewer.offsetY = imageViewer.dragOffsetY + event.clientY - imageViewer.dragStartY;
|
||
}
|
||
function stopImageDrag() {
|
||
imageViewer.dragging = false;
|
||
}
|
||
function saveViewerImage() {
|
||
if (!imageViewer.sourceUrl) {
|
||
return;
|
||
}
|
||
const downloadUrl = new URL('/api/media_download.php', window.location.origin);
|
||
downloadUrl.searchParams.set('url', imageViewer.sourceUrl);
|
||
downloadUrl.searchParams.set('name', imageViewer.name || 'image');
|
||
const link = document.createElement('a');
|
||
link.href = downloadUrl.toString();
|
||
link.download = imageViewer.name || 'image';
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
link.remove();
|
||
}
|
||
function openMenu(event, message) {
|
||
if (!canOpenMessageMenu(message)) {
|
||
closeMenu();
|
||
return;
|
||
}
|
||
contextMenu.visible = true;
|
||
contextMenu.message = message;
|
||
contextMenu.x = Math.min(event.clientX, window.innerWidth - 148);
|
||
contextMenu.y = Math.min(event.clientY, window.innerHeight - 352);
|
||
}
|
||
function closeMenu() {
|
||
contextMenu.visible = false;
|
||
contextMenu.message = null;
|
||
}
|
||
function closeMenuOnEscape(event) {
|
||
if (imageViewer.visible && event.key === 'ArrowLeft') {
|
||
event.preventDefault();
|
||
showPreviousImage();
|
||
return;
|
||
}
|
||
if (imageViewer.visible && event.key === 'ArrowRight') {
|
||
event.preventDefault();
|
||
showNextImage();
|
||
return;
|
||
}
|
||
if (event.key === 'Escape') {
|
||
if (senderProfile.visible) {
|
||
closeSenderProfile();
|
||
}
|
||
if (imageViewer.visible) {
|
||
closeImageViewer();
|
||
}
|
||
closeMenu();
|
||
}
|
||
}
|
||
function chooseMenuAction(action) {
|
||
if (contextMenu.message) {
|
||
emit('message-action', {
|
||
action,
|
||
message: contextMenu.message
|
||
});
|
||
}
|
||
closeMenu();
|
||
}
|
||
function formatTime(timestamp) {
|
||
return new Intl.DateTimeFormat('zh-CN', {
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
hour12: false,
|
||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
||
}).format(timestamp);
|
||
}
|
||
function deliveryState(message) {
|
||
if (message.direction !== 'out' || message.status === 'failed' || message.status === 'recalled' || message.recalled) {
|
||
return '';
|
||
}
|
||
const state = message.deliveryStatus || message.status;
|
||
if (state === 'read') {
|
||
return 'read';
|
||
}
|
||
if (state === 'delivered') {
|
||
return 'delivered';
|
||
}
|
||
if (state === 'sent') {
|
||
return 'sent';
|
||
}
|
||
return '';
|
||
}
|
||
function deliveryTitle(message) {
|
||
const state = deliveryState(message);
|
||
if (state === 'read') {
|
||
return '对方已读';
|
||
}
|
||
if (state === 'delivered') {
|
||
return '已送达对方';
|
||
}
|
||
if (state === 'sent') {
|
||
return '已送出';
|
||
}
|
||
return '';
|
||
}
|
||
function failureText(message) {
|
||
if (message.status === 'failed') {
|
||
if (message.errorCode) {
|
||
return message.error ? `失败:${message.error}(${message.errorCode})` : `失败:${message.errorCode}`;
|
||
}
|
||
return message.error ? `失败:${message.error}` : '失败';
|
||
}
|
||
return '';
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
|
||
ref_key: "listEl",
|
||
ref: listEl,
|
||
class: "message-list"
|
||
}, [((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .renderList */ .pI)(__props.messages, message => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("article", {
|
||
key: message.id,
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["message-row", [message.direction, {
|
||
system: isSystemMessage(message),
|
||
selected: isSelected(message),
|
||
attention: isAttention(message),
|
||
recalled: message.recalled || message.status === 'recalled'
|
||
}]]),
|
||
"data-message-key": messageIdentity(message),
|
||
onClick: $event => handleMessageClick(message)
|
||
}, [isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_2, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(systemMessageText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), __props.selectionMode && !isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("label", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("input", {
|
||
type: "checkbox",
|
||
checked: isSelected(message),
|
||
onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
|
||
onChange: $event => emit('toggle-select', message)
|
||
}, null, 40, _hoisted_4)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !isSystemMessage(message) && showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 2,
|
||
type: "button",
|
||
class: "message-sender-avatar",
|
||
title: groupSenderName(message),
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
|
||
}, [message.senderPortrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(message.senderPortrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(groupSenderAvatarText(message)), 1))], 8, _hoisted_5)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !isSystemMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_8, [showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 0,
|
||
type: "button",
|
||
class: "message-sender-name",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openSenderProfile(message), ["stop"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createTextVNode */ .eW)((0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(groupSenderName(message)) + " ", 1), senderRoleLabel(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderRoleLabel(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 8, _hoisted_9)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["message-bubble", roleBubbleClass(message)]),
|
||
onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => openMenu($event, message), ["prevent"])
|
||
}, [isRedPacketMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_13, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
|
||
class: "red-packet-icon"
|
||
}, "福", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(redPacketBlessing(message)), 1), _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("small", null, "请在 App 上领取", -1))])]), _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
|
||
class: "red-packet-card-footer"
|
||
}, "中聊红包", -1))])) : isRedPacketReceipt(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_14, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
|
||
class: "red-packet-mini-icon"
|
||
}, "福", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(redPacketReceiptText(message)), 1)])) : isImageMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 2,
|
||
type: "button",
|
||
class: "message-image",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)($event => handleImageClick(message), ["stop"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("img", {
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(message.attachment.url),
|
||
alt: message.attachment.name || '图片'
|
||
}, null, 8, _hoisted_16)], 8, _hoisted_15)) : isVideoMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("video", {
|
||
key: 3,
|
||
class: "message-video",
|
||
src: message.attachment.url,
|
||
controls: "",
|
||
playsinline: "",
|
||
preload: "metadata"
|
||
}, " 当前浏览器无法播放该视频 ", 8, _hoisted_17)) : isFileMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("a", {
|
||
key: 4,
|
||
class: "message-file",
|
||
href: message.attachment.url,
|
||
target: "_blank",
|
||
rel: "noreferrer",
|
||
download: ""
|
||
}, [_cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
|
||
class: "message-file-icon"
|
||
}, "▤", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", _hoisted_19, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.attachment.name || '文件'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatFileSize(message.attachment.size)), 1)])], 8, _hoisted_18)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), message.text && !isRedPacketMessage(message) && !isRedPacketReceipt(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("p", _hoisted_20, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.text), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("time", null, [isRecallNotice(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(message.recallStatus || '已撤回'), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatTime(message.displayTimestamp || message.timestamp)), 1), message.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_22, "【edit " + (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(formatTime(message.editedAt)) + "】", 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), isFavorite(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_23, "★")) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), deliveryState(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", {
|
||
key: 3,
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeClass */ .C4)(["delivery-mark", `delivery-mark-${deliveryState(message)}`]),
|
||
title: deliveryTitle(message),
|
||
"aria-label": deliveryTitle(message)
|
||
}, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", {
|
||
class: "delivery-check"
|
||
}, "✓", -1)), deliveryState(message) !== 'sent' ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_25, "✓")) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_24)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), message.status === 'failed' ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(failureText(message)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)])], 42, _hoisted_11)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_1);
|
||
}), 128)), contextMenu.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "message-context-menu",
|
||
style: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeStyle */ .Tr)({
|
||
left: `${contextMenu.x}px`,
|
||
top: `${contextMenu.y}px`
|
||
}),
|
||
onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .renderList */ .pI)(menuItems.value, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: item.action,
|
||
type: "button",
|
||
onClick: $event => chooseMenuAction(item.action)
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(item.label), 9, _hoisted_27);
|
||
}), 128))], 4)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Teleport */ .Im, {
|
||
to: "body"
|
||
}, [imageViewer.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "image-viewer-backdrop",
|
||
onClick: closeImageViewer
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
|
||
class: "image-viewer-dialog",
|
||
onClick: _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
|
||
class: "image-viewer-toolbar"
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "旋转",
|
||
"aria-label": "旋转",
|
||
onClick: rotateImage
|
||
}, "⟳"), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "保存",
|
||
"aria-label": "保存",
|
||
onClick: saveViewerImage
|
||
}, "⇩"), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "关闭",
|
||
"aria-label": "关闭",
|
||
onClick: closeImageViewer
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", {
|
||
ref_key: "viewerStage",
|
||
ref: viewerStage,
|
||
class: "image-viewer-stage"
|
||
}, [viewerImages.value.length > 1 ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 0,
|
||
type: "button",
|
||
class: "image-viewer-nav image-viewer-prev",
|
||
title: "上一张",
|
||
"aria-label": "上一张",
|
||
onPointerdown: _cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(showPreviousImage, ["stop"])
|
||
}, "‹", 32)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("img", {
|
||
class: "image-viewer-img",
|
||
src: imageViewer.url,
|
||
alt: imageViewer.name || '图片',
|
||
style: (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .normalizeStyle */ .Tr)(imageViewerStyle.value),
|
||
draggable: "false"
|
||
}, null, 12, _hoisted_28), viewerImages.value.length > 1 ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 1,
|
||
type: "button",
|
||
class: "image-viewer-nav image-viewer-next",
|
||
title: "下一张",
|
||
"aria-label": "下一张",
|
||
onPointerdown: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"])),
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(showNextImage, ["stop"])
|
||
}, "›", 32)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)], 512)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)])), ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createBlock */ .Wv)(vue__WEBPACK_IMPORTED_MODULE_7__/* .Teleport */ .Im, {
|
||
to: "body"
|
||
}, [senderProfile.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "sender-profile-backdrop",
|
||
onClick: closeSenderProfile
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("section", {
|
||
class: "sender-profile-dialog",
|
||
onClick: _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("header", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, "用户资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeSenderProfile
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", _hoisted_29, [senderProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "profile-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_8__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_11__/* .imageDisplayUrl */ .B)(senderProfile.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_30)) : ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_31, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.displayName || senderProfile.uid), 1), senderProfile.roleLabel ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_32, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.roleLabel), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dl", _hoisted_33, [(0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.userId || senderProfile.uid || '-'), 1)]), senderProfile.uid && senderProfile.userId && senderProfile.uid !== senderProfile.userId ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("div", _hoisted_34, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "用户UID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.uid), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.rawName || senderProfile.displayName || '-'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.mobile || '未知'), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("div", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.address || '未知'), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("label", _hoisted_35, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("span", null, "备注名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => senderProfile.aliasDraft = $event),
|
||
maxlength: "32",
|
||
autocomplete: "off",
|
||
placeholder: "可给群员设置备注",
|
||
disabled: senderProfile.saving || senderProfile.adding
|
||
}, null, 8, _hoisted_36), [[vue__WEBPACK_IMPORTED_MODULE_6__/* .vModelText */ .Jo, senderProfile.aliasDraft, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("footer", _hoisted_37, [senderProfile.notice ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_38, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.notice), 1)) : senderProfile.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("span", _hoisted_39, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), !senderProfile.isContact ? ((0,vue__WEBPACK_IMPORTED_MODULE_7__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementBlock */ .CE)("button", {
|
||
key: 2,
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
disabled: senderProfile.adding || senderProfile.saving || !senderProfile.uid,
|
||
onClick: addSenderAsContact
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.adding ? '添加中...' : '添加为好友'), 9, _hoisted_40)) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: senderProfile.saving || senderProfile.adding || !senderProfile.uid,
|
||
onClick: saveSenderAlias
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_9__/* .toDisplayString */ .v_)(senderProfile.saving ? '保存中...' : '保存备注'), 9, _hoisted_41)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_7__/* .createCommentVNode */ .Q3)("", true)]))], 512);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3915:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9045);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(446);
|
||
|
||
const _hoisted_1 = {
|
||
class: "contact-panel"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "chat-header"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "contact-profile"
|
||
};
|
||
const _hoisted_4 = ["src"];
|
||
const _hoisted_5 = {
|
||
key: 1,
|
||
class: "profile-avatar"
|
||
};
|
||
const _hoisted_6 = {
|
||
class: "profile-main"
|
||
};
|
||
const _hoisted_7 = {
|
||
class: "remark-row"
|
||
};
|
||
const _hoisted_8 = {
|
||
class: "profile-fields"
|
||
};
|
||
const _hoisted_9 = {
|
||
key: 0,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_10 = {
|
||
class: "modal-actions"
|
||
};
|
||
const _hoisted_11 = ["disabled"];
|
||
const _hoisted_12 = ["disabled"];
|
||
const _hoisted_13 = {
|
||
key: 1,
|
||
class: "empty-chat"
|
||
};
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'ContactPanel',
|
||
setup(__props) {
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_4__/* .useContactStore */ .p)();
|
||
const contact = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contacts.activeContact);
|
||
const remarkName = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.alias || '未设置');
|
||
const username = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.displayName || contact.value?.rawUser?.name || contact.value?.uid || '');
|
||
const mobile = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.mobile || '未知');
|
||
const address = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .computed */ .EW)(() => contact.value?.rawUser?.address || '未知');
|
||
const editingAlias = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
|
||
const aliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
|
||
const aliasSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)(false);
|
||
const aliasError = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .ref */ .KR)('');
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .watch */ .wB)(contact, () => {
|
||
editingAlias.value = false;
|
||
aliasError.value = '';
|
||
});
|
||
function openAliasEditor() {
|
||
aliasDraft.value = contact.value?.alias || '';
|
||
aliasError.value = '';
|
||
editingAlias.value = true;
|
||
}
|
||
function closeAliasEditor() {
|
||
if (aliasSaving.value) {
|
||
return;
|
||
}
|
||
editingAlias.value = false;
|
||
aliasError.value = '';
|
||
}
|
||
async function submitAlias() {
|
||
if (!contact.value) {
|
||
return;
|
||
}
|
||
aliasSaving.value = true;
|
||
aliasError.value = '';
|
||
const ok = await contacts.updateContactAlias(contact.value.uid, aliasDraft.value);
|
||
aliasSaving.value = false;
|
||
if (ok) {
|
||
editingAlias.value = false;
|
||
return;
|
||
}
|
||
aliasError.value = contacts.actionError || '备注名修改失败';
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("section", _hoisted_1, [contact.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_1__/* .Fragment */ .FK, {
|
||
key: 0
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h2", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(remarkName.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(username.value), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_3, [contact.value.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "profile-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__/* .imageDisplayUrl */ .B)(contact.value.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_4)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(contact.value.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(remarkName.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button remark-edit-button",
|
||
title: "编辑备注名",
|
||
onClick: openAliasEditor
|
||
}, "✏️")])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dl", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(username.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "手机号", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(mobile.value), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dt", null, "地区", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("dd", null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(address.value), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-action profile-action",
|
||
onClick: _cache[0] || (_cache[0] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .unref */ .R1)(contacts).openChat(contact.value))
|
||
}, "发消息")]), editingAlias.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "modal-backdrop contact-modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(closeAliasEditor, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("form", {
|
||
class: "modal-panel",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__/* .withModifiers */ .D$)(submitAlias, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("header", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "编辑备注名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeAliasEditor
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("label", null, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "备注名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => aliasDraft.value = $event),
|
||
maxlength: "32",
|
||
autocomplete: "off",
|
||
autofocus: ""
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_0__/* .vModelText */ .Jo, aliasDraft.value, void 0, {
|
||
trim: true
|
||
}]])]), aliasError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("p", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(aliasError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("div", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
disabled: aliasSaving.value,
|
||
onClick: closeAliasEditor
|
||
}, "取消", 8, _hoisted_11), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("button", {
|
||
type: "submit",
|
||
class: "primary-inline-action",
|
||
disabled: aliasSaving.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .toDisplayString */ .v_)(aliasSaving.value ? '保存中' : '保存'), 9, _hoisted_12)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createCommentVNode */ .Q3)("", true)], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementBlock */ .CE)("div", _hoisted_13, _cache[7] || (_cache[7] = [(0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("strong", null, "选择一个联系人", -1), (0,vue__WEBPACK_IMPORTED_MODULE_1__/* .createElementVNode */ .Lk)("span", null, "好友列表同步完成后,可以在左侧查看资料", -1)])))]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9829:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7566);
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "conversation-list favorite-list"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "list-header"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "sidebar-scroll"
|
||
};
|
||
const _hoisted_4 = ["onClick"];
|
||
const _hoisted_5 = {
|
||
class: "favorite-item-main"
|
||
};
|
||
const _hoisted_6 = {
|
||
key: 0,
|
||
class: "empty-list"
|
||
};
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'FavoriteList',
|
||
setup(__props) {
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_5__/* .useConversationStore */ .w)();
|
||
const activeKey = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => conversations.activeFavorite?.key || '');
|
||
function favoriteTitle(item) {
|
||
if (item.conversationTitle) {
|
||
return item.conversationTitle;
|
||
}
|
||
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
|
||
return conversation?.title || item.conversationId || '未知会话';
|
||
}
|
||
function favoritePreview(item) {
|
||
if (item.recalled) {
|
||
return `[${item.recallStatus || '已撤回'}]`;
|
||
}
|
||
if (item.preview) {
|
||
return item.preview;
|
||
}
|
||
if (item.text) {
|
||
return item.text;
|
||
}
|
||
if (item.type === 'image') {
|
||
return '[图片]';
|
||
}
|
||
if (item.type === 'file') {
|
||
return `[文件] ${item.attachment?.name || '文件'}`;
|
||
}
|
||
return '(无文字内容)';
|
||
}
|
||
function formatFavoriteTime(timestamp) {
|
||
const value = Number(timestamp || 0);
|
||
if (!value) {
|
||
return '';
|
||
}
|
||
return new Intl.DateTimeFormat('zh-CN', {
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
hour12: false
|
||
}).format(value);
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h2", null, "收藏", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages.length) + " 条消息", 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .renderList */ .pI)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("button", {
|
||
key: item.key,
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["favorite-item", {
|
||
active: activeKey.value === item.key
|
||
}]),
|
||
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).setActiveFavorite(item.key)
|
||
}, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
|
||
class: "favorite-item-icon"
|
||
}, "★", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteTitle(item)), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoritePreview(item)), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("time", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFavoriteTime(item.timestamp)), 1)], 10, _hoisted_4);
|
||
}), 128)), !(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(conversations).favoriteMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_6, " 暂无收藏消息 ")) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)])]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 6415:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7566);
|
||
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1414);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "favorite-panel"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "chat-header"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "favorite-detail"
|
||
};
|
||
const _hoisted_4 = {
|
||
class: "favorite-detail-body"
|
||
};
|
||
const _hoisted_5 = {
|
||
key: 0,
|
||
class: "recall-mark"
|
||
};
|
||
const _hoisted_6 = ["href"];
|
||
const _hoisted_7 = ["src", "alt"];
|
||
const _hoisted_8 = ["href"];
|
||
const _hoisted_9 = {
|
||
class: "message-file-main"
|
||
};
|
||
const _hoisted_10 = {
|
||
key: 3
|
||
};
|
||
const _hoisted_11 = {
|
||
class: "favorite-detail-actions"
|
||
};
|
||
const _hoisted_12 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_13 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_14 = {
|
||
key: 1,
|
||
class: "empty-chat"
|
||
};
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'FavoritePanel',
|
||
setup(__props) {
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_5__/* .useConversationStore */ .w)();
|
||
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_6__/* .useNavigationStore */ .l)();
|
||
const favorite = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .computed */ .EW)(() => conversations.activeFavorite);
|
||
const notice = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
const error = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .ref */ .KR)('');
|
||
function clearFeedback() {
|
||
notice.value = '';
|
||
error.value = '';
|
||
}
|
||
function favoriteTitle(item) {
|
||
if (item.conversationTitle) {
|
||
return item.conversationTitle;
|
||
}
|
||
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
|
||
return conversation?.title || item.conversationId || '未知会话';
|
||
}
|
||
function favoriteText(item) {
|
||
return item.text || '';
|
||
}
|
||
function isImageFavorite(item) {
|
||
return item?.type === 'image' && item?.attachment?.url;
|
||
}
|
||
function isFileFavorite(item) {
|
||
return item?.type === 'file' && item?.attachment?.url;
|
||
}
|
||
function favoriteCopyText(item) {
|
||
if (!item) {
|
||
return '';
|
||
}
|
||
if (item.text) {
|
||
return item.text;
|
||
}
|
||
if (item.recalled) {
|
||
return item.recallStatus || '已撤回';
|
||
}
|
||
if (isImageFavorite(item)) {
|
||
return item.attachment.url;
|
||
}
|
||
if (isFileFavorite(item)) {
|
||
return `${item.attachment.name || '文件'} ${item.attachment.url}`.trim();
|
||
}
|
||
return item.preview || '';
|
||
}
|
||
function formatFileSize(size) {
|
||
const bytes = Number(size || 0);
|
||
if (bytes >= 1024 * 1024) {
|
||
return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;
|
||
}
|
||
if (bytes >= 1024) {
|
||
return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;
|
||
}
|
||
return bytes > 0 ? `${bytes} B` : '';
|
||
}
|
||
function formatFavoriteTime(timestamp) {
|
||
const value = Number(timestamp || 0);
|
||
if (!value) {
|
||
return '';
|
||
}
|
||
return new Intl.DateTimeFormat('zh-CN', {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
hour12: false
|
||
}).format(value);
|
||
}
|
||
async function copyFavorite() {
|
||
clearFeedback();
|
||
const text = favoriteCopyText(favorite.value || {}).trim();
|
||
if (!text) {
|
||
error.value = '没有可复制的文字内容';
|
||
return;
|
||
}
|
||
try {
|
||
await writeClipboard(text);
|
||
notice.value = '已复制';
|
||
} catch (copyError) {
|
||
error.value = '复制失败';
|
||
}
|
||
}
|
||
async function writeClipboard(text) {
|
||
if (navigator.clipboard?.writeText) {
|
||
await navigator.clipboard.writeText(text);
|
||
return;
|
||
}
|
||
const element = document.createElement('textarea');
|
||
element.value = text;
|
||
element.setAttribute('readonly', 'readonly');
|
||
element.style.position = 'fixed';
|
||
element.style.left = '-9999px';
|
||
document.body.appendChild(element);
|
||
element.select();
|
||
document.execCommand('copy');
|
||
document.body.removeChild(element);
|
||
}
|
||
function openConversation() {
|
||
clearFeedback();
|
||
const item = favorite.value;
|
||
if (!item?.conversationId) {
|
||
error.value = '缺少原会话信息';
|
||
return;
|
||
}
|
||
const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);
|
||
if (!conversation) {
|
||
error.value = '原会话暂未加载,请刷新会话后再试';
|
||
conversations.refreshRemoteConversations();
|
||
return;
|
||
}
|
||
navigation.showMessages();
|
||
conversations.setActiveConversation(item.conversationId);
|
||
window.setTimeout(() => {
|
||
conversations.focusMessage({
|
||
id: item.id || item.key,
|
||
messageUid: item.messageUid || item.key
|
||
});
|
||
}, 450);
|
||
}
|
||
function removeFavorite() {
|
||
clearFeedback();
|
||
const key = favorite.value?.key || '';
|
||
if (!key) {
|
||
return;
|
||
}
|
||
conversations.removeFavorite(key);
|
||
notice.value = '已取消收藏';
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("section", _hoisted_1, [favorite.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_2__/* .Fragment */ .FK, {
|
||
key: 0
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("h2", null, "收藏详情", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteTitle(favorite.value)), 1)])]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .normalizeClass */ .C4)(["favorite-detail-message", {
|
||
recalled: favorite.value.recalled
|
||
}])
|
||
}, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
|
||
class: "favorite-detail-star"
|
||
}, "★", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_4, [favorite.value.recalled ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favorite.value.recallStatus || '已撤回'), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), isImageFavorite(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("a", {
|
||
key: 1,
|
||
class: "favorite-detail-image",
|
||
href: favorite.value.attachment.url,
|
||
target: "_blank",
|
||
rel: "noreferrer"
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("img", {
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__/* .imageDisplayUrl */ .B)(favorite.value.attachment.url),
|
||
alt: favorite.value.attachment.name || '图片'
|
||
}, null, 8, _hoisted_7)], 8, _hoisted_6)) : isFileFavorite(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("a", {
|
||
key: 2,
|
||
class: "message-file favorite-detail-file",
|
||
href: favorite.value.attachment.url,
|
||
target: "_blank",
|
||
rel: "noreferrer",
|
||
download: ""
|
||
}, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", {
|
||
class: "message-file-icon"
|
||
}, "▤", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favorite.value.attachment.name || '文件'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFileSize(favorite.value.attachment.size)), 1)])], 8, _hoisted_8)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), favoriteText(favorite.value) ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("p", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(favoriteText(favorite.value)), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("time", null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(formatFavoriteTime(favorite.value.timestamp)), 1)], 2), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("div", _hoisted_11, [notice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(notice.value), 1)) : error.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("span", _hoisted_13, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .toDisplayString */ .v_)(error.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: copyFavorite
|
||
}, "复制"), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: openConversation
|
||
}, "打开原会话"), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "danger-inline-action",
|
||
onClick: removeFavorite
|
||
}, "取消收藏")])])], 64)) : ((0,vue__WEBPACK_IMPORTED_MODULE_2__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementBlock */ .CE)("div", _hoisted_14, _cache[3] || (_cache[3] = [(0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("strong", null, "暂无收藏消息", -1), (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .createElementVNode */ .Lk)("span", null, "右键消息气泡选择“收藏”后,会显示在这里", -1)])))]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5684:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(9045);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "conversation-list"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "list-header"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "header-actions"
|
||
};
|
||
const _hoisted_4 = {
|
||
class: "search-box"
|
||
};
|
||
const _hoisted_5 = {
|
||
class: "sidebar-scroll"
|
||
};
|
||
const _hoisted_6 = ["onClick"];
|
||
const _hoisted_7 = ["src"];
|
||
const _hoisted_8 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_9 = {
|
||
class: "conversation-copy"
|
||
};
|
||
const _hoisted_10 = {
|
||
key: 0,
|
||
class: "empty-list"
|
||
};
|
||
const _hoisted_11 = {
|
||
key: 0,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_12 = {
|
||
key: 1,
|
||
class: "form-info"
|
||
};
|
||
const _hoisted_13 = {
|
||
class: "modal-actions"
|
||
};
|
||
const _hoisted_14 = ["disabled"];
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'ContactList',
|
||
setup(__props) {
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_7__/* .useContactStore */ .p)();
|
||
const keyword = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)('');
|
||
const addingContact = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)(false);
|
||
const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .ref */ .KR)('');
|
||
const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .computed */ .EW)(() => {
|
||
const value = keyword.value.toLowerCase();
|
||
if (!value) {
|
||
return contacts.contacts;
|
||
}
|
||
return contacts.contacts.filter(item => {
|
||
return item.title.toLowerCase().includes(value) || item.subtitle.toLowerCase().includes(value) || item.uid.toLowerCase().includes(value);
|
||
});
|
||
});
|
||
function openAddContact() {
|
||
contacts.actionError = '';
|
||
contacts.actionInfo = '';
|
||
addKeyword.value = '';
|
||
addingContact.value = true;
|
||
}
|
||
function closeAddContact() {
|
||
addingContact.value = false;
|
||
}
|
||
async function submitAddContact() {
|
||
const added = await contacts.addContact(addKeyword.value);
|
||
if (added) {
|
||
window.setTimeout(() => {
|
||
addingContact.value = false;
|
||
}, 500);
|
||
}
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("h2", null, "联系人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).contacts.length) + " 位好友", 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
|
||
class: "icon-button",
|
||
title: "添加联系人",
|
||
onClick: openAddContact
|
||
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
|
||
class: "icon-button",
|
||
title: "刷新",
|
||
onClick: _cache[0] || (_cache[0] = $event => (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).refreshContacts({
|
||
force: true
|
||
}))
|
||
}, "↻")])]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => keyword.value = $event),
|
||
placeholder: "搜索联系人"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_3__/* .vModelText */ .Jo, keyword.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_4__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .renderList */ .pI)(filteredContacts.value, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("button", {
|
||
key: item.id,
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .normalizeClass */ .C4)(["conversation-item", {
|
||
active: item.id === (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).activeId
|
||
}]),
|
||
onClick: $event => (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).setActiveContact(item.id)
|
||
}, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_8__/* .imageDisplayUrl */ .B)(item.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.title), 1), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)(item.subtitle), 1)])], 10, _hoisted_6);
|
||
}), 128)), !filteredContacts.value.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("div", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '正在加载' : '暂无联系人'), 1), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '请稍候' : '好友同步完成后会显示在这里'), 1)])) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true)]), addingContact.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withModifiers */ .D$)(closeAddContact, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("form", {
|
||
class: "modal-panel",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withModifiers */ .D$)(submitAddContact, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("header", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("strong", null, "添加联系人", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeAddContact
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("label", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("span", null, "用户ID / 手机号 / 用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => addKeyword.value = $event),
|
||
autocomplete: "off",
|
||
placeholder: "请输入要添加的联系人"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_3__/* .vModelText */ .Jo, addKeyword.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("p", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionError), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionInfo ? ((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementBlock */ .CE)("p", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).actionInfo), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: closeAddContact
|
||
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-inline-action",
|
||
disabled: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading || !addKeyword.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_6__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_5__/* .unref */ .R1)(contacts).loading ? '添加中...' : '添加'), 9, _hoisted_14)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .createCommentVNode */ .Q3)("", true)]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4621:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(531);
|
||
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3579);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5367);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2731);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(7566);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(9045);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "conversation-list"
|
||
};
|
||
const _hoisted_2 = {
|
||
class: "list-header"
|
||
};
|
||
const _hoisted_3 = {
|
||
class: "header-actions action-menu-anchor"
|
||
};
|
||
const _hoisted_4 = {
|
||
class: "search-box"
|
||
};
|
||
const _hoisted_5 = {
|
||
class: "sidebar-scroll"
|
||
};
|
||
const _hoisted_6 = ["onClick", "onContextmenu"];
|
||
const _hoisted_7 = ["src"];
|
||
const _hoisted_8 = {
|
||
key: 1,
|
||
class: "conversation-avatar"
|
||
};
|
||
const _hoisted_9 = {
|
||
class: "conversation-copy"
|
||
};
|
||
const _hoisted_10 = {
|
||
key: 0,
|
||
class: "conversation-pin",
|
||
"aria-label": "已置顶"
|
||
};
|
||
const _hoisted_11 = ["aria-label"];
|
||
const _hoisted_12 = {
|
||
key: 1,
|
||
class: "empty-list"
|
||
};
|
||
const _hoisted_13 = {
|
||
key: 2,
|
||
class: "empty-list"
|
||
};
|
||
const _hoisted_14 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_15 = {
|
||
key: 2
|
||
};
|
||
const _hoisted_16 = {
|
||
key: 5,
|
||
class: "form-error"
|
||
};
|
||
const _hoisted_17 = {
|
||
key: 6,
|
||
class: "form-info"
|
||
};
|
||
const _hoisted_18 = {
|
||
class: "modal-actions"
|
||
};
|
||
const _hoisted_19 = ["disabled"];
|
||
|
||
|
||
|
||
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'ConversationList',
|
||
setup(__props) {
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_20__/* .useConversationStore */ .w)();
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_21__/* .useContactStore */ .p)();
|
||
const actionMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)(false);
|
||
const activeAction = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const actionBusy = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)(false);
|
||
const searchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const groupName = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const groupAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const groupWelcomeText = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const joinGroupKey = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const broadcastText = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const channelName = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const channelAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const contactKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)('');
|
||
const selectedContactIds = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)([]);
|
||
const conversationMenu = (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .ref */ .KR)({
|
||
item: null,
|
||
x: 0,
|
||
y: 0
|
||
});
|
||
const actionTitles = {
|
||
addContact: '添加联系人',
|
||
createGroup: '新建群组',
|
||
joinGroup: '加入群组',
|
||
broadcast: '群发助手',
|
||
createChannel: '创建频道/公告群'
|
||
};
|
||
const submitLabels = {
|
||
addContact: '添加',
|
||
createGroup: '创建',
|
||
joinGroup: '加入',
|
||
broadcast: '发送',
|
||
createChannel: '创建'
|
||
};
|
||
const actionTitle = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => actionTitles[activeAction.value] || '');
|
||
const submitLabel = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => submitLabels[activeAction.value] || '确定');
|
||
const modalError = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => contacts.actionError || conversations.actionError);
|
||
const modalInfo = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => contacts.actionInfo || conversations.actionNotice);
|
||
const normalizedSearchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => searchKeyword.value.trim().toLowerCase());
|
||
const contactsByUid = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
|
||
const map = new Map();
|
||
contacts.contacts.forEach(contact => {
|
||
const uid = String(contact.uid || contact.id || '');
|
||
if (uid) {
|
||
map.set(uid, contact);
|
||
}
|
||
});
|
||
return map;
|
||
});
|
||
const filteredConversationItems = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
|
||
const keyword = normalizedSearchKeyword.value;
|
||
if (!keyword) {
|
||
return conversations.conversations.map(item => conversationResult(item));
|
||
}
|
||
const conversationResults = conversations.conversations.filter(item => matchesConversation(item, keyword, contactForConversation(item))).map(item => conversationResult(item));
|
||
const conversationTargets = new Set(conversations.conversations.filter(item => item.type === 'single').map(item => conversationTarget(item)));
|
||
const contactResults = contacts.contacts.filter(item => !conversationTargets.has(String(item.uid || item.id || ''))).filter(item => matchesContact(item, keyword)).map(item => contactResult(item));
|
||
return [...conversationResults, ...contactResults];
|
||
});
|
||
const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
|
||
const keyword = contactKeyword.value.toLowerCase();
|
||
if (!keyword) {
|
||
return contacts.contacts;
|
||
}
|
||
return contacts.contacts.filter(item => {
|
||
return String(item.title || '').toLowerCase().includes(keyword) || String(item.subtitle || '').toLowerCase().includes(keyword) || String(item.uid || '').toLowerCase().includes(keyword);
|
||
});
|
||
});
|
||
const submitDisabled = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .computed */ .EW)(() => {
|
||
if (activeAction.value === 'addContact') {
|
||
return !addKeyword.value;
|
||
}
|
||
if (activeAction.value === 'createGroup') {
|
||
return !groupName.value || !selectedContactIds.value.length;
|
||
}
|
||
if (activeAction.value === 'joinGroup') {
|
||
return !joinGroupKey.value;
|
||
}
|
||
if (activeAction.value === 'broadcast') {
|
||
return !broadcastText.value || !selectedContactIds.value.length;
|
||
}
|
||
if (activeAction.value === 'createChannel') {
|
||
return !channelName.value;
|
||
}
|
||
return true;
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .onMounted */ .sV)(() => {
|
||
contacts.refreshContacts().catch(() => {});
|
||
});
|
||
function isPinned(item) {
|
||
return item?.resultKind === 'conversation' && Number(item.pinnedAt || item.top || 0) > 0;
|
||
}
|
||
function openConversationMenu(event, item) {
|
||
if (item.resultKind !== 'conversation') return;
|
||
conversationMenu.value = {
|
||
item,
|
||
x: Math.min(event.clientX, window.innerWidth - 140),
|
||
y: Math.min(event.clientY, window.innerHeight - 60)
|
||
};
|
||
}
|
||
function closeConversationMenu() {
|
||
conversationMenu.value = {
|
||
item: null,
|
||
x: 0,
|
||
y: 0
|
||
};
|
||
}
|
||
function togglePinned() {
|
||
const item = conversationMenu.value.item;
|
||
if (item) conversations.togglePinnedConversation(item.id);
|
||
closeConversationMenu();
|
||
}
|
||
const ContactPicker = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .defineComponent */ .pM)({
|
||
name: 'ContactPicker',
|
||
props: {
|
||
contacts: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
selectedIds: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
keyword: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
emptyText: {
|
||
type: String,
|
||
default: '暂无联系人'
|
||
}
|
||
},
|
||
emits: ['toggle', 'update:keyword'],
|
||
setup(props, {
|
||
emit
|
||
}) {
|
||
return () => (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
|
||
class: 'contact-picker'
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('input', {
|
||
value: props.keyword,
|
||
placeholder: '搜索联系人',
|
||
onInput: event => emit('update:keyword', event.target.value)
|
||
}), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
|
||
class: 'contact-picker-list'
|
||
}, props.contacts.length ? props.contacts.map(contact => (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('button', {
|
||
key: contact.uid,
|
||
type: 'button',
|
||
class: ['contact-picker-row', {
|
||
selected: props.selectedIds.includes(contact.uid)
|
||
}],
|
||
onClick: () => emit('toggle', contact.uid)
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
|
||
class: 'contact-check'
|
||
}, props.selectedIds.includes(contact.uid) ? '✓' : ''), contact.portrait ? (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('img', {
|
||
class: 'conversation-avatar image-avatar',
|
||
src: contact.portrait,
|
||
alt: ''
|
||
}) : (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
|
||
class: 'conversation-avatar'
|
||
}, contact.avatarText), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('span', {
|
||
class: 'contact-picker-copy'
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('strong', contact.title), (0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('small', contact.subtitle)])])) : [(0,vue__WEBPACK_IMPORTED_MODULE_17__.h)('div', {
|
||
class: 'contact-picker-empty'
|
||
}, props.emptyText)])]);
|
||
}
|
||
});
|
||
function searchableValues(...values) {
|
||
return values.flatMap(value => {
|
||
if (Array.isArray(value)) {
|
||
return value;
|
||
}
|
||
if (value && typeof value === 'object') {
|
||
return Object.values(value);
|
||
}
|
||
return [value];
|
||
}).map(value => String(value || '').toLowerCase()).filter(Boolean);
|
||
}
|
||
function matchesKeyword(values, keyword) {
|
||
const compactKeyword = keyword.replace(/[^\p{L}\p{N}]+/gu, '');
|
||
return searchableValues(values).some(value => {
|
||
if (value.includes(keyword)) {
|
||
return true;
|
||
}
|
||
if (!compactKeyword) {
|
||
return false;
|
||
}
|
||
return value.replace(/[^\p{L}\p{N}]+/gu, '').includes(compactKeyword);
|
||
});
|
||
}
|
||
function conversationTarget(item) {
|
||
if (item.type !== 'single') {
|
||
return String(item.target || item.raw?.target || item.id || '');
|
||
}
|
||
return String(item.target || item.raw?.target || item.id.replace(/^single-/, '') || '');
|
||
}
|
||
function contactForConversation(item) {
|
||
const target = conversationTarget(item);
|
||
return target ? contactsByUid.value.get(target) || null : null;
|
||
}
|
||
function matchesConversation(item, keyword, contact = null) {
|
||
return matchesKeyword([item.title, item.subtitle, item.target, item.id, item.type, item.raw?.target, item.raw?.groupId, item.raw?.group_id, item.raw?.owner_uid, item.raw?.name, item.raw?.displayName, item.raw?.mobile, item.raw?.friendAlias, item.raw?.alias, contact?.title, contact?.subtitle, contact?.uid, contact?.id, contact?.alias, contact?.address, contact?.rawUser, contact?.rawFriend], keyword);
|
||
}
|
||
function matchesContact(item, keyword) {
|
||
return matchesKeyword([item.title, item.subtitle, item.uid, item.id, item.alias, item.address, item.rawUser, item.rawFriend], keyword);
|
||
}
|
||
function conversationResult(item) {
|
||
return {
|
||
...item,
|
||
resultKind: 'conversation',
|
||
resultKey: `conversation-${item.id}`
|
||
};
|
||
}
|
||
function contactResult(contact) {
|
||
return {
|
||
id: contact.id,
|
||
resultKind: 'contact',
|
||
resultKey: `contact-${contact.uid || contact.id}`,
|
||
contact,
|
||
title: contact.title,
|
||
subtitle: contact.subtitle,
|
||
portrait: contact.portrait,
|
||
avatarText: contact.avatarText,
|
||
unread: 0
|
||
};
|
||
}
|
||
function isListItemActive(item) {
|
||
if (item.resultKind === 'conversation') {
|
||
return item.id === conversations.activeId;
|
||
}
|
||
return `single-${item.contact?.uid || item.id}` === conversations.activeId;
|
||
}
|
||
function selectListItem(item) {
|
||
if (item.resultKind === 'contact') {
|
||
contacts.openChat(item.contact);
|
||
return;
|
||
}
|
||
conversations.setActiveConversation(item.id);
|
||
}
|
||
function clearStoreMessages() {
|
||
contacts.actionError = '';
|
||
contacts.actionInfo = '';
|
||
conversations.actionError = '';
|
||
conversations.actionNotice = '';
|
||
}
|
||
function resetActionFields() {
|
||
addKeyword.value = '';
|
||
groupName.value = '';
|
||
groupAnnouncement.value = '';
|
||
groupWelcomeText.value = '';
|
||
joinGroupKey.value = '';
|
||
broadcastText.value = '';
|
||
channelName.value = '';
|
||
channelAnnouncement.value = '';
|
||
contactKeyword.value = '';
|
||
selectedContactIds.value = [];
|
||
clearStoreMessages();
|
||
}
|
||
function toggleActionMenu() {
|
||
actionMenuOpen.value = !actionMenuOpen.value;
|
||
}
|
||
function closeActionMenu() {
|
||
actionMenuOpen.value = false;
|
||
}
|
||
function openAction(action) {
|
||
resetActionFields();
|
||
activeAction.value = action;
|
||
actionMenuOpen.value = false;
|
||
if (['createGroup', 'broadcast', 'createChannel'].includes(action)) {
|
||
contacts.refreshContacts({
|
||
force: true
|
||
});
|
||
}
|
||
}
|
||
function closeActionModal() {
|
||
activeAction.value = '';
|
||
actionBusy.value = false;
|
||
resetActionFields();
|
||
}
|
||
function toggleContact(contactId) {
|
||
const selected = new Set(selectedContactIds.value);
|
||
if (selected.has(contactId)) {
|
||
selected.delete(contactId);
|
||
} else {
|
||
selected.add(contactId);
|
||
}
|
||
selectedContactIds.value = Array.from(selected);
|
||
}
|
||
async function submitAction() {
|
||
if (submitDisabled.value || actionBusy.value) {
|
||
return;
|
||
}
|
||
actionBusy.value = true;
|
||
clearStoreMessages();
|
||
try {
|
||
let ok = false;
|
||
if (activeAction.value === 'addContact') {
|
||
ok = await contacts.addContact(addKeyword.value);
|
||
if (ok && contacts.activeContact) {
|
||
contacts.openChat(contacts.activeContact);
|
||
}
|
||
} else if (activeAction.value === 'createGroup') {
|
||
ok = await conversations.createGroup({
|
||
name: groupName.value,
|
||
announcement: groupAnnouncement.value,
|
||
welcomeText: groupWelcomeText.value,
|
||
memberIds: selectedContactIds.value
|
||
});
|
||
} else if (activeAction.value === 'joinGroup') {
|
||
ok = await conversations.joinGroup(joinGroupKey.value);
|
||
} else if (activeAction.value === 'broadcast') {
|
||
ok = await conversations.broadcastMessage(selectedContactIds.value, broadcastText.value);
|
||
} else if (activeAction.value === 'createChannel') {
|
||
ok = await conversations.createGroup({
|
||
name: channelName.value,
|
||
memberIds: selectedContactIds.value,
|
||
announcement: channelAnnouncement.value,
|
||
channel: true
|
||
});
|
||
}
|
||
if (ok) {
|
||
window.setTimeout(closeActionModal, 450);
|
||
}
|
||
} finally {
|
||
actionBusy.value = false;
|
||
}
|
||
}
|
||
document.addEventListener('click', closeActionMenu);
|
||
document.addEventListener('click', closeConversationMenu);
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .onBeforeUnmount */ .xo)(() => {
|
||
document.removeEventListener('click', closeActionMenu);
|
||
document.removeEventListener('click', closeConversationMenu);
|
||
});
|
||
function formatUnread(value) {
|
||
const count = Number(value || 0);
|
||
return count > 99 ? '99+' : String(count);
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("header", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", null, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("h2", null, "消息", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).totalUnread) + " 条未读", 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
class: "icon-button",
|
||
title: "新建会话",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(toggleActionMenu, ["stop"])
|
||
}, "+"), actionMenuOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "quick-action-menu",
|
||
onClick: _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[0] || (_cache[0] = $event => openAction('addContact'))
|
||
}, "添加联系人"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[1] || (_cache[1] = $event => openAction('createGroup'))
|
||
}, "新建群组"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[2] || (_cache[2] = $event => openAction('joinGroup'))
|
||
}, "加入群组"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[3] || (_cache[3] = $event => openAction('broadcast'))
|
||
}, "群发助手"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: _cache[4] || (_cache[4] = $event => openAction('createChannel'))
|
||
}, "创建频道/公告群")])) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[6] || (_cache[6] = $event => searchKeyword.value = $event),
|
||
placeholder: "搜索会话、联系人"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, searchKeyword.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .renderList */ .pI)(filteredConversationItems.value, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("button", {
|
||
key: item.resultKey,
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .normalizeClass */ .C4)(["conversation-item", {
|
||
active: isListItemActive(item),
|
||
pinned: isPinned(item)
|
||
}]),
|
||
onClick: $event => selectListItem(item),
|
||
onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)($event => openConversationMenu($event, item), ["prevent"])
|
||
}, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
class: "conversation-avatar image-avatar",
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_22__/* .imageDisplayUrl */ .B)(item.portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.avatarText), 1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, [isPinned(item) ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", _hoisted_10, "⌖")) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createTextVNode */ .eW)((0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.title), 1)]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("small", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(item.subtitle), 1)]), Number(item.unread || 0) > 0 ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("span", {
|
||
key: 2,
|
||
class: "unread-badge",
|
||
"aria-label": `${item.unread} 条未读消息`
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(formatUnread(item.unread)), 9, _hoisted_11)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)], 42, _hoisted_6);
|
||
}), 128)), conversationMenu.value.item ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "conversation-context-menu",
|
||
style: (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .normalizeStyle */ .Tr)({
|
||
left: `${conversationMenu.value.x}px`,
|
||
top: `${conversationMenu.value.y}px`
|
||
}),
|
||
onClick: _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(() => {}, ["stop"]))
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
onClick: togglePinned
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(isPinned(conversationMenu.value.item) ? '取消置顶' : '置顶会话'), 1)], 4)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), !filteredConversationItems.value.length && searchKeyword.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", _hoisted_12, _cache[20] || (_cache[20] = [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, "没有匹配结果", -1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "换个关键词再试试", -1)]))) : !(0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).conversations.length && !(0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(conversations).usingDemoData ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", _hoisted_13, _cache[21] || (_cache[21] = [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, "暂无会话", -1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "收到或发起消息后会出现在这里", -1)]))) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)]), activeAction.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(closeActionModal, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("form", {
|
||
class: "modal-panel conversation-action-panel",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_16__/* .withModifiers */ .D$)(submitAction, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("header", null, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("strong", null, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(actionTitle.value), 1), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeActionModal
|
||
}, "×")]), activeAction.value === 'addContact' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("label", _hoisted_14, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "用户ID / 手机号 / 用户名", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[8] || (_cache[8] = $event => addKeyword.value = $event),
|
||
autocomplete: "off",
|
||
placeholder: "请输入要添加的联系人"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, addKeyword.value, void 0, {
|
||
trim: true
|
||
}]])])) : activeAction.value === 'createGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
|
||
key: 1
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群组名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[9] || (_cache[9] = $event => groupName.value = $event),
|
||
maxlength: "64",
|
||
autocomplete: "off",
|
||
placeholder: "请输入群组名称"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupName.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[10] || (_cache[10] = $event => groupAnnouncement.value = $event),
|
||
maxlength: "1000",
|
||
rows: "3",
|
||
placeholder: "可选"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupAnnouncement.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "欢迎词", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[11] || (_cache[11] = $event => groupWelcomeText.value = $event),
|
||
maxlength: "1000",
|
||
rows: "3",
|
||
placeholder: "群组创建后自动发送"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, groupWelcomeText.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
|
||
contacts: filteredContacts.value,
|
||
"selected-ids": selectedContactIds.value,
|
||
keyword: contactKeyword.value,
|
||
"empty-text": "暂无可选联系人",
|
||
"onUpdate:keyword": _cache[12] || (_cache[12] = $event => contactKeyword.value = $event),
|
||
onToggle: toggleContact
|
||
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : activeAction.value === 'joinGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("label", _hoisted_15, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群组ID / 群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[13] || (_cache[13] = $event => joinGroupKey.value = $event),
|
||
autocomplete: "off",
|
||
placeholder: "请输入群组ID或群名称"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, joinGroupKey.value, void 0, {
|
||
trim: true
|
||
}]])])) : activeAction.value === 'broadcast' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
|
||
key: 3
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "群发内容", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[14] || (_cache[14] = $event => broadcastText.value = $event),
|
||
maxlength: "2000",
|
||
rows: "4",
|
||
placeholder: "输入要群发的文字"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, broadcastText.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
|
||
contacts: filteredContacts.value,
|
||
"selected-ids": selectedContactIds.value,
|
||
keyword: contactKeyword.value,
|
||
"empty-text": "暂无可选联系人",
|
||
"onUpdate:keyword": _cache[15] || (_cache[15] = $event => contactKeyword.value = $event),
|
||
onToggle: toggleContact
|
||
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : activeAction.value === 'createChannel' ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_17__/* .Fragment */ .FK, {
|
||
key: 4
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "频道/公告群名称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[16] || (_cache[16] = $event => channelName.value = $event),
|
||
maxlength: "64",
|
||
autocomplete: "off",
|
||
placeholder: "请输入名称"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, channelName.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("label", null, [_cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("span", null, "公告说明", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("textarea", {
|
||
"onUpdate:modelValue": _cache[17] || (_cache[17] = $event => channelAnnouncement.value = $event),
|
||
maxlength: "1000",
|
||
rows: "3",
|
||
placeholder: "可选"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_16__/* .vModelText */ .Jo, channelAnnouncement.value, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createVNode */ .bF)((0,vue__WEBPACK_IMPORTED_MODULE_18__/* .unref */ .R1)(ContactPicker), {
|
||
contacts: filteredContacts.value,
|
||
"selected-ids": selectedContactIds.value,
|
||
keyword: contactKeyword.value,
|
||
"empty-text": "暂无可选联系人",
|
||
"onUpdate:keyword": _cache[18] || (_cache[18] = $event => contactKeyword.value = $event),
|
||
onToggle: toggleContact
|
||
}, null, 8, ["contacts", "selected-ids", "keyword"])], 64)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), modalError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("p", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(modalError.value), 1)) : modalInfo.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_17__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementBlock */ .CE)("p", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(modalInfo.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("div", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: closeActionModal
|
||
}, "取消"), (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-inline-action",
|
||
disabled: actionBusy.value || submitDisabled.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_19__/* .toDisplayString */ .v_)(actionBusy.value ? '处理中...' : submitLabel.value), 9, _hoisted_19)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_17__/* .createCommentVNode */ .Q3)("", true)]);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7420:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5130);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6768);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(144);
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5187);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(926);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(446);
|
||
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(1414);
|
||
/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(9045);
|
||
|
||
|
||
|
||
const _hoisted_1 = {
|
||
class: "navigation-rail"
|
||
};
|
||
const _hoisted_2 = ["src"];
|
||
const _hoisted_3 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_4 = {
|
||
class: "settings-panel"
|
||
};
|
||
const _hoisted_5 = {
|
||
class: "settings-layout"
|
||
};
|
||
const _hoisted_6 = {
|
||
class: "settings-menu",
|
||
"aria-label": "设置菜单"
|
||
};
|
||
const _hoisted_7 = ["onClick"];
|
||
const _hoisted_8 = {
|
||
key: 0
|
||
};
|
||
const _hoisted_9 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_10 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_11 = ["disabled"];
|
||
const _hoisted_12 = {
|
||
key: 1,
|
||
class: "settings-placeholder"
|
||
};
|
||
const _hoisted_13 = {
|
||
class: "profile-avatar-field"
|
||
};
|
||
const _hoisted_14 = ["src"];
|
||
const _hoisted_15 = {
|
||
key: 1
|
||
};
|
||
const _hoisted_16 = ["value"];
|
||
const _hoisted_17 = {
|
||
class: "modal-actions"
|
||
};
|
||
const _hoisted_18 = {
|
||
key: 0,
|
||
class: "inline-save-status"
|
||
};
|
||
const _hoisted_19 = {
|
||
key: 1,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_20 = ["disabled"];
|
||
const _hoisted_21 = {
|
||
class: "avatar-preview-dialog"
|
||
};
|
||
const _hoisted_22 = {
|
||
class: "avatar-preview-actions"
|
||
};
|
||
const _hoisted_23 = ["src"];
|
||
const _hoisted_24 = {
|
||
class: "modal-panel avatar-cropper-panel"
|
||
};
|
||
const _hoisted_25 = {
|
||
class: "avatar-cropper-header-actions"
|
||
};
|
||
const _hoisted_26 = ["disabled"];
|
||
const _hoisted_27 = {
|
||
class: "avatar-cropper-layout"
|
||
};
|
||
const _hoisted_28 = {
|
||
key: 0,
|
||
class: "avatar-cropper-placeholder"
|
||
};
|
||
const _hoisted_29 = {
|
||
class: "avatar-cropper-controls"
|
||
};
|
||
const _hoisted_30 = {
|
||
class: "avatar-cropper-tools"
|
||
};
|
||
const _hoisted_31 = {
|
||
class: "avatar-cropper-preview"
|
||
};
|
||
const _hoisted_32 = {
|
||
key: 0,
|
||
class: "inline-save-status error"
|
||
};
|
||
const _hoisted_33 = ["disabled"];
|
||
const _hoisted_34 = ["disabled"];
|
||
|
||
|
||
|
||
|
||
|
||
const CROP_OUTPUT_SIZE = 512;
|
||
/* harmony default export */ __webpack_exports__.A = ({
|
||
__name: 'NavigationRail',
|
||
setup(__props) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_6__/* .useSessionStore */ .B)();
|
||
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_8__/* .useNavigationStore */ .l)();
|
||
const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_9__/* .useContactStore */ .p)();
|
||
const settingsItems = [{
|
||
key: 'notifications',
|
||
label: '通知设置'
|
||
}, {
|
||
key: 'password',
|
||
label: '更改密码'
|
||
}, {
|
||
key: 'wallet',
|
||
label: '钱包管理'
|
||
}, {
|
||
key: 'language',
|
||
label: '切换语言'
|
||
}, {
|
||
key: 'feedback',
|
||
label: '问题反馈'
|
||
}];
|
||
const initials = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => (session.displayName || session.userId || 'Q').slice(0, 1).toUpperCase());
|
||
const settingsOpen = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
|
||
const settingsSection = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('password');
|
||
const passwordSaving = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
|
||
const settingsNotice = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
|
||
const settingsError = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
|
||
const profileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
|
||
const profileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(false);
|
||
const profileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
|
||
const profileError = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
|
||
const profileFile = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
|
||
const profilePreview = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)('');
|
||
const portraitInput = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
|
||
const cropperCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
|
||
const cropperPreviewCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)(null);
|
||
const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .ref */ .KR)({
|
||
displayName: ''
|
||
});
|
||
const passwordDraft = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
|
||
oldPassword: '',
|
||
newPassword: '',
|
||
confirmPassword: ''
|
||
});
|
||
const currentAvatarUrl = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => profilePreview.value || session.portrait || '');
|
||
const activeSettingsItem = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => settingsItems.find(item => item.key === settingsSection.value) || settingsItems[0]);
|
||
const avatarPreviewViewer = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
|
||
open: false,
|
||
url: '',
|
||
scale: 1,
|
||
offsetX: 0,
|
||
offsetY: 0,
|
||
dragging: false,
|
||
dragStartX: 0,
|
||
dragStartY: 0,
|
||
dragOffsetX: 0,
|
||
dragOffsetY: 0
|
||
});
|
||
const avatarCropper = (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .reactive */ .Kh)({
|
||
open: false,
|
||
loaded: false,
|
||
busy: false,
|
||
error: '',
|
||
objectUrl: '',
|
||
fileName: 'avatar.jpg',
|
||
image: null,
|
||
baseScale: 1,
|
||
scale: 1,
|
||
rotation: 0,
|
||
offsetX: 0,
|
||
offsetY: 0,
|
||
dragging: false,
|
||
dragStartX: 0,
|
||
dragStartY: 0,
|
||
dragOffsetX: 0,
|
||
dragOffsetY: 0
|
||
});
|
||
const avatarPreviewStyle = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .computed */ .EW)(() => ({
|
||
transform: `translate3d(${avatarPreviewViewer.offsetX}px, ${avatarPreviewViewer.offsetY}px, 0) scale(${avatarPreviewViewer.scale})`
|
||
}));
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onMounted */ .sV)(() => {
|
||
session.refreshProfile();
|
||
window.addEventListener('resize', drawAvatarCropper);
|
||
});
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .onBeforeUnmount */ .xo)(() => {
|
||
revokeProfilePreview();
|
||
closeAvatarCropper();
|
||
window.removeEventListener('resize', drawAvatarCropper);
|
||
});
|
||
function showContacts() {
|
||
navigation.showContacts();
|
||
contacts.refreshContacts();
|
||
}
|
||
function clearProfileFeedback() {
|
||
profileNotice.value = '';
|
||
profileError.value = '';
|
||
}
|
||
function clearSettingsFeedback() {
|
||
settingsNotice.value = '';
|
||
settingsError.value = '';
|
||
}
|
||
function resetPasswordDraft() {
|
||
passwordDraft.oldPassword = '';
|
||
passwordDraft.newPassword = '';
|
||
passwordDraft.confirmPassword = '';
|
||
}
|
||
function openSettings() {
|
||
settingsOpen.value = true;
|
||
settingsSection.value = 'password';
|
||
clearSettingsFeedback();
|
||
}
|
||
function closeSettings() {
|
||
if (passwordSaving.value) {
|
||
return;
|
||
}
|
||
settingsOpen.value = false;
|
||
clearSettingsFeedback();
|
||
resetPasswordDraft();
|
||
}
|
||
function selectSettingsSection(section) {
|
||
settingsSection.value = section;
|
||
clearSettingsFeedback();
|
||
}
|
||
function revokeProfilePreview() {
|
||
if (profilePreview.value) {
|
||
URL.revokeObjectURL(profilePreview.value);
|
||
profilePreview.value = '';
|
||
}
|
||
}
|
||
function revokeCropperObjectUrl() {
|
||
if (avatarCropper.objectUrl) {
|
||
URL.revokeObjectURL(avatarCropper.objectUrl);
|
||
avatarCropper.objectUrl = '';
|
||
}
|
||
}
|
||
async function openProfileEditor() {
|
||
profileOpen.value = true;
|
||
clearProfileFeedback();
|
||
profileDraft.value.displayName = session.displayName || session.userId || '';
|
||
const profile = await session.refreshProfile();
|
||
if (profileOpen.value && profile) {
|
||
profileDraft.value.displayName = session.displayName || session.userId || '';
|
||
}
|
||
}
|
||
function closeProfileEditor() {
|
||
profileOpen.value = false;
|
||
profileFile.value = null;
|
||
clearProfileFeedback();
|
||
revokeProfilePreview();
|
||
closeAvatarPreview();
|
||
closeAvatarCropper();
|
||
}
|
||
function selectPortrait(event) {
|
||
const file = event.target.files?.[0] || null;
|
||
event.target.value = '';
|
||
clearProfileFeedback();
|
||
if (file) {
|
||
openAvatarCropper(file);
|
||
}
|
||
}
|
||
function choosePortraitFile() {
|
||
portraitInput.value?.click();
|
||
}
|
||
function openAvatarPreview() {
|
||
if (!currentAvatarUrl.value) {
|
||
return;
|
||
}
|
||
avatarPreviewViewer.open = true;
|
||
avatarPreviewViewer.url = currentAvatarUrl.value;
|
||
resetAvatarPreview();
|
||
}
|
||
function closeAvatarPreview() {
|
||
avatarPreviewViewer.open = false;
|
||
avatarPreviewViewer.dragging = false;
|
||
}
|
||
function resetAvatarPreview() {
|
||
avatarPreviewViewer.scale = 1;
|
||
avatarPreviewViewer.offsetX = 0;
|
||
avatarPreviewViewer.offsetY = 0;
|
||
}
|
||
function zoomAvatarPreview(factor) {
|
||
avatarPreviewViewer.scale = Math.max(0.5, Math.min(6, Number((avatarPreviewViewer.scale * factor).toFixed(2))));
|
||
if (avatarPreviewViewer.scale <= 1) {
|
||
avatarPreviewViewer.offsetX = 0;
|
||
avatarPreviewViewer.offsetY = 0;
|
||
}
|
||
}
|
||
function handleAvatarPreviewWheel(event) {
|
||
zoomAvatarPreview(event.deltaY < 0 ? 1.12 : 1 / 1.12);
|
||
}
|
||
function startAvatarPreviewDrag(event) {
|
||
if (avatarPreviewViewer.scale <= 1) {
|
||
return;
|
||
}
|
||
avatarPreviewViewer.dragging = true;
|
||
avatarPreviewViewer.dragStartX = event.clientX;
|
||
avatarPreviewViewer.dragStartY = event.clientY;
|
||
avatarPreviewViewer.dragOffsetX = avatarPreviewViewer.offsetX;
|
||
avatarPreviewViewer.dragOffsetY = avatarPreviewViewer.offsetY;
|
||
event.currentTarget.setPointerCapture?.(event.pointerId);
|
||
}
|
||
function moveAvatarPreviewDrag(event) {
|
||
if (!avatarPreviewViewer.dragging) {
|
||
return;
|
||
}
|
||
avatarPreviewViewer.offsetX = avatarPreviewViewer.dragOffsetX + event.clientX - avatarPreviewViewer.dragStartX;
|
||
avatarPreviewViewer.offsetY = avatarPreviewViewer.dragOffsetY + event.clientY - avatarPreviewViewer.dragStartY;
|
||
}
|
||
function stopAvatarPreviewDrag() {
|
||
avatarPreviewViewer.dragging = false;
|
||
}
|
||
function dropPortrait(event) {
|
||
const file = Array.from(event.dataTransfer?.files || []).find(item => item.type.startsWith('image/'));
|
||
if (file) {
|
||
clearProfileFeedback();
|
||
openAvatarCropper(file);
|
||
}
|
||
}
|
||
function cropperStageSize() {
|
||
const canvas = cropperCanvas.value;
|
||
const rect = canvas?.getBoundingClientRect();
|
||
const width = Math.max(280, Math.round(rect?.width || 360));
|
||
const height = Math.max(280, Math.round(rect?.height || 360));
|
||
return {
|
||
width,
|
||
height
|
||
};
|
||
}
|
||
function cropperBoxSize() {
|
||
const {
|
||
width,
|
||
height
|
||
} = cropperStageSize();
|
||
return Math.round(Math.min(width, height) * 0.74);
|
||
}
|
||
function rotatedImageSize() {
|
||
const image = avatarCropper.image;
|
||
if (!image) {
|
||
return {
|
||
width: 1,
|
||
height: 1
|
||
};
|
||
}
|
||
const quarterTurn = Math.abs(avatarCropper.rotation % 180) === 90;
|
||
return {
|
||
width: quarterTurn ? image.naturalHeight : image.naturalWidth,
|
||
height: quarterTurn ? image.naturalWidth : image.naturalHeight
|
||
};
|
||
}
|
||
function clampCropperOffset() {
|
||
const cropSize = cropperBoxSize();
|
||
const rotated = rotatedImageSize();
|
||
const scaledWidth = rotated.width * avatarCropper.scale;
|
||
const scaledHeight = rotated.height * avatarCropper.scale;
|
||
const maxX = Math.max(0, (scaledWidth - cropSize) / 2);
|
||
const maxY = Math.max(0, (scaledHeight - cropSize) / 2);
|
||
avatarCropper.offsetX = Math.max(-maxX, Math.min(maxX, avatarCropper.offsetX));
|
||
avatarCropper.offsetY = Math.max(-maxY, Math.min(maxY, avatarCropper.offsetY));
|
||
}
|
||
function updateCropperBaseScale() {
|
||
const cropSize = cropperBoxSize();
|
||
const rotated = rotatedImageSize();
|
||
avatarCropper.baseScale = Math.max(cropSize / rotated.width, cropSize / rotated.height);
|
||
avatarCropper.scale = Math.max(avatarCropper.baseScale, avatarCropper.scale || avatarCropper.baseScale);
|
||
}
|
||
function drawCanvasImage(canvas, width, height, outputScale = 1, cropOnly = false) {
|
||
const image = avatarCropper.image;
|
||
if (!canvas || !image) {
|
||
return;
|
||
}
|
||
const dpr = cropOnly ? 1 : window.devicePixelRatio || 1;
|
||
canvas.width = Math.round(width * dpr);
|
||
canvas.height = Math.round(height * dpr);
|
||
const context = canvas.getContext('2d');
|
||
context.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||
context.clearRect(0, 0, width, height);
|
||
context.fillStyle = '#eef4f7';
|
||
context.fillRect(0, 0, width, height);
|
||
context.save();
|
||
context.translate(width / 2 + avatarCropper.offsetX * outputScale, height / 2 + avatarCropper.offsetY * outputScale);
|
||
context.rotate(avatarCropper.rotation * Math.PI / 180);
|
||
context.scale(avatarCropper.scale * outputScale, avatarCropper.scale * outputScale);
|
||
context.drawImage(image, -image.naturalWidth / 2, -image.naturalHeight / 2);
|
||
context.restore();
|
||
if (!cropOnly) {
|
||
const cropSize = cropperBoxSize();
|
||
context.save();
|
||
context.fillStyle = 'rgba(10, 18, 30, 0.42)';
|
||
context.beginPath();
|
||
context.rect(0, 0, width, height);
|
||
context.rect((width - cropSize) / 2, (height - cropSize) / 2, cropSize, cropSize);
|
||
context.fill('evenodd');
|
||
context.restore();
|
||
}
|
||
}
|
||
function drawAvatarCropper() {
|
||
if (!avatarCropper.open || !avatarCropper.loaded) {
|
||
return;
|
||
}
|
||
clampCropperOffset();
|
||
const {
|
||
width,
|
||
height
|
||
} = cropperStageSize();
|
||
drawCanvasImage(cropperCanvas.value, width, height);
|
||
const previewCanvas = cropperPreviewCanvas.value;
|
||
if (previewCanvas) {
|
||
drawCanvasImage(previewCanvas, 108, 108, 108 / cropperBoxSize(), true);
|
||
}
|
||
}
|
||
function resetCropperTransform() {
|
||
if (!avatarCropper.image) {
|
||
return;
|
||
}
|
||
avatarCropper.rotation = 0;
|
||
avatarCropper.offsetX = 0;
|
||
avatarCropper.offsetY = 0;
|
||
updateCropperBaseScale();
|
||
avatarCropper.scale = avatarCropper.baseScale;
|
||
drawAvatarCropper();
|
||
}
|
||
function openAvatarCropper(file) {
|
||
if (!file.type.startsWith('image/')) {
|
||
profileError.value = '请选择图片文件';
|
||
return;
|
||
}
|
||
if (file.size > 8 * 1024 * 1024) {
|
||
profileError.value = '头像图片不能超过8MB';
|
||
return;
|
||
}
|
||
closeAvatarCropper();
|
||
avatarCropper.open = true;
|
||
avatarCropper.loaded = false;
|
||
avatarCropper.error = '';
|
||
avatarCropper.fileName = file.name || 'avatar.jpg';
|
||
avatarCropper.objectUrl = URL.createObjectURL(file);
|
||
const image = new Image();
|
||
image.onload = () => {
|
||
avatarCropper.image = image;
|
||
avatarCropper.loaded = true;
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .nextTick */ .dY)(resetCropperTransform);
|
||
};
|
||
image.onerror = () => {
|
||
avatarCropper.error = '图片加载失败';
|
||
avatarCropper.loaded = false;
|
||
};
|
||
image.src = avatarCropper.objectUrl;
|
||
}
|
||
function closeAvatarCropper() {
|
||
avatarCropper.open = false;
|
||
avatarCropper.loaded = false;
|
||
avatarCropper.busy = false;
|
||
avatarCropper.error = '';
|
||
avatarCropper.image = null;
|
||
avatarCropper.dragging = false;
|
||
revokeCropperObjectUrl();
|
||
}
|
||
function zoomCropper(factor) {
|
||
if (!avatarCropper.loaded) {
|
||
return;
|
||
}
|
||
updateCropperBaseScale();
|
||
avatarCropper.scale = Math.max(avatarCropper.baseScale, Math.min(avatarCropper.baseScale * 6, avatarCropper.scale * factor));
|
||
drawAvatarCropper();
|
||
}
|
||
function rotateCropper(degrees) {
|
||
if (!avatarCropper.loaded) {
|
||
return;
|
||
}
|
||
avatarCropper.rotation = (avatarCropper.rotation + degrees + 360) % 360;
|
||
updateCropperBaseScale();
|
||
clampCropperOffset();
|
||
drawAvatarCropper();
|
||
}
|
||
function handleCropperWheel(event) {
|
||
zoomCropper(event.deltaY < 0 ? 1.08 : 1 / 1.08);
|
||
}
|
||
function startCropperDrag(event) {
|
||
if (!avatarCropper.loaded) {
|
||
return;
|
||
}
|
||
avatarCropper.dragging = true;
|
||
avatarCropper.dragStartX = event.clientX;
|
||
avatarCropper.dragStartY = event.clientY;
|
||
avatarCropper.dragOffsetX = avatarCropper.offsetX;
|
||
avatarCropper.dragOffsetY = avatarCropper.offsetY;
|
||
event.currentTarget.setPointerCapture?.(event.pointerId);
|
||
}
|
||
function moveCropperDrag(event) {
|
||
if (!avatarCropper.dragging) {
|
||
return;
|
||
}
|
||
avatarCropper.offsetX = avatarCropper.dragOffsetX + event.clientX - avatarCropper.dragStartX;
|
||
avatarCropper.offsetY = avatarCropper.dragOffsetY + event.clientY - avatarCropper.dragStartY;
|
||
drawAvatarCropper();
|
||
}
|
||
function stopCropperDrag() {
|
||
avatarCropper.dragging = false;
|
||
}
|
||
function canvasToBlob(canvas, type = 'image/jpeg', quality = 0.9) {
|
||
return new Promise((resolve, reject) => {
|
||
canvas.toBlob(blob => {
|
||
if (blob) {
|
||
resolve(blob);
|
||
} else {
|
||
reject(new Error('头像裁切失败'));
|
||
}
|
||
}, type, quality);
|
||
});
|
||
}
|
||
async function confirmAvatarCrop() {
|
||
if (!avatarCropper.loaded || avatarCropper.busy) {
|
||
return;
|
||
}
|
||
avatarCropper.busy = true;
|
||
avatarCropper.error = '';
|
||
try {
|
||
const outputCanvas = document.createElement('canvas');
|
||
drawCanvasImage(outputCanvas, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE / cropperBoxSize(), true);
|
||
const blob = await canvasToBlob(outputCanvas);
|
||
const fileName = avatarCropper.fileName.replace(/\.[^.]+$/, '') || 'avatar';
|
||
const croppedFile = new File([blob], `${fileName}.jpg`, {
|
||
type: 'image/jpeg'
|
||
});
|
||
profileFile.value = croppedFile;
|
||
revokeProfilePreview();
|
||
profilePreview.value = URL.createObjectURL(croppedFile);
|
||
closeAvatarCropper();
|
||
} catch (error) {
|
||
avatarCropper.error = error.message || '头像裁切失败';
|
||
} finally {
|
||
avatarCropper.busy = false;
|
||
}
|
||
}
|
||
async function saveProfile() {
|
||
if (profileSaving.value || !profileDraft.value.displayName) {
|
||
return;
|
||
}
|
||
clearProfileFeedback();
|
||
profileSaving.value = true;
|
||
try {
|
||
await session.saveProfile({
|
||
displayName: profileDraft.value.displayName,
|
||
portraitFile: profileFile.value
|
||
});
|
||
profileFile.value = null;
|
||
revokeProfilePreview();
|
||
profileNotice.value = '资料已保存';
|
||
contacts.refreshContacts({
|
||
force: true
|
||
});
|
||
} catch (error) {
|
||
profileError.value = error.message || '资料保存失败';
|
||
} finally {
|
||
profileSaving.value = false;
|
||
}
|
||
}
|
||
async function savePassword() {
|
||
if (passwordSaving.value) {
|
||
return;
|
||
}
|
||
clearSettingsFeedback();
|
||
const oldPassword = passwordDraft.oldPassword;
|
||
const newPassword = passwordDraft.newPassword;
|
||
const confirmPassword = passwordDraft.confirmPassword;
|
||
if (!oldPassword || !newPassword || !confirmPassword) {
|
||
settingsError.value = '请填写完整密码';
|
||
return;
|
||
}
|
||
if (newPassword !== confirmPassword) {
|
||
settingsError.value = '两次输入的新密码不一致';
|
||
return;
|
||
}
|
||
if (oldPassword === newPassword) {
|
||
settingsError.value = '新密码不能和当前密码相同';
|
||
return;
|
||
}
|
||
passwordSaving.value = true;
|
||
try {
|
||
await session.changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
});
|
||
resetPasswordDraft();
|
||
settingsNotice.value = '密码已更新';
|
||
} catch (error) {
|
||
settingsError.value = error.message || '密码修改失败';
|
||
} finally {
|
||
passwordSaving.value = false;
|
||
}
|
||
}
|
||
function logout() {
|
||
closeSettings();
|
||
contacts.clearContacts();
|
||
session.logout();
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, null, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("aside", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "rail-avatar rail-avatar-button",
|
||
title: "编辑个人资料",
|
||
onClick: openProfileEditor
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__/* .imageDisplayUrl */ .B)((0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).portrait),
|
||
alt: ""
|
||
}, null, 8, _hoisted_2)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(initials.value), 1))]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
|
||
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'messages'
|
||
}]),
|
||
title: "消息",
|
||
onClick: _cache[0] || (_cache[0] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showMessages && (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showMessages(...args))
|
||
}, "💬", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
|
||
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'contacts'
|
||
}]),
|
||
title: "联系人",
|
||
onClick: showContacts
|
||
}, "👥", 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["rail-button", {
|
||
active: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).section === 'favorites'
|
||
}]),
|
||
title: "收藏",
|
||
onClick: _cache[1] || (_cache[1] = (...args) => (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showFavorites && (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(navigation).showFavorites(...args))
|
||
}, "☆", 2), _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
|
||
class: "rail-spacer"
|
||
}, null, -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: "rail-button",
|
||
title: "设置",
|
||
"aria-label": "设置",
|
||
onClick: openSettings
|
||
}, _cache[13] || (_cache[13] = [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("svg", {
|
||
viewBox: "0 0 24 24",
|
||
"aria-hidden": "true"
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("path", {
|
||
d: "M12 8.2a3.8 3.8 0 1 1 0 7.6 3.8 3.8 0 0 1 0-7.6Z"
|
||
}), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("path", {
|
||
d: "M19.4 13.6a7.8 7.8 0 0 0 .1-1.6l1.7-1.3-1.7-3-2 .8a8 8 0 0 0-1.4-.8L15.8 5h-3.5l-.3 2.1a8 8 0 0 0-1.5.8l-1.9-.8-1.8 3 1.7 1.3a7.8 7.8 0 0 0 0 1.6l-1.7 1.3 1.8 3 1.9-.8c.5.4 1 .7 1.5.8l.3 2.1h3.5l.3-2.1c.5-.2 1-.5 1.4-.8l2 .8 1.7-3-1.8-1.3Z"
|
||
})], -1)])), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: "rail-button rail-logout-button",
|
||
title: "退出登录",
|
||
"aria-label": "退出登录",
|
||
onClick: logout
|
||
}, _cache[14] || (_cache[14] = [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createStaticVNode */ .Fv)("<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4.5 20.5V3.5h9.2a1.8 1.8 0 0 1 1.8 1.8v13.4a1.8 1.8 0 0 1-1.8 1.8H4.5Z\"></path><path d=\"M9 12h9.5\"></path><path d=\"m15.5 8.8 3.2 3.2-3.2 3.2\"></path><path d=\"M7.8 20.5V5.8l6.5-2.3\"></path></svg>", 1)]))]), settingsOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
|
||
key: 0,
|
||
class: "modal-backdrop settings-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeSettings, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "设置", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeSettings
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("nav", _hoisted_6, [((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)(vue__WEBPACK_IMPORTED_MODULE_3__/* .Fragment */ .FK, null, (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .renderList */ .pI)(settingsItems, item => {
|
||
return (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
key: item.key,
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)({
|
||
active: settingsSection.value === item.key
|
||
}),
|
||
onClick: $event => selectSettingsSection(item.key)
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(item.label), 1), item.key !== 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("small", _hoisted_8, "稍后开放")) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 10, _hoisted_7);
|
||
}), 64))]), settingsSection.value === 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("form", {
|
||
key: 0,
|
||
class: "settings-password-form",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(savePassword, ["prevent"])
|
||
}, [_cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("h3", null, "更改密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "当前密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => passwordDraft.oldPassword = $event),
|
||
type: "password",
|
||
autocomplete: "current-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.oldPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => passwordDraft.newPassword = $event),
|
||
type: "password",
|
||
autocomplete: "new-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.newPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "确认新密码", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => passwordDraft.confirmPassword = $event),
|
||
type: "password",
|
||
autocomplete: "new-password"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, passwordDraft.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("footer", null, [settingsNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(settingsNotice.value), 1)) : settingsError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(settingsError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "submit",
|
||
class: "primary-inline-action",
|
||
disabled: passwordSaving.value
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(passwordSaving.value ? '保存中...' : '保存密码'), 9, _hoisted_11)])], 32)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("section", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(activeSettingsItem.value?.label || '设置'), 1), _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("p", null, "该功能稍后开放。", -1))]))])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), profileOpen.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
|
||
key: 1,
|
||
class: "modal-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeProfileEditor, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("form", {
|
||
class: "modal-panel profile-edit-panel",
|
||
onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(saveProfile, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "个人资料", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeProfileEditor
|
||
}, "×")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["profile-avatar-preview", {
|
||
clickable: currentAvatarUrl.value
|
||
}]),
|
||
title: "预览头像",
|
||
onClick: openAvatarPreview
|
||
}, [currentAvatarUrl.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("img", {
|
||
key: 0,
|
||
src: currentAvatarUrl.value,
|
||
alt: ""
|
||
}, null, 8, _hoisted_14)) : ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(initials.value), 1))], 2), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action profile-avatar-change-button",
|
||
onClick: choosePortraitFile
|
||
}, "更换头像"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
ref_key: "portraitInput",
|
||
ref: portraitInput,
|
||
type: "file",
|
||
accept: "image/*",
|
||
onChange: selectPortrait
|
||
}, null, 544)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "昵称", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .withDirectives */ .bo)((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => profileDraft.value.displayName = $event),
|
||
maxlength: "64",
|
||
autocomplete: "off"
|
||
}, null, 512), [[vue__WEBPACK_IMPORTED_MODULE_2__/* .vModelText */ .Jo, profileDraft.value.displayName, void 0, {
|
||
trim: true
|
||
}]])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("label", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("span", null, "用户ID", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("input", {
|
||
value: (0,vue__WEBPACK_IMPORTED_MODULE_4__/* .unref */ .R1)(session).userId,
|
||
readonly: ""
|
||
}, null, 8, _hoisted_16)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
onClick: closeProfileEditor
|
||
}, "取消"), profileNotice.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_18, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileNotice.value), 1)) : profileError.value ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileError.value), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
class: "primary-inline-action",
|
||
disabled: profileSaving.value || !profileDraft.value.displayName
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(profileSaving.value ? '保存中...' : '保存'), 9, _hoisted_20)])], 32)])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), avatarPreviewViewer.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
|
||
key: 2,
|
||
class: "modal-backdrop avatar-preview-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeAvatarPreview, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "头像预览", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_22, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "缩小",
|
||
onClick: _cache[6] || (_cache[6] = $event => zoomAvatarPreview(1 / 1.16))
|
||
}, "−"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "放大",
|
||
onClick: _cache[7] || (_cache[7] = $event => zoomAvatarPreview(1.16))
|
||
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "还原",
|
||
onClick: resetAvatarPreview
|
||
}, "1:1"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeAvatarPreview
|
||
}, "×")])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["avatar-preview-stage", {
|
||
dragging: avatarPreviewViewer.dragging
|
||
}]),
|
||
onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(handleAvatarPreviewWheel, ["prevent"]),
|
||
onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(startAvatarPreviewDrag, ["prevent"]),
|
||
onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(moveAvatarPreviewDrag, ["prevent"]),
|
||
onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopAvatarPreviewDrag, ["prevent"]),
|
||
onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopAvatarPreviewDrag, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("img", {
|
||
src: avatarPreviewViewer.url,
|
||
alt: "头像预览",
|
||
style: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeStyle */ .Tr)(avatarPreviewStyle.value),
|
||
draggable: "false"
|
||
}, null, 12, _hoisted_23)], 34)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), avatarCropper.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", {
|
||
key: 3,
|
||
class: "modal-backdrop avatar-cropper-backdrop",
|
||
onClick: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(closeAvatarCropper, ["self"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("section", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("header", null, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("strong", null, "头像预裁切", -1)), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: avatarCropper.busy,
|
||
onClick: choosePortraitFile
|
||
}, "上传", 8, _hoisted_26), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "icon-button",
|
||
title: "关闭",
|
||
onClick: closeAvatarCropper
|
||
}, "×")])]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_27, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
|
||
class: (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .normalizeClass */ .C4)(["avatar-cropper-stage", {
|
||
dragging: avatarCropper.dragging
|
||
}]),
|
||
onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(handleCropperWheel, ["prevent"]),
|
||
onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(startCropperDrag, ["prevent"]),
|
||
onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(moveCropperDrag, ["prevent"]),
|
||
onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopCropperDrag, ["prevent"]),
|
||
onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(stopCropperDrag, ["prevent"]),
|
||
onDragover: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(() => {}, ["prevent"])),
|
||
onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_2__/* .withModifiers */ .D$)(dropPortrait, ["prevent"])
|
||
}, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("canvas", {
|
||
ref_key: "cropperCanvas",
|
||
ref: cropperCanvas
|
||
}, null, 512), _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
|
||
class: "avatar-cropper-mask",
|
||
"aria-hidden": "true"
|
||
}, null, -1)), _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", {
|
||
class: "avatar-cropper-box",
|
||
"aria-hidden": "true"
|
||
}, null, -1)), !avatarCropper.loaded ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("div", _hoisted_28, "图片加载中")) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 34), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("aside", _hoisted_29, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_30, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "左旋90度",
|
||
onClick: _cache[9] || (_cache[9] = $event => rotateCropper(-90))
|
||
}, "↶90°"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "右旋90度",
|
||
onClick: _cache[10] || (_cache[10] = $event => rotateCropper(90))
|
||
}, "↷90°"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "放大",
|
||
onClick: _cache[11] || (_cache[11] = $event => zoomCropper(1.12))
|
||
}, "+"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "缩小",
|
||
onClick: _cache[12] || (_cache[12] = $event => zoomCropper(1 / 1.12))
|
||
}, "−"), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
title: "重置",
|
||
onClick: resetCropperTransform
|
||
}, "重置")]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("div", _hoisted_31, [(0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("canvas", {
|
||
ref_key: "cropperPreviewCanvas",
|
||
ref: cropperPreviewCanvas
|
||
}, null, 512)]), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("footer", null, [avatarCropper.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_3__/* .openBlock */ .uX)(), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementBlock */ .CE)("span", _hoisted_32, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(avatarCropper.error), 1)) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "ghost-inline-action",
|
||
disabled: avatarCropper.busy,
|
||
onClick: closeAvatarCropper
|
||
}, "取消", 8, _hoisted_33), (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createElementVNode */ .Lk)("button", {
|
||
type: "button",
|
||
class: "primary-inline-action",
|
||
disabled: avatarCropper.busy || !avatarCropper.loaded,
|
||
onClick: confirmAvatarCrop
|
||
}, (0,vue__WEBPACK_IMPORTED_MODULE_5__/* .toDisplayString */ .v_)(avatarCropper.busy ? '处理中...' : '确认裁切'), 9, _hoisted_34)])])])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_3__/* .createCommentVNode */ .Q3)("", true)], 64);
|
||
};
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
|
||
/***/ 2169:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
const currentHost = window.location.hostname || '127.0.0.1';
|
||
const runtimeConfig = window.JC_WEB_IM_CONFIG || {};
|
||
const appServerOrigin = `${window.location.protocol}//${currentHost}:8888`;
|
||
const qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`;
|
||
const adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;
|
||
const appConfig = {
|
||
appName: 'Web IM',
|
||
adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin,
|
||
appServer: runtimeConfig.appServer || undefined || appServerOrigin,
|
||
qrAppServer: runtimeConfig.qrAppServer || undefined || qrAppServerOrigin,
|
||
platformConfigApi: runtimeConfig.platformConfigApi || undefined || ( false ? 0 : '/api/platform_config.php'),
|
||
registerConfigApi: runtimeConfig.registerConfigApi || undefined || `${adminServerOrigin}/api/register-config`,
|
||
registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || undefined || `${adminServerOrigin}/api/register-phone-exists`,
|
||
contactsApi: runtimeConfig.contactsApi || undefined || ( false ? 0 : '/api/contacts.php'),
|
||
updateAliasApi: runtimeConfig.updateAliasApi || undefined || ( false ? 0 : '/api/update_alias.php'),
|
||
addContactApi: runtimeConfig.addContactApi || undefined || ( false ? 0 : '/api/add_contact.php'),
|
||
conversationActionsApi: runtimeConfig.conversationActionsApi || undefined || ( false ? 0 : '/api/conversation_actions.php'),
|
||
sendMessageApi: runtimeConfig.sendMessageApi || undefined || ( false ? 0 : '/api/send_message.php'),
|
||
messageActionApi: runtimeConfig.messageActionApi || undefined || ( false ? 0 : '/api/message_action.php'),
|
||
messageDetailApi: runtimeConfig.messageDetailApi || undefined || ( false ? 0 : '/api/message_detail.php'),
|
||
messagesApi: runtimeConfig.messagesApi || undefined || ( false ? 0 : '/api/messages.php'),
|
||
profileApi: runtimeConfig.profileApi || undefined || ( false ? 0 : '/api/profile.php'),
|
||
changePasswordApi: runtimeConfig.changePasswordApi || undefined || `${appServerOrigin}/auth/changePassword`,
|
||
logoutApi: runtimeConfig.logoutApi || undefined || `${appServerOrigin}/auth/logout`,
|
||
imServerHost: runtimeConfig.imServerHost || undefined || currentHost,
|
||
imRoutePort: Number(runtimeConfig.imRoutePort || undefined || 18000),
|
||
useWss: runtimeConfig.useWss ?? undefined === 'true',
|
||
wsPath: runtimeConfig.wsPath || undefined || '/ws',
|
||
wsUrl: runtimeConfig.wsUrl || undefined || '',
|
||
sdkMode: runtimeConfig.sdkMode || undefined || 'http',
|
||
syncIntervalMs: Number(runtimeConfig.syncIntervalMs || undefined || 300),
|
||
sseEnabled: runtimeConfig.sseEnabled ?? undefined === 'true',
|
||
sseTicketApi: runtimeConfig.sseTicketApi || undefined || '/api/sse_ticket.php',
|
||
sseUrl: runtimeConfig.sseUrl || undefined || '/ws-events',
|
||
platform: 5,
|
||
clientIdStorageKey: 'qmt-web-im-client-id',
|
||
authTokenStoragePrefix: 'qmt-web-im-auth-token-'
|
||
};
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "U", 0, /* binding */ appConfig
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1406:
|
||
/***/ (function(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5130);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
|
||
/* harmony import */ var _App_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7067);
|
||
|
||
|
||
|
||
|
||
(0,vue__WEBPACK_IMPORTED_MODULE_0__/* .createApp */ .Ef)(_App_vue__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A).use((0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .createPinia */ .Ey)()).mount('#app');
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9311:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ Ln: function() { return /* binding */ appServerPost; },
|
||
/* harmony export */ Pd: function() { return /* binding */ getStoredAppAuth; },
|
||
/* harmony export */ eG: function() { return /* binding */ persistAppAuth; },
|
||
/* harmony export */ u$: function() { return /* binding */ clearStoredAppAuth; }
|
||
/* harmony export */ });
|
||
/* unused harmony exports appServerRequest, appServerGet */
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9577);
|
||
/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6632);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4226);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9486);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(456);
|
||
/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4979);
|
||
/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2387);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2169);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const AES_KEY = 'xczx2026!@#secKe';
|
||
const ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check'];
|
||
const AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1';
|
||
const AUTH_ERROR_CODE = 13;
|
||
const REFRESH_ERROR_CODE = 20045;
|
||
let importedCryptoKeyPromise = null;
|
||
let refreshPromise = null;
|
||
function storageScope() {
|
||
return _config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer || '';
|
||
}
|
||
function readAuthStore() {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function writeAuthStore(store) {
|
||
localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store));
|
||
}
|
||
function normalizeAuthBundle(bundle = {}) {
|
||
const accessToken = String(bundle.accessToken || '').trim();
|
||
const refreshToken = String(bundle.refreshToken || '').trim();
|
||
if (!accessToken || !refreshToken) {
|
||
return null;
|
||
}
|
||
return {
|
||
accessToken,
|
||
refreshToken,
|
||
tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer',
|
||
accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0,
|
||
accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0,
|
||
refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0,
|
||
refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0
|
||
};
|
||
}
|
||
function getStoredAppAuth() {
|
||
const store = readAuthStore();
|
||
return normalizeAuthBundle(store[storageScope()]);
|
||
}
|
||
function persistAppAuth(bundle) {
|
||
const normalized = normalizeAuthBundle(bundle);
|
||
const store = readAuthStore();
|
||
if (!normalized) {
|
||
delete store[storageScope()];
|
||
writeAuthStore(store);
|
||
return null;
|
||
}
|
||
store[storageScope()] = normalized;
|
||
writeAuthStore(store);
|
||
return normalized;
|
||
}
|
||
function clearStoredAppAuth() {
|
||
persistAppAuth(null);
|
||
}
|
||
function hasFormData(value) {
|
||
return typeof FormData !== 'undefined' && value instanceof FormData;
|
||
}
|
||
function absoluteUrl(url) {
|
||
return new URL(url, window.location.origin);
|
||
}
|
||
function shouldEncrypt(url) {
|
||
const pathname = absoluteUrl(url).pathname;
|
||
return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path));
|
||
}
|
||
function shouldAttachAuth(config) {
|
||
return !config.skipAuth;
|
||
}
|
||
function textEncoder() {
|
||
return new TextEncoder();
|
||
}
|
||
function textDecoder() {
|
||
return new TextDecoder();
|
||
}
|
||
function bytesToBase64(bytes) {
|
||
let binary = '';
|
||
bytes.forEach(byte => {
|
||
binary += String.fromCharCode(byte);
|
||
});
|
||
return btoa(binary);
|
||
}
|
||
function base64ToBytes(base64) {
|
||
const binary = atob(base64);
|
||
const bytes = new Uint8Array(binary.length);
|
||
for (let index = 0; index < binary.length; index += 1) {
|
||
bytes[index] = binary.charCodeAt(index);
|
||
}
|
||
return bytes;
|
||
}
|
||
async function getCryptoKey() {
|
||
if (!importedCryptoKeyPromise) {
|
||
importedCryptoKeyPromise = window.crypto.subtle.importKey('raw', textEncoder().encode(AES_KEY), {
|
||
name: 'AES-CBC'
|
||
}, false, ['encrypt', 'decrypt']);
|
||
}
|
||
return importedCryptoKeyPromise;
|
||
}
|
||
async function encryptPayload(plainText) {
|
||
const iv = window.crypto.getRandomValues(new Uint8Array(16));
|
||
const key = await getCryptoKey();
|
||
const encrypted = await window.crypto.subtle.encrypt({
|
||
name: 'AES-CBC',
|
||
iv
|
||
}, key, textEncoder().encode(plainText));
|
||
return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`;
|
||
}
|
||
async function decryptPayload(cipherText) {
|
||
const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2);
|
||
if (!ivBase64 || !encryptedBase64) {
|
||
throw new Error('Encrypted payload format is invalid');
|
||
}
|
||
const key = await getCryptoKey();
|
||
const decrypted = await window.crypto.subtle.decrypt({
|
||
name: 'AES-CBC',
|
||
iv: base64ToBytes(ivBase64)
|
||
}, key, base64ToBytes(encryptedBase64));
|
||
return textDecoder().decode(decrypted);
|
||
}
|
||
function normalizeBusinessResponse(payload) {
|
||
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
||
return payload;
|
||
}
|
||
return {
|
||
code: 0,
|
||
message: 'success',
|
||
data: payload
|
||
};
|
||
}
|
||
async function decodeResponsePayload(response) {
|
||
const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true';
|
||
if (encrypted && typeof response.data === 'string') {
|
||
const plainText = await decryptPayload(response.data);
|
||
response.data = normalizeBusinessResponse(JSON.parse(plainText));
|
||
return response;
|
||
}
|
||
response.data = normalizeBusinessResponse(response.data);
|
||
return response;
|
||
}
|
||
const client = axios__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.create({
|
||
withCredentials: false
|
||
});
|
||
client.interceptors.request.use(async config => {
|
||
const nextConfig = {
|
||
...config
|
||
};
|
||
const url = absoluteUrl(nextConfig.url || '').toString();
|
||
if (shouldAttachAuth(nextConfig)) {
|
||
const auth = getStoredAppAuth();
|
||
if (auth?.accessToken) {
|
||
nextConfig.headers = {
|
||
...(nextConfig.headers || {}),
|
||
Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}`
|
||
};
|
||
}
|
||
}
|
||
if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) {
|
||
const plainBody = JSON.stringify(nextConfig.data ?? {});
|
||
nextConfig.data = await encryptPayload(plainBody);
|
||
nextConfig.headers = {
|
||
...(nextConfig.headers || {}),
|
||
'Content-Type': 'text/plain;charset=UTF-8',
|
||
'X-Timestamp': `${Math.floor(Date.now() / 1000)}`
|
||
};
|
||
}
|
||
return nextConfig;
|
||
});
|
||
client.interceptors.response.use(async response => decodeResponsePayload(response));
|
||
async function refreshAccessToken() {
|
||
if (refreshPromise) {
|
||
return refreshPromise;
|
||
}
|
||
const auth = getStoredAppAuth();
|
||
if (!auth?.refreshToken) {
|
||
clearStoredAppAuth();
|
||
throw new Error('登录状态已失效,请重新登录');
|
||
}
|
||
refreshPromise = client.post(`${_config__WEBPACK_IMPORTED_MODULE_9__/* .appConfig */ .U.appServer}/auth/refreshToken`, {
|
||
refreshToken: auth.refreshToken
|
||
}, {
|
||
skipAuth: true
|
||
}).then(response => {
|
||
const payload = response.data || {};
|
||
if (Number(payload.code) !== 0 || !payload.data) {
|
||
if (Number(payload.code) === REFRESH_ERROR_CODE) {
|
||
clearStoredAppAuth();
|
||
}
|
||
throw new Error(payload.message || '刷新登录状态失败');
|
||
}
|
||
persistAppAuth(payload.data);
|
||
return payload.data;
|
||
}).finally(() => {
|
||
refreshPromise = null;
|
||
});
|
||
return refreshPromise;
|
||
}
|
||
async function request(config) {
|
||
const response = await client.request(config);
|
||
const payload = response.data || {};
|
||
if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) {
|
||
await refreshAccessToken();
|
||
return request({
|
||
...config,
|
||
_retriedAfterRefresh: true
|
||
});
|
||
}
|
||
return response;
|
||
}
|
||
async function appServerRequest(config) {
|
||
return request(config);
|
||
}
|
||
async function appServerGet(url, config = {}) {
|
||
return request({
|
||
...config,
|
||
method: 'get',
|
||
url
|
||
});
|
||
}
|
||
async function appServerPost(url, data = {}, config = {}) {
|
||
return request({
|
||
...config,
|
||
method: 'post',
|
||
url,
|
||
data
|
||
});
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4355:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ u: function() { return /* binding */ DocumentedHttpImClient; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5099);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2387);
|
||
/* harmony import */ var _appServerClient__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9311);
|
||
|
||
|
||
|
||
|
||
|
||
function inferAccountType(account) {
|
||
return String(account || '').includes('@') ? 2 : 1;
|
||
}
|
||
function unwrapData(response) {
|
||
return response.data?.data ?? response.data?.result ?? null;
|
||
}
|
||
function unwrapMessage(response, fallback) {
|
||
return response.data?.message || response.data?.msg || fallback;
|
||
}
|
||
class DocumentedHttpImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_2__/* .HttpImClient */ .Y {
|
||
unsupported(feature) {
|
||
throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`);
|
||
}
|
||
async loginWithPassword(account, password, type = inferAccountType(account)) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/login_pwd`, {
|
||
type,
|
||
number: account,
|
||
password,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
|
||
clientId: this.getClientId()
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '登录失败'));
|
||
}
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
|
||
return unwrapData(response);
|
||
}
|
||
async requestAuthCode(email) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/sendEmailCode`, {
|
||
email
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '验证码发送失败'));
|
||
}
|
||
return unwrapData(response);
|
||
}
|
||
async loginWithCode(account, code) {
|
||
void account;
|
||
void code;
|
||
throw new Error('接口文档未提供验证码登录接口,请使用密码登录');
|
||
}
|
||
async register({
|
||
type,
|
||
number,
|
||
code = '',
|
||
password,
|
||
invitationCode = ''
|
||
}) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.appServer}/auth/register`, {
|
||
type,
|
||
number,
|
||
code,
|
||
password,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform,
|
||
invitationCode
|
||
}, {
|
||
skipAuth: true
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '注册失败'));
|
||
}
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(unwrapData(response));
|
||
return unwrapData(response);
|
||
}
|
||
async createPcSession(userId = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/pc_session`, {
|
||
flag: 1,
|
||
device_name: 'Web IM',
|
||
userId,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.platform
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '二维码登录会话创建失败'));
|
||
}
|
||
return unwrapData(response) || {};
|
||
}
|
||
async loginWithPcSession(token) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.qrAppServer}/session_login/${encodeURIComponent(token)}`;
|
||
let response;
|
||
try {
|
||
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.post(url, null, {
|
||
withCredentials: false
|
||
});
|
||
} catch (postError) {
|
||
response = await axios__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.get(url, {
|
||
withCredentials: false
|
||
});
|
||
}
|
||
this.persistAppToken(url, response);
|
||
const payload = response.data || {};
|
||
const result = payload.result ?? payload.data ?? null;
|
||
if (Number(payload.code) === 0 && result) {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .persistAppAuth */ .eG)(result);
|
||
}
|
||
if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) {
|
||
return {
|
||
...payload,
|
||
data: result
|
||
};
|
||
}
|
||
throw new Error(payload.message || '扫码登录失败');
|
||
}
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.changePasswordApi, {
|
||
oldPassword,
|
||
newPassword
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '密码修改失败'));
|
||
}
|
||
return true;
|
||
}
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
void mobile;
|
||
void resetCode;
|
||
void newPassword;
|
||
throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程');
|
||
}
|
||
async logout() {
|
||
const auth = (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .getStoredAppAuth */ .Pd)();
|
||
if (!auth?.refreshToken) {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
|
||
return true;
|
||
}
|
||
try {
|
||
const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .appServerPost */ .Ln)(_config__WEBPACK_IMPORTED_MODULE_1__/* .appConfig */ .U.logoutApi, {
|
||
refreshToken: auth.refreshToken
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(unwrapMessage(response, '退出登录失败'));
|
||
}
|
||
} finally {
|
||
(0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__/* .clearStoredAppAuth */ .u$)();
|
||
}
|
||
return true;
|
||
}
|
||
async fetchRemoteConversations() {
|
||
return [];
|
||
}
|
||
async fetchRemoteMessages() {
|
||
return [];
|
||
}
|
||
async getServerContactList() {
|
||
return [];
|
||
}
|
||
async getProfile() {
|
||
return null;
|
||
}
|
||
async sendTextMessage() {
|
||
this.unsupported('发送消息');
|
||
}
|
||
async sendAttachmentMessage() {
|
||
this.unsupported('发送附件消息');
|
||
}
|
||
async addContact() {
|
||
this.unsupported('添加联系人');
|
||
}
|
||
async updateContactAlias() {
|
||
this.unsupported('联系人备注');
|
||
}
|
||
async createGroup() {
|
||
this.unsupported('创建群组');
|
||
}
|
||
async joinGroup() {
|
||
this.unsupported('加入群组');
|
||
}
|
||
async broadcastMessage() {
|
||
this.unsupported('群发消息');
|
||
}
|
||
async getGroupDetail() {
|
||
this.unsupported('群详情');
|
||
}
|
||
async getGroupMembers() {
|
||
this.unsupported('群成员');
|
||
}
|
||
async updateGroupAlias() {
|
||
this.unsupported('群备注');
|
||
}
|
||
async leaveGroup() {
|
||
this.unsupported('退出群组');
|
||
}
|
||
async dismissGroup() {
|
||
this.unsupported('解散群组');
|
||
}
|
||
async transferGroup() {
|
||
this.unsupported('转让群组');
|
||
}
|
||
async setGroupAdmins() {
|
||
this.unsupported('设置群管理员');
|
||
}
|
||
async updateGroupProfile() {
|
||
this.unsupported('更新群资料');
|
||
}
|
||
async kickGroupMembers() {
|
||
this.unsupported('移除群成员');
|
||
}
|
||
async updateGroupMuteSetting() {
|
||
this.unsupported('群禁言设置');
|
||
}
|
||
async updateProfile() {
|
||
this.unsupported('更新个人资料');
|
||
}
|
||
async recallMessage() {
|
||
this.unsupported('撤回消息');
|
||
}
|
||
async editMessage() {
|
||
this.unsupported('编辑消息');
|
||
}
|
||
async getMessageDetail() {
|
||
this.unsupported('消息详情');
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5099:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ Y: function() { return /* binding */ HttpImClient; }
|
||
/* harmony export */ });
|
||
/* unused harmony export imClient */
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3579);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5367);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2731);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(2387);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2169);
|
||
/* harmony import */ var _services_appServerClient__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(9311);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2';
|
||
const LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1';
|
||
const LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1';
|
||
function scopedStorageKey(baseKey, userId = '') {
|
||
const scope = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer || ''}:${userId || 'anonymous'}`;
|
||
return `${baseKey}:${encodeURIComponent(scope)}`;
|
||
}
|
||
function randomId() {
|
||
if (window.crypto && window.crypto.randomUUID) {
|
||
return window.crypto.randomUUID().replaceAll('-', '');
|
||
}
|
||
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
|
||
}
|
||
function readLocalMessages(userId) {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function readMessageSet(storageKey, userId) {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function writeMessageSet(storageKey, messagesByConversation, userId) {
|
||
localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation));
|
||
}
|
||
function messageKeys(message) {
|
||
return [message?.id, message?.messageUid].filter(Boolean).map(value => String(value));
|
||
}
|
||
function hasStoredMessage(storageKey, conversationId, message, userId) {
|
||
const stored = readMessageSet(storageKey, userId);
|
||
const ids = new Set(stored[conversationId] || []);
|
||
return messageKeys(message).some(id => ids.has(id));
|
||
}
|
||
function storeMessageKeys(storageKey, conversationId, messages, userId) {
|
||
const stored = readMessageSet(storageKey, userId);
|
||
const ids = new Set(stored[conversationId] || []);
|
||
messages.forEach(message => {
|
||
messageKeys(message).forEach(id => ids.add(id));
|
||
});
|
||
stored[conversationId] = Array.from(ids);
|
||
writeMessageSet(storageKey, stored, userId);
|
||
}
|
||
function withRecalledState(message) {
|
||
return {
|
||
...message,
|
||
status: 'recalled',
|
||
deliveryStatus: '',
|
||
recalled: true,
|
||
recallStatus: '已撤回'
|
||
};
|
||
}
|
||
function applyLocalMessageState(conversationId, messages, userId) {
|
||
return messages.filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)).map(message => {
|
||
const isRecalled = Boolean(message.recalled) || message.status === 'recalled' || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId);
|
||
if (!isRecalled) {
|
||
return message;
|
||
}
|
||
return withRecalledState(message);
|
||
});
|
||
}
|
||
function writeLocalMessages(messagesByConversation, userId) {
|
||
localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation));
|
||
}
|
||
function saveLocalMessage(message, userId) {
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || [];
|
||
const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id);
|
||
if (index >= 0) {
|
||
messagesByConversation[message.conversationId].splice(index, 1, message);
|
||
} else {
|
||
messagesByConversation[message.conversationId].push(message);
|
||
}
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
function mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) {
|
||
const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId);
|
||
const localByKey = new Map();
|
||
visibleLocalMessages.forEach(message => {
|
||
messageKeys(message).forEach(key => {
|
||
if (!localByKey.has(key)) {
|
||
localByKey.set(key, message);
|
||
}
|
||
});
|
||
});
|
||
const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => {
|
||
if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) {
|
||
return remoteMessage;
|
||
}
|
||
const localMessage = messageKeys(remoteMessage).map(key => localByKey.get(key)).find(message => message?.text && message.text !== '你撤回了一条消息');
|
||
return localMessage ? {
|
||
...remoteMessage,
|
||
text: localMessage.text
|
||
} : remoteMessage;
|
||
});
|
||
const remoteKeys = new Set();
|
||
visibleRemoteMessages.forEach(message => {
|
||
messageKeys(message).forEach(key => remoteKeys.add(key));
|
||
});
|
||
const now = Date.now();
|
||
function hasRemoteMatch(localMessage) {
|
||
if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) {
|
||
return true;
|
||
}
|
||
return visibleRemoteMessages.some(remoteMessage => {
|
||
return remoteMessage.direction === localMessage.direction && remoteMessage.text === localMessage.text && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000;
|
||
});
|
||
}
|
||
const pendingLocalMessages = visibleLocalMessages.filter(message => {
|
||
if (message.status === 'recalled' || message.recalled) {
|
||
return message.direction === 'out' && !hasRemoteMatch(message);
|
||
}
|
||
if (message.direction !== 'out') {
|
||
return false;
|
||
}
|
||
if (message.status === 'sent' && message.messageUid) {
|
||
return !hasRemoteMatch(message);
|
||
}
|
||
if (message.status === 'sent') {
|
||
return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000;
|
||
}
|
||
return message.status === 'sending' || message.status === 'failed';
|
||
});
|
||
return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => {
|
||
return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0);
|
||
});
|
||
}
|
||
function getTitle(value, fallback) {
|
||
return value || fallback || '';
|
||
}
|
||
function getUniqueEquipment(mobile, fallback) {
|
||
const allowedDevices = {
|
||
'18301902119': '67072d37062c4f31b1165073552933ba',
|
||
'18301902116': '1777479418113eeea8e236edce',
|
||
'18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',
|
||
'18301902117': 'd117f480faa64145b6162107b1b49617'
|
||
};
|
||
return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback;
|
||
}
|
||
function canUseLocalLoginFallback(response) {
|
||
const message = response.data?.message || '';
|
||
return false && 0;
|
||
}
|
||
class HttpImClient {
|
||
constructor() {
|
||
this.listeners = new Map();
|
||
this.connected = false;
|
||
this.currentUser = null;
|
||
}
|
||
getClientId() {
|
||
let clientId = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey);
|
||
if (!clientId) {
|
||
clientId = randomId();
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
|
||
}
|
||
return clientId;
|
||
}
|
||
restoreClientId(clientId) {
|
||
if (clientId) {
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.clientIdStorageKey, clientId);
|
||
}
|
||
}
|
||
getSdkVersion() {
|
||
return 'HTTP';
|
||
}
|
||
async ensureSdk() {
|
||
return true;
|
||
}
|
||
async loginWithPassword(mobile, password) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login_pwd`;
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
password,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: this.getClientId()
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
if (canUseLocalLoginFallback(response)) {
|
||
return {
|
||
userId: mobile,
|
||
token: `local-device-pending-${Date.now()}`,
|
||
displayName: mobile,
|
||
localOnly: true
|
||
};
|
||
}
|
||
throw new Error(response.data?.message || '登录失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async requestAuthCode(mobile) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/send_code`, {
|
||
mobile
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '验证码发送失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async loginWithCode(mobile, code) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/login`;
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
code,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: this.getClientId()
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '登录失败');
|
||
}
|
||
return response.data.result;
|
||
}
|
||
async createPcSession(userId = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(`${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/pc_session`, {
|
||
flag: 1,
|
||
device_name: 'Web IM',
|
||
userId,
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '二维码登录会话创建失败');
|
||
}
|
||
return response.data.result || {};
|
||
}
|
||
async loginWithPcSession(token) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/session_login/${encodeURIComponent(token)}`;
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, null, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
const data = response.data || {};
|
||
if ([0, 8, 9, 10, 18].includes(Number(data.code))) {
|
||
return data;
|
||
}
|
||
throw new Error(data.message || '扫码登录失败');
|
||
}
|
||
async registerWithPhone(mobile, code) {
|
||
const url = `${_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer}/register`;
|
||
const deviceId = getUniqueEquipment(mobile, this.getClientId());
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(url, {
|
||
mobile,
|
||
code,
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.platform,
|
||
clientId: deviceId,
|
||
uniqueEquipment: deviceId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
this.persistAppToken(url, response);
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '注册失败');
|
||
}
|
||
return response.data.result;
|
||
} catch (error) {
|
||
const status = error.response?.status;
|
||
if (status === 404 || status === 405) {
|
||
return this.loginWithCode(mobile, code);
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
connect(userId, token) {
|
||
this.currentUser = {
|
||
userId,
|
||
token
|
||
};
|
||
this.connected = true;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: true,
|
||
statusText: '已连接'
|
||
});
|
||
this.refreshConversationList();
|
||
}
|
||
disconnect() {
|
||
this.connected = false;
|
||
this.currentUser = null;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '未连接'
|
||
});
|
||
}
|
||
getConversationList() {
|
||
return [];
|
||
}
|
||
refreshConversationList() {
|
||
const conversations = this.getConversationList();
|
||
if (conversations.length) {
|
||
this.emit('conversationsChanged', conversations);
|
||
}
|
||
if (this.currentUser?.userId) {
|
||
this.fetchRemoteConversations().then(remoteConversations => {
|
||
this.emit('conversationsChanged', remoteConversations);
|
||
}).catch(() => {});
|
||
}
|
||
return conversations;
|
||
}
|
||
async fetchRemoteConversations(limit = 50) {
|
||
if (!this.currentUser?.userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
|
||
userId: this.currentUser.userId,
|
||
limit
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '会话同步失败');
|
||
}
|
||
return (response.data?.result?.conversations || []).map(conversation => ({
|
||
...conversation,
|
||
updatedAt: Number(conversation.updatedAt || Date.now()),
|
||
avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(),
|
||
raw: conversation.raw || {
|
||
type: 'single',
|
||
target: conversation.target,
|
||
line: 0
|
||
}
|
||
}));
|
||
}
|
||
getMessages(conversation) {
|
||
if (!conversation?.id) {
|
||
return [];
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId);
|
||
}
|
||
async fetchRemoteMessages(conversation, limit = 50, options = {}) {
|
||
if (!conversation?.id || !this.currentUser?.userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messagesApi, {
|
||
userId: this.currentUser.userId,
|
||
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
|
||
limit,
|
||
conversationType: conversation.type || conversation.raw?.type || 0,
|
||
markRead: Boolean(options.markRead),
|
||
includeConversations: Boolean(options.includeConversations)
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '消息同步失败');
|
||
}
|
||
const messages = (response.data?.result?.messages || []).map(message => ({
|
||
...message,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp,
|
||
conversationId: conversation.id
|
||
}));
|
||
messages.pinnedMessageUid = String(response.data?.result?.pinnedMessageUid || '');
|
||
if (options.includeConversations && Array.isArray(response.data?.result?.conversations)) {
|
||
const remoteConversations = response.data.result.conversations.map(remoteConversation => ({
|
||
...remoteConversation,
|
||
updatedAt: Number(remoteConversation.updatedAt || Date.now()),
|
||
avatarText: remoteConversation.avatarText || String(remoteConversation.title || remoteConversation.target || '?').slice(0, 1).toUpperCase(),
|
||
raw: remoteConversation.raw || {
|
||
type: 'single',
|
||
target: remoteConversation.target,
|
||
line: 0
|
||
}
|
||
}));
|
||
this.emit('conversationsChanged', remoteConversations);
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);
|
||
messagesByConversation[conversation.id].pinnedMessageUid = messages.pinnedMessageUid;
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
return messagesByConversation[conversation.id];
|
||
}
|
||
async setPinnedMessage(conversation, messageUid = '') {
|
||
const action = messageUid ? 'pin' : 'unpin';
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
|
||
action,
|
||
userId: this.currentUser?.userId || '',
|
||
messageUid: messageUid || '1',
|
||
target: conversation.target || conversation.raw?.target || '',
|
||
conversationType: ['group', 'channel'].includes(conversation.type) ? 'group' : 'single'
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) throw new Error(response.data?.message || '置顶失败');
|
||
}
|
||
hideMessages(conversation, messages) {
|
||
const items = Array.isArray(messages) ? messages : [messages];
|
||
if (!conversation?.id || !items.length) {
|
||
return;
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
markMessagesRecalled(conversation, messages) {
|
||
const items = Array.isArray(messages) ? messages : [messages];
|
||
if (!conversation?.id || !items.length) {
|
||
return;
|
||
}
|
||
const userId = this.currentUser?.userId || '';
|
||
storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId);
|
||
const messagesByConversation = readLocalMessages(userId);
|
||
messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);
|
||
writeLocalMessages(messagesByConversation, userId);
|
||
}
|
||
async recallMessage(conversation, message) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!/^\d+$/.test(messageUid)) {
|
||
throw new Error('缺少可撤回的消息ID');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
|
||
action: 'recall',
|
||
userId: this.currentUser?.userId || message.from || '',
|
||
messageUid
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '撤回失败');
|
||
}
|
||
this.markMessagesRecalled(conversation, [message]);
|
||
return response.data.result;
|
||
}
|
||
async editMessage(conversation, message, text) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!/^\d+$/.test(messageUid)) {
|
||
throw new Error('缺少可编辑的消息ID');
|
||
}
|
||
const nextText = String(text || '').trim();
|
||
if (!nextText) {
|
||
throw new Error('编辑内容不能为空');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageActionApi, {
|
||
action: 'edit',
|
||
userId: this.currentUser?.userId || message.from || '',
|
||
messageUid,
|
||
text: nextText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '编辑失败');
|
||
}
|
||
const result = response.data?.result?.message || {};
|
||
const editedMessage = {
|
||
...message,
|
||
text: result.text || nextText,
|
||
status: 'delivered',
|
||
deliveryStatus: 'delivered',
|
||
editedAt: Number(result.editedAt || Date.now()),
|
||
activityTimestamp: Number(result.editedAt || Date.now())
|
||
};
|
||
saveLocalMessage(editedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', editedMessage);
|
||
return editedMessage;
|
||
}
|
||
async getMessageDetail(conversation, message) {
|
||
const messageUid = String(message?.messageUid || message?.id || '').trim();
|
||
if (!messageUid) {
|
||
throw new Error('缺少消息ID');
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.messageDetailApi, {
|
||
userId: this.currentUser?.userId || '',
|
||
target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '',
|
||
conversationType: conversation?.type || conversation?.raw?.type || 'single',
|
||
messageUid
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '消息详情加载失败');
|
||
}
|
||
return response.data?.result?.detail || null;
|
||
}
|
||
async sendTextMessage(conversation, text, initialMessage = null) {
|
||
const senderRole = conversation?.role || conversation?.raw?.role || '';
|
||
const message = initialMessage || {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: this.currentUser?.userId || 'me',
|
||
senderRole,
|
||
direction: 'out',
|
||
type: 'text',
|
||
text,
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now()
|
||
};
|
||
saveLocalMessage(message, this.currentUser?.userId || '');
|
||
if (!initialMessage) {
|
||
this.emit('messageSent', message);
|
||
}
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, {
|
||
sender: this.currentUser?.userId || '',
|
||
target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),
|
||
conversationType: conversation.type || conversation.raw?.type || 0,
|
||
text
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '发送失败');
|
||
}
|
||
const sentMessage = {
|
||
...message,
|
||
status: 'sent',
|
||
deliveryStatus: 'sent',
|
||
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
|
||
senderRole: response.data?.result?.senderRole || message.senderRole || '',
|
||
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
|
||
timestamp: message.timestamp,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp
|
||
};
|
||
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', sentMessage);
|
||
return sentMessage;
|
||
} catch (error) {
|
||
const failedMessage = {
|
||
...message,
|
||
status: 'failed',
|
||
deliveryStatus: '',
|
||
error: error.response?.data?.message || error.message || '发送失败'
|
||
};
|
||
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', failedMessage);
|
||
return failedMessage;
|
||
}
|
||
}
|
||
async sendAttachmentMessage(conversation, {
|
||
type,
|
||
file,
|
||
text = ''
|
||
}, initialMessage = null) {
|
||
const senderRole = conversation?.role || conversation?.raw?.role || '';
|
||
const message = initialMessage || {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: this.currentUser?.userId || 'me',
|
||
senderRole,
|
||
direction: 'out',
|
||
type,
|
||
text,
|
||
attachment: {
|
||
type,
|
||
name: file?.name || (type === 'image' ? '图片' : '文件'),
|
||
mime: file?.type || '',
|
||
size: file?.size || 0,
|
||
url: type === 'image' && file ? URL.createObjectURL(file) : ''
|
||
},
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now()
|
||
};
|
||
saveLocalMessage(message, this.currentUser?.userId || '');
|
||
if (!initialMessage) {
|
||
this.emit('messageSent', message);
|
||
}
|
||
try {
|
||
const formData = new FormData();
|
||
formData.append('sender', this.currentUser?.userId || '');
|
||
formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''));
|
||
formData.append('conversationType', conversation.type || conversation.raw?.type || 0);
|
||
formData.append('messageType', type);
|
||
formData.append('text', text || '');
|
||
formData.append('attachment', file);
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.sendMessageApi, formData, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '发送失败');
|
||
}
|
||
const sentMessage = {
|
||
...message,
|
||
status: 'sent',
|
||
deliveryStatus: 'sent',
|
||
messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',
|
||
senderRole: response.data?.result?.senderRole || message.senderRole || '',
|
||
attachment: response.data?.result?.attachment || message.attachment,
|
||
serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,
|
||
timestamp: message.timestamp,
|
||
displayTimestamp: message.displayTimestamp || message.timestamp
|
||
};
|
||
saveLocalMessage(sentMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', sentMessage);
|
||
return sentMessage;
|
||
} catch (error) {
|
||
const failedMessage = {
|
||
...message,
|
||
status: 'failed',
|
||
deliveryStatus: '',
|
||
error: error.response?.data?.message || error.message || '发送失败'
|
||
};
|
||
saveLocalMessage(failedMessage, this.currentUser?.userId || '');
|
||
this.emit('messageStatusChanged', failedMessage);
|
||
return failedMessage;
|
||
}
|
||
}
|
||
getContactList() {
|
||
return [];
|
||
}
|
||
async getServerContactList(userId) {
|
||
if (!userId) {
|
||
return [];
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi, {
|
||
userId
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.contactsApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '联系人加载失败');
|
||
}
|
||
return (response.data?.result?.contacts || []).map(item => {
|
||
return this.mapContact(item.uid, {
|
||
alias: item.alias
|
||
}, {
|
||
uid: item.uid,
|
||
displayName: item.displayName,
|
||
name: item.name,
|
||
mobile: item.mobile,
|
||
portrait: item.portrait,
|
||
address: item.address,
|
||
friendAlias: item.alias
|
||
});
|
||
}).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
|
||
}
|
||
async addContact(userId, keyword, reason = '') {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.addContactApi, {
|
||
userId,
|
||
keyword,
|
||
reason
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '添加联系人失败');
|
||
}
|
||
const item = response.data?.result?.contact;
|
||
if (!item?.uid) {
|
||
return null;
|
||
}
|
||
return this.mapContact(item.uid, {
|
||
alias: item.alias
|
||
}, {
|
||
uid: item.uid,
|
||
displayName: item.displayName,
|
||
name: item.name,
|
||
mobile: item.mobile,
|
||
portrait: item.portrait,
|
||
address: item.address,
|
||
friendAlias: item.alias
|
||
});
|
||
}
|
||
normalizeConversation(conversation) {
|
||
const title = getTitle(conversation?.title, conversation?.target || '');
|
||
return {
|
||
...conversation,
|
||
id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`,
|
||
target: conversation?.target || conversation?.raw?.target || '',
|
||
title,
|
||
subtitle: conversation?.subtitle || '',
|
||
unread: Number(conversation?.unread || 0),
|
||
portrait: conversation?.portrait || '',
|
||
avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(),
|
||
updatedAt: Number(conversation?.updatedAt || Date.now()),
|
||
raw: conversation?.raw || {
|
||
type: conversation?.type === 'single' ? 'single' : 'group',
|
||
target: conversation?.target || '',
|
||
line: 0
|
||
}
|
||
};
|
||
}
|
||
async createGroup(userId, {
|
||
name,
|
||
memberIds = [],
|
||
announcement = '',
|
||
welcomeText = '',
|
||
channel = false
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: channel ? 'create_channel' : 'create_group',
|
||
userId,
|
||
name,
|
||
memberIds,
|
||
announcement,
|
||
welcomeText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败'));
|
||
}
|
||
return this.normalizeConversation(response.data?.result?.conversation || {});
|
||
}
|
||
async joinGroup(userId, groupKey) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'join_group',
|
||
userId,
|
||
groupKey
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '加入群组失败');
|
||
}
|
||
return this.normalizeConversation(response.data?.result?.conversation || {});
|
||
}
|
||
async broadcastMessage(userId, targetIds, text) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'broadcast',
|
||
userId,
|
||
targetIds,
|
||
text
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群发失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async getGroupDetail(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'group_detail',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群资料加载失败');
|
||
}
|
||
return response.data?.result?.group || null;
|
||
}
|
||
async getGroupMembers(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'group_members',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群员加载失败');
|
||
}
|
||
return response.data?.result?.members || [];
|
||
}
|
||
async updateGroupAlias(userId, groupId, alias) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_group_alias',
|
||
userId,
|
||
groupId,
|
||
alias
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '本群昵称保存失败');
|
||
}
|
||
return response.data?.result?.alias || '';
|
||
}
|
||
async leaveGroup(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'leave_group',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '退出群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async dismissGroup(userId, groupId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'dismiss_group',
|
||
userId,
|
||
groupId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '解散群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async transferGroup(userId, groupId, targetUserId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'transfer_group',
|
||
userId,
|
||
groupId,
|
||
targetUserId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '转让群组失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async setGroupAdmins(userId, groupId, adminIds) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'set_group_admins',
|
||
userId,
|
||
groupId,
|
||
adminIds
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '管理员设置失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async updateGroupProfile(userId, groupId, {
|
||
name,
|
||
announcement,
|
||
welcomeText
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_group_profile',
|
||
userId,
|
||
groupId,
|
||
name,
|
||
announcement,
|
||
welcomeText
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '群资料保存失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async kickGroupMembers(userId, groupId, targetIds) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'kick_group_members',
|
||
userId,
|
||
groupId,
|
||
targetIds
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '踢人失败');
|
||
}
|
||
return response.data?.result || {};
|
||
}
|
||
async updateGroupMuteSetting(userId, groupId, setting) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.conversationActionsApi, {
|
||
action: 'update_mute_setting',
|
||
userId,
|
||
groupId,
|
||
...setting
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '禁言设置保存失败');
|
||
}
|
||
return response.data?.result?.muteSetting || null;
|
||
}
|
||
async updateContactAlias(userId, targetId, alias) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi, {
|
||
userId,
|
||
targetId,
|
||
alias
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.updateAliasApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '备注名修改失败');
|
||
}
|
||
return response.data?.result?.contact?.alias || '';
|
||
}
|
||
async getProfile(userId) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, {
|
||
action: 'get',
|
||
userId
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '用户资料加载失败');
|
||
}
|
||
return response.data?.result?.profile || null;
|
||
}
|
||
async updateProfile(userId, {
|
||
displayName,
|
||
portraitFile
|
||
}) {
|
||
const formData = new FormData();
|
||
formData.append('action', 'update');
|
||
formData.append('userId', userId);
|
||
formData.append('displayName', displayName);
|
||
if (portraitFile) {
|
||
formData.append('portraitFile', portraitFile);
|
||
}
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.profileApi, formData, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.appServer)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || '用户资料保存失败');
|
||
}
|
||
return response.data?.result?.profile || null;
|
||
}
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi, {
|
||
oldPassword,
|
||
newPassword
|
||
}, {
|
||
withCredentials: false,
|
||
headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.changePasswordApi)
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || response.data?.msg || '密码修改失败');
|
||
}
|
||
return true;
|
||
}
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_17__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.resetPasswordApi, {
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}, {
|
||
withCredentials: false
|
||
});
|
||
if (response.data?.code !== 0) {
|
||
throw new Error(response.data?.message || response.data?.msg || '密码设置失败');
|
||
}
|
||
return true;
|
||
}
|
||
refreshContactList() {
|
||
const contacts = this.getContactList();
|
||
this.emit('contactsChanged', contacts);
|
||
return contacts;
|
||
}
|
||
createSingleConversation(userId, userInfo = null) {
|
||
const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId);
|
||
return {
|
||
id: `single-${userId}`,
|
||
type: 'single',
|
||
target: userId,
|
||
title,
|
||
subtitle: '',
|
||
unread: 0,
|
||
portrait: userInfo?.portrait || '',
|
||
avatarText: title.slice(0, 1).toUpperCase(),
|
||
updatedAt: Date.now(),
|
||
raw: {
|
||
type: 'single',
|
||
target: userId,
|
||
line: 0
|
||
}
|
||
};
|
||
}
|
||
mapContact(userId, friend, userInfo) {
|
||
const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId);
|
||
return {
|
||
id: userId,
|
||
uid: userId,
|
||
title,
|
||
subtitle: userInfo?.mobile || userInfo?.name || userId,
|
||
portrait: userInfo?.portrait || '',
|
||
address: userInfo?.address || '',
|
||
avatarText: title.slice(0, 1).toUpperCase(),
|
||
alias: friend?.alias || userInfo?.friendAlias || '',
|
||
rawFriend: friend,
|
||
rawUser: userInfo
|
||
};
|
||
}
|
||
on(eventName, handler) {
|
||
if (!this.listeners.has(eventName)) {
|
||
this.listeners.set(eventName, new Set());
|
||
}
|
||
this.listeners.get(eventName).add(handler);
|
||
return () => this.off(eventName, handler);
|
||
}
|
||
off(eventName, handler) {
|
||
this.listeners.get(eventName)?.delete(handler);
|
||
}
|
||
emit(eventName, payload) {
|
||
this.listeners.get(eventName)?.forEach(handler => handler(payload));
|
||
}
|
||
persistAppToken(url, response) {
|
||
const appToken = response.headers?.authtoken || response.headers?.authToken;
|
||
if (appToken) {
|
||
localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + this.getUrlHost(url), appToken);
|
||
}
|
||
}
|
||
getAppAuthHeaders(url) {
|
||
const host = this.getUrlHost(url);
|
||
if (!host) {
|
||
return {};
|
||
}
|
||
const token = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__/* .appConfig */ .U.authTokenStoragePrefix + host);
|
||
return token ? {
|
||
authToken: token
|
||
} : {};
|
||
}
|
||
getUrlHost(url) {
|
||
try {
|
||
return new URL(url, window.location.origin).host;
|
||
} catch (error) {
|
||
return '';
|
||
}
|
||
}
|
||
}
|
||
const imClient = new HttpImClient();
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5051:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* unused harmony export WildfireImClient */
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5099);
|
||
/* harmony import */ var _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3909);
|
||
/* harmony import */ var _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4355);
|
||
|
||
|
||
|
||
|
||
class UnsupportedWildfireImClient {
|
||
constructor() {
|
||
throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK');
|
||
}
|
||
}
|
||
const imClient = _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'wildfire' ? new UnsupportedWildfireImClient() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'custom-ws' || _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'long' ? new _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__/* .LongConnectionImClient */ .E() : _config__WEBPACK_IMPORTED_MODULE_0__/* .appConfig */ .U.sdkMode === 'legacy-http' ? new _httpImClient__WEBPACK_IMPORTED_MODULE_1__/* .HttpImClient */ .Y() : new _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__/* .DocumentedHttpImClient */ .u();
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "wD", 0, /* binding */ imClient
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3909:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ E: function() { return /* binding */ LongConnectionImClient; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2169);
|
||
/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5099);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const HEARTBEAT_INTERVAL_MS = 25000;
|
||
const RECONNECT_MIN_MS = 1000;
|
||
const RECONNECT_MAX_MS = 15000;
|
||
function buildWsUrl() {
|
||
if (_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl) {
|
||
return _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsUrl;
|
||
}
|
||
const protocol = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.useWss ? 'wss' : 'ws';
|
||
const host = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imServerHost || window.location.hostname;
|
||
const port = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort ? `:${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.imRoutePort}` : '';
|
||
const path = _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath?.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath : `/${_config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.wsPath || 'ws'}`;
|
||
return `${protocol}://${host}${port}${path}`;
|
||
}
|
||
function normalizeConversationId(payload) {
|
||
const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender;
|
||
return payload.conversationId || (target ? `single-${target}` : '');
|
||
}
|
||
function normalizeIncomingMessage(payload, currentUserId) {
|
||
const item = payload.message || payload;
|
||
const from = item.from || item.sender || item.fromUser || '';
|
||
const target = item.target || item.to || item.receiver || '';
|
||
const direction = from && String(from) === String(currentUserId) ? 'out' : 'in';
|
||
const conversationId = item.conversationId || normalizeConversationId({
|
||
...item,
|
||
target: direction === 'out' ? target : from
|
||
});
|
||
if (!conversationId) {
|
||
return null;
|
||
}
|
||
const status = item.status || item.deliveryStatus || 'sent';
|
||
return {
|
||
id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`,
|
||
messageUid: item.messageUid || item.uid || item.messageId || '',
|
||
conversationId,
|
||
from,
|
||
target,
|
||
direction,
|
||
type: item.type || 'text',
|
||
text: item.text || item.content || item.searchableContent || '',
|
||
status,
|
||
deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''),
|
||
timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()),
|
||
displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()),
|
||
raw: item
|
||
};
|
||
}
|
||
class LongConnectionImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_5__/* .HttpImClient */ .Y {
|
||
constructor() {
|
||
super();
|
||
this.socket = null;
|
||
this.wsUrl = buildWsUrl();
|
||
this.heartbeatTimer = null;
|
||
this.reconnectTimer = null;
|
||
this.reconnectAttempts = 0;
|
||
this.manualClose = false;
|
||
}
|
||
getSdkVersion() {
|
||
return 'JC-LC/0.1';
|
||
}
|
||
shouldUseMessagePolling() {
|
||
return !this.connected;
|
||
}
|
||
async ensureSdk() {
|
||
if (typeof WebSocket === 'undefined') {
|
||
throw new Error('当前浏览器不支持 WebSocket 长连接');
|
||
}
|
||
return true;
|
||
}
|
||
connect(userId, token) {
|
||
this.currentUser = {
|
||
userId,
|
||
token
|
||
};
|
||
this.manualClose = false;
|
||
this.openSocket();
|
||
}
|
||
disconnect() {
|
||
this.manualClose = true;
|
||
this.clearReconnectTimer();
|
||
this.clearHeartbeatTimer();
|
||
if (this.socket) {
|
||
this.socket.close();
|
||
this.socket = null;
|
||
}
|
||
super.disconnect();
|
||
}
|
||
openSocket() {
|
||
if (this.socket?.readyState === WebSocket.OPEN) {
|
||
this.sendAuthFrame();
|
||
return;
|
||
}
|
||
if (this.socket?.readyState === WebSocket.CONNECTING) {
|
||
return;
|
||
}
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接连接中'
|
||
});
|
||
try {
|
||
this.socket = new WebSocket(this.wsUrl);
|
||
this.socket.binaryType = 'arraybuffer';
|
||
} catch (error) {
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接创建失败,使用HTTP补偿'
|
||
});
|
||
this.scheduleReconnect();
|
||
return;
|
||
}
|
||
this.socket.onopen = () => {
|
||
this.connected = true;
|
||
this.reconnectAttempts = 0;
|
||
this.emit('connectionStatusChanged', {
|
||
connected: true,
|
||
statusText: '长连接已连接'
|
||
});
|
||
this.sendAuthFrame();
|
||
this.startHeartbeat();
|
||
this.refreshConversationList();
|
||
};
|
||
this.socket.onmessage = event => {
|
||
this.handleFrame(event.data);
|
||
};
|
||
this.socket.onerror = () => {
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接异常,使用HTTP补偿'
|
||
});
|
||
};
|
||
this.socket.onclose = () => {
|
||
this.connected = false;
|
||
this.clearHeartbeatTimer();
|
||
this.socket = null;
|
||
if (this.manualClose) {
|
||
return;
|
||
}
|
||
this.emit('connectionStatusChanged', {
|
||
connected: false,
|
||
statusText: '长连接重连中'
|
||
});
|
||
this.scheduleReconnect();
|
||
};
|
||
}
|
||
sendAuthFrame() {
|
||
this.sendFrame({
|
||
type: 'auth',
|
||
userId: this.currentUser?.userId || '',
|
||
token: this.currentUser?.token || '',
|
||
clientId: this.getClientId(),
|
||
platform: _config__WEBPACK_IMPORTED_MODULE_4__/* .appConfig */ .U.platform,
|
||
timestamp: Date.now()
|
||
});
|
||
}
|
||
sendFrame(frame) {
|
||
if (this.socket?.readyState !== WebSocket.OPEN) {
|
||
return false;
|
||
}
|
||
this.socket.send(JSON.stringify(frame));
|
||
return true;
|
||
}
|
||
handleFrame(rawData) {
|
||
if (rawData instanceof ArrayBuffer) {
|
||
this.emit('rawFrameReceived', rawData);
|
||
return;
|
||
}
|
||
let payload;
|
||
try {
|
||
payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
|
||
} catch (error) {
|
||
return;
|
||
}
|
||
const type = payload.type || payload.event || payload.cmd || '';
|
||
if (type === 'pong' || type === 'auth_ok' || type === 'connected') {
|
||
return;
|
||
}
|
||
if (type === 'contactsChanged') {
|
||
this.emit('contactsChanged', payload.contacts || []);
|
||
return;
|
||
}
|
||
if (type === 'conversationsChanged') {
|
||
this.emit('conversationsChanged', payload.conversations || []);
|
||
return;
|
||
}
|
||
if (type === 'messages' && Array.isArray(payload.messages)) {
|
||
payload.messages.map(message => normalizeIncomingMessage(message, this.currentUser?.userId)).filter(Boolean).forEach(message => this.emit('messageReceived', message));
|
||
return;
|
||
}
|
||
const message = normalizeIncomingMessage(payload, this.currentUser?.userId);
|
||
if (message) {
|
||
this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message);
|
||
}
|
||
}
|
||
startHeartbeat() {
|
||
this.clearHeartbeatTimer();
|
||
this.heartbeatTimer = window.setInterval(() => {
|
||
this.sendFrame({
|
||
type: 'ping',
|
||
timestamp: Date.now()
|
||
});
|
||
}, HEARTBEAT_INTERVAL_MS);
|
||
}
|
||
clearHeartbeatTimer() {
|
||
if (this.heartbeatTimer) {
|
||
window.clearInterval(this.heartbeatTimer);
|
||
this.heartbeatTimer = null;
|
||
}
|
||
}
|
||
scheduleReconnect() {
|
||
this.clearReconnectTimer();
|
||
const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts);
|
||
this.reconnectAttempts += 1;
|
||
this.reconnectTimer = window.setTimeout(() => {
|
||
this.openSocket();
|
||
}, delay);
|
||
}
|
||
clearReconnectTimer() {
|
||
if (this.reconnectTimer) {
|
||
window.clearTimeout(this.reconnectTimer);
|
||
this.reconnectTimer = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 446:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ B: function() { return /* binding */ imageDisplayUrl; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
function configuredProxyHosts() {
|
||
const configured = window.JC_WEB_IM_CONFIG?.mediaProxyHosts;
|
||
const values = Array.isArray(configured) ? configured : String(configured || '').split(/[\s,]+/);
|
||
return new Set(['zhiyanim.dfpnm.cn', ...values].map(value => String(value || '').trim().toLowerCase().replace(/\.$/, '')).filter(Boolean));
|
||
}
|
||
function imageDisplayUrl(value) {
|
||
const source = String(value || '').trim();
|
||
if (!source || source.startsWith('blob:') || source.startsWith('data:')) {
|
||
return source;
|
||
}
|
||
try {
|
||
const url = new URL(source, window.location.origin);
|
||
if (url.protocol !== 'https:' || !configuredProxyHosts().has(url.hostname.toLowerCase())) {
|
||
return source;
|
||
}
|
||
const proxyUrl = new URL('/api/media_proxy.php', window.location.origin);
|
||
proxyUrl.searchParams.set('url', url.toString());
|
||
return proxyUrl.toString();
|
||
} catch (error) {
|
||
return source;
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9687:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2387);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2169);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5051);
|
||
|
||
|
||
|
||
|
||
class RealtimeNotificationClient {
|
||
constructor() {
|
||
this.source = null;
|
||
this.userId = '';
|
||
this.handler = null;
|
||
this.reconnectTimer = null;
|
||
this.reconnectAttempt = 0;
|
||
this.generation = 0;
|
||
}
|
||
isConnected() {
|
||
return this.source?.readyState === WebSocket.OPEN;
|
||
}
|
||
start(userId, handler) {
|
||
this.stop();
|
||
if (!_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseEnabled || !userId || typeof window.WebSocket !== 'function') return;
|
||
this.userId = userId;
|
||
this.handler = handler;
|
||
this.generation += 1;
|
||
this.open(this.generation);
|
||
}
|
||
stop() {
|
||
this.generation += 1;
|
||
window.clearTimeout(this.reconnectTimer);
|
||
this.reconnectTimer = null;
|
||
if (this.source) this.source.close();
|
||
this.source = null;
|
||
this.userId = '';
|
||
this.handler = null;
|
||
this.reconnectAttempt = 0;
|
||
}
|
||
async open(generation) {
|
||
try {
|
||
const response = await axios__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.post(_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseTicketApi, {
|
||
userId: this.userId
|
||
}, {
|
||
withCredentials: false,
|
||
headers: _services_imClient__WEBPACK_IMPORTED_MODULE_3__/* .imClient */ .wD.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.appServer)
|
||
});
|
||
if (generation !== this.generation) return;
|
||
if (response.data?.code !== 0) throw new Error(response.data?.message || '实时通知凭证申请失败');
|
||
const ticket = response.data?.result?.ticket || '';
|
||
if (!ticket) throw new Error('实时通知凭证为空');
|
||
const separator = _config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseUrl.includes('?') ? '&' : '?';
|
||
const endpoint = `${_config__WEBPACK_IMPORTED_MODULE_2__/* .appConfig */ .U.sseUrl}${separator}ticket=${encodeURIComponent(ticket)}`;
|
||
const socketUrl = endpoint.startsWith('ws://') || endpoint.startsWith('wss://') ? endpoint : `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
|
||
const source = new WebSocket(socketUrl);
|
||
this.source = source;
|
||
source.onopen = () => {
|
||
this.reconnectAttempt = 0;
|
||
};
|
||
source.onmessage = event => {
|
||
if (generation !== this.generation) return;
|
||
let payload = {};
|
||
try {
|
||
payload = JSON.parse(event.data || '{}');
|
||
} catch (error) {
|
||
payload = {};
|
||
}
|
||
if (payload.type !== 'message-notification') return;
|
||
this.handler?.(payload);
|
||
};
|
||
source.onerror = () => {
|
||
if (generation !== this.generation) return;
|
||
source.close();
|
||
if (this.source === source) this.source = null;
|
||
this.scheduleReconnect(generation);
|
||
};
|
||
source.onclose = () => {
|
||
if (generation !== this.generation || this.source !== source) return;
|
||
this.source = null;
|
||
this.scheduleReconnect(generation);
|
||
};
|
||
} catch (error) {
|
||
if (generation === this.generation) this.scheduleReconnect(generation);
|
||
}
|
||
}
|
||
scheduleReconnect(generation) {
|
||
window.clearTimeout(this.reconnectTimer);
|
||
const delay = Math.min(30000, 1000 * 2 ** Math.min(this.reconnectAttempt, 5));
|
||
this.reconnectAttempt += 1;
|
||
this.reconnectTimer = window.setTimeout(() => this.open(generation), delay);
|
||
}
|
||
}
|
||
const realtimeNotifications = new RealtimeNotificationClient();
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "w", 0, /* binding */ realtimeNotifications
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9045:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5367);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2731);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2261);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5051);
|
||
/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(7566);
|
||
/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(1414);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(926);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const CONTACT_CACHE_MS = 15000;
|
||
function normalizeContacts(contacts) {
|
||
const unique = new Map();
|
||
contacts.forEach(contact => {
|
||
const uid = String(contact.uid || contact.id || '').trim();
|
||
if (!uid) {
|
||
return;
|
||
}
|
||
const normalized = {
|
||
...contact,
|
||
id: String(contact.id || uid),
|
||
uid
|
||
};
|
||
unique.set(uid, {
|
||
...(unique.get(uid) || {}),
|
||
...normalized
|
||
});
|
||
});
|
||
return Array.from(unique.values()).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
|
||
}
|
||
const useContactStore = (0,pinia__WEBPACK_IMPORTED_MODULE_6__/* .defineStore */ .nY)('contacts', {
|
||
state: () => ({
|
||
contacts: [],
|
||
activeId: '',
|
||
loading: false,
|
||
eventsBound: false,
|
||
refreshSerial: 0,
|
||
refreshPromise: null,
|
||
loadedForUserId: '',
|
||
loadedAt: 0,
|
||
actionError: '',
|
||
actionInfo: ''
|
||
}),
|
||
getters: {
|
||
activeContact(state) {
|
||
return state.contacts.find(item => item.id === state.activeId) || state.contacts[0] || null;
|
||
}
|
||
},
|
||
actions: {
|
||
bindImEvents() {
|
||
if (this.eventsBound) {
|
||
return;
|
||
}
|
||
this.eventsBound = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.on('contactsChanged', contacts => {
|
||
if (!contacts.length && this.contacts.length) {
|
||
return;
|
||
}
|
||
this.contacts = normalizeContacts(contacts);
|
||
if (!this.contacts.find(item => item.id === this.activeId)) {
|
||
this.activeId = this.contacts[0]?.id || '';
|
||
}
|
||
});
|
||
},
|
||
async refreshContacts(options = {}) {
|
||
this.bindImEvents();
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
|
||
const requestUserId = session.userId;
|
||
const force = Boolean(options.force);
|
||
if (!requestUserId) {
|
||
this.clearContacts();
|
||
return [];
|
||
}
|
||
if (!force && this.contacts.length && this.loadedForUserId === requestUserId && Date.now() - this.loadedAt < CONTACT_CACHE_MS) {
|
||
return this.contacts;
|
||
}
|
||
if (this.refreshPromise && !force) {
|
||
return this.refreshPromise;
|
||
}
|
||
const serial = this.refreshSerial + 1;
|
||
this.refreshSerial = serial;
|
||
this.loading = true;
|
||
this.refreshPromise = (async () => {
|
||
this.contacts = normalizeContacts(_services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.refreshContactList());
|
||
if (!this.contacts.find(item => item.id === this.activeId)) {
|
||
this.activeId = this.contacts[0]?.id || '';
|
||
}
|
||
if (!this.contacts.length || force) {
|
||
const serverContacts = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.getServerContactList(requestUserId);
|
||
if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)().userId !== requestUserId) {
|
||
return this.contacts;
|
||
}
|
||
this.contacts = normalizeContacts(serverContacts);
|
||
this.loadedForUserId = requestUserId;
|
||
this.loadedAt = Date.now();
|
||
if (!this.contacts.find(item => item.id === this.activeId)) {
|
||
this.activeId = this.contacts[0]?.id || '';
|
||
}
|
||
}
|
||
window.setTimeout(() => {
|
||
if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)().userId !== requestUserId) {
|
||
return;
|
||
}
|
||
const latest = _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.getContactList(false);
|
||
if (latest.length || !this.contacts.length) {
|
||
this.contacts = normalizeContacts(latest);
|
||
this.loadedForUserId = requestUserId;
|
||
this.loadedAt = Date.now();
|
||
if (!this.contacts.find(item => item.id === this.activeId)) {
|
||
this.activeId = this.contacts[0]?.id || '';
|
||
}
|
||
}
|
||
}, 1200);
|
||
return this.contacts;
|
||
})();
|
||
try {
|
||
return await this.refreshPromise;
|
||
} finally {
|
||
if (serial === this.refreshSerial) {
|
||
this.loading = false;
|
||
this.refreshPromise = null;
|
||
}
|
||
}
|
||
},
|
||
async addContact(keyword) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
|
||
const value = String(keyword || '').trim();
|
||
this.actionError = '';
|
||
this.actionInfo = '';
|
||
if (!session.userId) {
|
||
this.actionError = '请先登录';
|
||
return false;
|
||
}
|
||
if (!value) {
|
||
this.actionError = '请输入用户ID、手机号或用户名';
|
||
return false;
|
||
}
|
||
this.loading = true;
|
||
try {
|
||
const contact = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.addContact(session.userId, value, '添加联系人');
|
||
if (contact) {
|
||
this.contacts = normalizeContacts([...this.contacts, contact]);
|
||
this.activeId = contact.id;
|
||
}
|
||
this.actionInfo = '联系人已添加';
|
||
await this.refreshContacts({
|
||
force: true
|
||
});
|
||
return true;
|
||
} catch (error) {
|
||
this.actionError = error.message || '添加联系人失败';
|
||
return false;
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
async updateContactAlias(contactId, alias) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__/* .useSessionStore */ .B)();
|
||
const targetId = String(contactId || '').trim();
|
||
const nextAlias = String(alias || '').trim();
|
||
this.actionError = '';
|
||
this.actionInfo = '';
|
||
if (!session.userId) {
|
||
this.actionError = '请先登录';
|
||
return false;
|
||
}
|
||
if (!targetId) {
|
||
this.actionError = '缺少联系人ID';
|
||
return false;
|
||
}
|
||
try {
|
||
const savedAlias = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.updateContactAlias(session.userId, targetId, nextAlias);
|
||
this.contacts = normalizeContacts(this.contacts.map(item => {
|
||
if (item.uid !== targetId && item.id !== targetId) {
|
||
return item;
|
||
}
|
||
const rawUser = {
|
||
...(item.rawUser || {}),
|
||
friendAlias: savedAlias
|
||
};
|
||
const rawFriend = {
|
||
...(item.rawFriend || {}),
|
||
alias: savedAlias
|
||
};
|
||
const title = savedAlias || rawUser.displayName || rawUser.name || item.uid;
|
||
return {
|
||
...item,
|
||
title,
|
||
avatarText: title.slice(0, 1).toUpperCase(),
|
||
alias: savedAlias,
|
||
rawFriend,
|
||
rawUser
|
||
};
|
||
}));
|
||
this.loadedAt = Date.now();
|
||
this.actionInfo = '备注名已修改';
|
||
return true;
|
||
} catch (error) {
|
||
this.actionError = error.message || '备注名修改失败';
|
||
return false;
|
||
}
|
||
},
|
||
clearContacts() {
|
||
this.refreshSerial += 1;
|
||
this.contacts = [];
|
||
this.activeId = '';
|
||
this.loading = false;
|
||
this.refreshPromise = null;
|
||
this.loadedForUserId = '';
|
||
this.loadedAt = 0;
|
||
this.actionError = '';
|
||
this.actionInfo = '';
|
||
},
|
||
setActiveContact(id) {
|
||
this.activeId = id;
|
||
},
|
||
openChat(contact) {
|
||
if (!contact) {
|
||
return;
|
||
}
|
||
const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_8__/* .useConversationStore */ .w)();
|
||
const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_9__/* .useNavigationStore */ .l)();
|
||
const conversation = _services_imClient__WEBPACK_IMPORTED_MODULE_7__/* .imClient */ .wD.createSingleConversation(contact.uid, contact);
|
||
conversations.upsertConversation(conversation);
|
||
conversations.setActiveConversation(conversation.id);
|
||
navigation.showMessages();
|
||
}
|
||
}
|
||
});
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "p", 0, /* binding */ useContactStore
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7566:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* unused harmony import specifier */ var imClient;
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4114);
|
||
/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8111);
|
||
/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2489);
|
||
/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(116);
|
||
/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__);
|
||
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(531);
|
||
/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5__);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7588);
|
||
/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6__);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1701);
|
||
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__);
|
||
/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(8237);
|
||
/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8__);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(3579);
|
||
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5367);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10__);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(2731);
|
||
/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11__);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(7642);
|
||
/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12__);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(8004);
|
||
/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13__);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(3853);
|
||
/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14__);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(5876);
|
||
/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(2475);
|
||
/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16__);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(5024);
|
||
/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17__);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(1698);
|
||
/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18__);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(2261);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(5051);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(2169);
|
||
/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(926);
|
||
/* harmony import */ var _services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(9687);
|
||
/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(446);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const LOCAL_CONVERSATION_STORAGE_KEY = 'qmt-web-im-local-conversations-v2';
|
||
const LOCAL_FAVORITE_MESSAGES_KEY = 'qmt-web-im-favorite-messages-v1';
|
||
const LOCAL_PINNED_MESSAGES_KEY = 'qmt-web-im-pinned-messages-v1';
|
||
function scopedStorageKey(baseKey) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
const scope = `${_config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.appServer || ''}:${session.userId || 'anonymous'}`;
|
||
return `${baseKey}:${encodeURIComponent(scope)}`;
|
||
}
|
||
function readFavoriteMessages() {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY)) || '[]');
|
||
} catch (error) {
|
||
return [];
|
||
}
|
||
}
|
||
function writeFavoriteMessages(messages) {
|
||
localStorage.setItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY), JSON.stringify(messages));
|
||
}
|
||
function readLocalConversations() {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY)) || '[]');
|
||
} catch (error) {
|
||
return [];
|
||
}
|
||
}
|
||
function writeLocalConversations(conversations) {
|
||
localStorage.setItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY), JSON.stringify(conversations));
|
||
}
|
||
function readPinnedMessages() {
|
||
try {
|
||
return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_PINNED_MESSAGES_KEY)) || '{}');
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
function writePinnedMessages(messages) {
|
||
localStorage.setItem(scopedStorageKey(LOCAL_PINNED_MESSAGES_KEY), JSON.stringify(messages));
|
||
}
|
||
function sortConversations(conversations) {
|
||
return [...conversations].sort((left, right) => {
|
||
const leftPinned = Number(left.pinnedAt || left.top || 0);
|
||
const rightPinned = Number(right.pinnedAt || right.top || 0);
|
||
if (Boolean(leftPinned) !== Boolean(rightPinned)) {
|
||
return rightPinned ? 1 : -1;
|
||
}
|
||
if (leftPinned && rightPinned && leftPinned !== rightPinned) {
|
||
return rightPinned - leftPinned;
|
||
}
|
||
return Number(right.updatedAt || 0) - Number(left.updatedAt || 0);
|
||
});
|
||
}
|
||
function randomId() {
|
||
if (window.crypto && window.crypto.randomUUID) {
|
||
return window.crypto.randomUUID().replaceAll('-', '');
|
||
}
|
||
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
|
||
}
|
||
function messageKey(message) {
|
||
return message.id || message.messageUid;
|
||
}
|
||
function messageStableKey(message) {
|
||
return String(message?.messageUid || message?.id || '');
|
||
}
|
||
function messageActivityTimestamp(message) {
|
||
return Number(message?.activityTimestamp || message?.editedAt || message?.displayTimestamp || message?.timestamp || 0);
|
||
}
|
||
function isRecalledMessage(message) {
|
||
return Boolean(message?.recalled) || message?.status === 'recalled';
|
||
}
|
||
function attachmentLabel(message) {
|
||
const attachment = message?.attachment;
|
||
if (!attachment) {
|
||
return '';
|
||
}
|
||
if (attachment.type === 'image') {
|
||
return '[图片]';
|
||
}
|
||
return `[文件] ${attachment.name || '文件'}`;
|
||
}
|
||
function messagePreviewText(message) {
|
||
if (isRecalledMessage(message)) {
|
||
return `[${message?.recallStatus || '已撤回'}]`;
|
||
}
|
||
const text = String(message?.text || '').replace(/\s+/g, ' ').trim();
|
||
return text || attachmentLabel(message);
|
||
}
|
||
function quotePrefix(message) {
|
||
const text = messagePreviewText(message);
|
||
return text.length > 48 ? `${text.slice(0, 48)}...` : text;
|
||
}
|
||
async function writeClipboard(text) {
|
||
if (navigator.clipboard?.writeText) {
|
||
await navigator.clipboard.writeText(text);
|
||
return;
|
||
}
|
||
const element = document.createElement('textarea');
|
||
element.value = text;
|
||
element.setAttribute('readonly', 'readonly');
|
||
element.style.position = 'fixed';
|
||
element.style.left = '-9999px';
|
||
document.body.appendChild(element);
|
||
element.select();
|
||
document.execCommand('copy');
|
||
document.body.removeChild(element);
|
||
}
|
||
function isSameMessage(left, right) {
|
||
if (left.messageUid && right.messageUid && left.messageUid === right.messageUid) {
|
||
return true;
|
||
}
|
||
if (left.id && right.id && left.id === right.id) {
|
||
return true;
|
||
}
|
||
return left.direction === right.direction && left.text === right.text && (left.type || 'text') === (right.type || 'text') && Math.abs(Number(left.displayTimestamp || left.timestamp || 0) - Number(right.displayTimestamp || right.timestamp || 0)) < 15000;
|
||
}
|
||
function hasExactMessage(messages, message) {
|
||
return messages.some(item => {
|
||
if (item.id && message.id && item.id === message.id) {
|
||
return true;
|
||
}
|
||
return item.messageUid && message.messageUid && item.messageUid === message.messageUid;
|
||
});
|
||
}
|
||
function shouldUseMessagePolling() {
|
||
return imClient.shouldUseMessagePolling ? imClient.shouldUseMessagePolling() : true;
|
||
}
|
||
function canMarkReadNow(options = {}) {
|
||
if (typeof document === 'undefined') {
|
||
return false;
|
||
}
|
||
if (document.visibilityState !== 'visible') {
|
||
return false;
|
||
}
|
||
if (options.userAction) {
|
||
return true;
|
||
}
|
||
return true;
|
||
}
|
||
function normalizeMessageForDisplay(message) {
|
||
if (!message || message.attachment || String(message.text || '').trim()) {
|
||
return message;
|
||
}
|
||
const contentType = Number(message.contentType || 0);
|
||
const labels = {
|
||
3: '[图片加载失败]',
|
||
6: '[视频加载失败]',
|
||
90: '[红包]',
|
||
92: '以上是打招呼的内容',
|
||
93: '你们已经是好友了,可以开始聊天了。',
|
||
105: '[领取了红包]'
|
||
};
|
||
if (!labels[contentType]) {
|
||
return message;
|
||
}
|
||
return {
|
||
...message,
|
||
type: 'text',
|
||
text: labels[contentType]
|
||
};
|
||
}
|
||
function mergeVisibleMessages(currentMessages, syncedMessages) {
|
||
const merged = [...syncedMessages].map(normalizeMessageForDisplay);
|
||
currentMessages.forEach(currentMessage => {
|
||
currentMessage = normalizeMessageForDisplay(currentMessage);
|
||
const exists = merged.some(message => isSameMessage(message, currentMessage));
|
||
const shouldKeepLocal = currentMessage.status === 'sending' || currentMessage.status === 'failed' || currentMessage.direction === 'out' && currentMessage.status === 'sent' && Date.now() - Number(currentMessage.timestamp || 0) < 30000;
|
||
if (!exists && shouldKeepLocal) {
|
||
merged.push(currentMessage);
|
||
}
|
||
});
|
||
return merged.filter((message, index, messages) => {
|
||
const key = messageKey(message);
|
||
return messages.findIndex(item => messageKey(item) === key) === index;
|
||
}).sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0));
|
||
}
|
||
function incomingEditedMessages(previousMessages, nextMessages) {
|
||
const previousByKey = new Map();
|
||
(previousMessages || []).forEach(message => {
|
||
const key = messageStableKey(message);
|
||
if (key) {
|
||
previousByKey.set(key, message);
|
||
}
|
||
});
|
||
return (nextMessages || []).filter(message => {
|
||
if (message.direction !== 'in') {
|
||
return false;
|
||
}
|
||
const editedAt = Number(message.editedAt || 0);
|
||
if (editedAt <= 0) {
|
||
return false;
|
||
}
|
||
const previous = previousByKey.get(messageStableKey(message));
|
||
return previous && editedAt > Number(previous.editedAt || 0);
|
||
});
|
||
}
|
||
let notificationAudioContext = null;
|
||
function playNotificationSound() {
|
||
if (typeof window === 'undefined') {
|
||
return;
|
||
}
|
||
try {
|
||
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
||
if (!AudioContext) {
|
||
return;
|
||
}
|
||
notificationAudioContext = notificationAudioContext || new AudioContext();
|
||
if (notificationAudioContext.state === 'suspended') {
|
||
notificationAudioContext.resume().catch(() => {});
|
||
}
|
||
const oscillator = notificationAudioContext.createOscillator();
|
||
const gain = notificationAudioContext.createGain();
|
||
const startAt = notificationAudioContext.currentTime;
|
||
oscillator.type = 'sine';
|
||
oscillator.frequency.setValueAtTime(880, startAt);
|
||
oscillator.frequency.setValueAtTime(660, startAt + 0.1);
|
||
gain.gain.setValueAtTime(0.0001, startAt);
|
||
gain.gain.exponentialRampToValueAtTime(0.12, startAt + 0.02);
|
||
gain.gain.exponentialRampToValueAtTime(0.0001, startAt + 0.22);
|
||
oscillator.connect(gain);
|
||
gain.connect(notificationAudioContext.destination);
|
||
oscillator.start(startAt);
|
||
oscillator.stop(startAt + 0.24);
|
||
} catch (error) {
|
||
// Notification sound is best-effort; browsers may block audio until user interaction.
|
||
}
|
||
}
|
||
const useConversationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_19__/* .defineStore */ .nY)('conversations', {
|
||
state: () => ({
|
||
activeId: '',
|
||
conversations: [],
|
||
messagesByConversation: {},
|
||
visibleMessagesByConversation: {},
|
||
eventsBound: false,
|
||
usingDemoData: false,
|
||
loading: false,
|
||
syncTimer: null,
|
||
conversationSyncTimer: null,
|
||
readPresenceEventsBound: false,
|
||
syncInFlight: false,
|
||
pendingReadReceiptConversationId: '',
|
||
conversationSyncInFlight: false,
|
||
syncAfterSendTimer: null,
|
||
optimisticMessagesByConversation: {},
|
||
quotedMessage: null,
|
||
forwardingMessages: [],
|
||
editingMessage: null,
|
||
editingText: '',
|
||
editingMode: '',
|
||
messageDetailOpen: false,
|
||
messageDetailLoading: false,
|
||
messageDetailError: '',
|
||
messageDetail: null,
|
||
attentionMessageId: '',
|
||
attentionMessageTimer: null,
|
||
selectionMode: false,
|
||
selectedMessageIds: [],
|
||
favoriteMessages: [],
|
||
pinnedMessagesByConversation: {},
|
||
activeFavoriteKey: '',
|
||
actionNotice: '',
|
||
actionError: '',
|
||
actionNoticeTimer: null,
|
||
realtimeSyncTimer: null
|
||
}),
|
||
getters: {
|
||
activeConversation(state) {
|
||
return state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;
|
||
},
|
||
activeMessages(state) {
|
||
return state.visibleMessagesByConversation[state.activeId] || [];
|
||
},
|
||
totalUnread(state) {
|
||
return state.conversations.reduce((sum, item) => sum + Number(item.unread || 0), 0);
|
||
},
|
||
canSendActiveConversation(state) {
|
||
const conversation = state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;
|
||
if (!conversation) {
|
||
return false;
|
||
}
|
||
if (conversation.type !== 'channel') {
|
||
return true;
|
||
}
|
||
return ['owner', 'admin'].includes(conversation.role || conversation.raw?.role || '');
|
||
},
|
||
favoriteMessageIds(state) {
|
||
return state.favoriteMessages.map(message => message.key);
|
||
},
|
||
activeFavorite(state) {
|
||
return state.favoriteMessages.find(message => message.key === state.activeFavoriteKey) || state.favoriteMessages[0] || null;
|
||
},
|
||
activePinnedMessage(state) {
|
||
const pinned = state.pinnedMessagesByConversation[state.activeId] || null;
|
||
if (!pinned) return null;
|
||
const message = (state.visibleMessagesByConversation[state.activeId] || []).find(item => messageStableKey(item) === pinned.key);
|
||
return message ? {
|
||
...pinned,
|
||
...message,
|
||
key: pinned.key
|
||
} : pinned;
|
||
},
|
||
selectedMessages(state) {
|
||
const selectedIds = new Set(state.selectedMessageIds);
|
||
return (state.visibleMessagesByConversation[state.activeId] || []).filter(message => selectedIds.has(messageStableKey(message)));
|
||
}
|
||
},
|
||
actions: {
|
||
bootstrapDemoData() {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
this.bindImEvents();
|
||
this.usingDemoData = false;
|
||
if (!session.userId) {
|
||
this.clearUserState();
|
||
return;
|
||
}
|
||
this.loadScopedLocalState();
|
||
this.startMessageSync();
|
||
_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.start(session.userId, payload => this.handleRealtimeNotification(payload));
|
||
},
|
||
loadScopedLocalState() {
|
||
this.conversations = [];
|
||
this.favoriteMessages = readFavoriteMessages();
|
||
this.pinnedMessagesByConversation = readPinnedMessages();
|
||
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
|
||
this.activeId = '';
|
||
this.messagesByConversation = {};
|
||
this.visibleMessagesByConversation = {};
|
||
this.optimisticMessagesByConversation = {};
|
||
this.quotedMessage = null;
|
||
this.forwardingMessages = [];
|
||
this.editingMessage = null;
|
||
this.editingText = '';
|
||
this.editingMode = '';
|
||
this.messageDetailOpen = false;
|
||
this.messageDetailLoading = false;
|
||
this.messageDetailError = '';
|
||
this.messageDetail = null;
|
||
this.selectionMode = false;
|
||
this.selectedMessageIds = [];
|
||
},
|
||
clearUserState() {
|
||
window.clearInterval(this.syncTimer);
|
||
window.clearInterval(this.conversationSyncTimer);
|
||
window.clearTimeout(this.syncAfterSendTimer);
|
||
window.clearTimeout(this.attentionMessageTimer);
|
||
window.clearTimeout(this.actionNoticeTimer);
|
||
window.clearTimeout(this.realtimeSyncTimer);
|
||
_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.stop();
|
||
this.syncTimer = null;
|
||
this.conversationSyncTimer = null;
|
||
this.syncAfterSendTimer = null;
|
||
this.attentionMessageTimer = null;
|
||
this.actionNoticeTimer = null;
|
||
this.realtimeSyncTimer = null;
|
||
this.syncInFlight = false;
|
||
this.conversationSyncInFlight = false;
|
||
this.pendingReadReceiptConversationId = '';
|
||
this.activeId = '';
|
||
this.conversations = [];
|
||
this.messagesByConversation = {};
|
||
this.visibleMessagesByConversation = {};
|
||
this.optimisticMessagesByConversation = {};
|
||
this.quotedMessage = null;
|
||
this.forwardingMessages = [];
|
||
this.editingMessage = null;
|
||
this.editingText = '';
|
||
this.editingMode = '';
|
||
this.messageDetailOpen = false;
|
||
this.messageDetailLoading = false;
|
||
this.messageDetailError = '';
|
||
this.messageDetail = null;
|
||
this.attentionMessageId = '';
|
||
this.selectionMode = false;
|
||
this.selectedMessageIds = [];
|
||
this.favoriteMessages = [];
|
||
this.activeFavoriteKey = '';
|
||
this.actionNotice = '';
|
||
this.actionError = '';
|
||
},
|
||
bindImEvents() {
|
||
if (this.eventsBound) {
|
||
return;
|
||
}
|
||
this.eventsBound = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageSent', message => {
|
||
this.appendMessage(message.conversationId, message);
|
||
});
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageReceived', message => {
|
||
this.appendMessage(message.conversationId, message);
|
||
if (message.conversationId === this.activeId) {
|
||
this.scheduleActiveMessagesSync({
|
||
allowReadReceipt: true
|
||
}, 500);
|
||
}
|
||
});
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('messageStatusChanged', message => {
|
||
this.replaceMessage(message.conversationId, message);
|
||
});
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.on('conversationsChanged', remoteConversations => {
|
||
this.usingDemoData = false;
|
||
this.applyRemoteConversations(remoteConversations);
|
||
});
|
||
},
|
||
setActiveConversation(id) {
|
||
this.activeId = id;
|
||
const conversation = this.conversations.find(item => item.id === id);
|
||
if (conversation) {
|
||
conversation.unread = 0;
|
||
}
|
||
this.loadActiveMessages({
|
||
allowReadReceipt: true,
|
||
userAction: true
|
||
});
|
||
},
|
||
sendText(text) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation || !text.trim()) {
|
||
return;
|
||
}
|
||
let value = text.trim();
|
||
if (this.quotedMessage) {
|
||
value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`;
|
||
this.quotedMessage = null;
|
||
}
|
||
const message = {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: 'me',
|
||
direction: 'out',
|
||
type: 'text',
|
||
text: value,
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now(),
|
||
displayTimestamp: Date.now()
|
||
};
|
||
this.appendVisibleMessage(conversation.id, message);
|
||
this.appendMessage(conversation.id, message);
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendTextMessage(conversation, value, message);
|
||
conversation.subtitle = value;
|
||
conversation.updatedAt = Date.now();
|
||
writeLocalConversations(this.conversations);
|
||
window.clearTimeout(this.syncAfterSendTimer);
|
||
this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 250);
|
||
},
|
||
sendAttachment({
|
||
type,
|
||
file,
|
||
text = ''
|
||
}) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation || !file || !['image', 'file'].includes(type)) {
|
||
return;
|
||
}
|
||
let value = text.trim();
|
||
if (this.quotedMessage) {
|
||
value = `引用:${quotePrefix(this.quotedMessage)}\n${value}`.trim();
|
||
this.quotedMessage = null;
|
||
}
|
||
const now = Date.now();
|
||
const message = {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: 'me',
|
||
senderRole: conversation.role || conversation.raw?.role || '',
|
||
direction: 'out',
|
||
type,
|
||
text: value,
|
||
attachment: {
|
||
type,
|
||
name: file.name || (type === 'image' ? '图片' : '文件'),
|
||
mime: file.type || '',
|
||
size: file.size || 0,
|
||
url: type === 'image' ? URL.createObjectURL(file) : ''
|
||
},
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: now,
|
||
displayTimestamp: now
|
||
};
|
||
this.appendVisibleMessage(conversation.id, message);
|
||
this.appendMessage(conversation.id, message);
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendAttachmentMessage(conversation, {
|
||
type,
|
||
file,
|
||
text: value
|
||
}, message);
|
||
conversation.subtitle = messagePreviewText(message);
|
||
conversation.updatedAt = now;
|
||
writeLocalConversations(this.conversations);
|
||
window.clearTimeout(this.syncAfterSendTimer);
|
||
this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 350);
|
||
},
|
||
async sendTextToConversation(conversation, text) {
|
||
if (!conversation || !text.trim()) {
|
||
return null;
|
||
}
|
||
const value = text.trim();
|
||
const message = {
|
||
id: randomId(),
|
||
conversationId: conversation.id,
|
||
from: 'me',
|
||
direction: 'out',
|
||
type: 'text',
|
||
text: value,
|
||
status: 'sending',
|
||
deliveryStatus: 'sending',
|
||
timestamp: Date.now(),
|
||
displayTimestamp: Date.now()
|
||
};
|
||
this.appendMessage(conversation.id, message);
|
||
const sentMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendTextMessage(conversation, value, message);
|
||
this.replaceMessage(conversation.id, sentMessage);
|
||
return sentMessage;
|
||
},
|
||
upsertConversation(conversation) {
|
||
const index = this.conversations.findIndex(item => item.id === conversation.id);
|
||
if (index >= 0) {
|
||
this.conversations.splice(index, 1, {
|
||
...this.conversations[index],
|
||
...conversation
|
||
});
|
||
} else {
|
||
this.conversations.unshift(conversation);
|
||
}
|
||
this.usingDemoData = false;
|
||
writeLocalConversations(this.conversations);
|
||
},
|
||
removeConversation(conversationId) {
|
||
this.conversations = this.conversations.filter(conversation => conversation.id !== conversationId);
|
||
const {
|
||
[conversationId]: removedMessages,
|
||
...messagesByConversation
|
||
} = this.messagesByConversation;
|
||
const {
|
||
[conversationId]: removedVisibleMessages,
|
||
...visibleMessagesByConversation
|
||
} = this.visibleMessagesByConversation;
|
||
const {
|
||
[conversationId]: removedOptimisticMessages,
|
||
...optimisticMessagesByConversation
|
||
} = this.optimisticMessagesByConversation;
|
||
void removedMessages;
|
||
void removedVisibleMessages;
|
||
void removedOptimisticMessages;
|
||
this.messagesByConversation = messagesByConversation;
|
||
this.visibleMessagesByConversation = visibleMessagesByConversation;
|
||
this.optimisticMessagesByConversation = optimisticMessagesByConversation;
|
||
if (this.activeId === conversationId) {
|
||
this.activeId = this.conversations[0]?.id || '';
|
||
}
|
||
writeLocalConversations(this.conversations);
|
||
if (this.activeId) {
|
||
this.loadActiveMessages();
|
||
}
|
||
},
|
||
applyRemoteConversations(remoteConversations) {
|
||
const remote = Array.isArray(remoteConversations) ? remoteConversations : [];
|
||
if (!remote.length && this.conversations.length) {
|
||
return;
|
||
}
|
||
const merged = new Map();
|
||
this.conversations.forEach(conversation => {
|
||
merged.set(conversation.id, conversation);
|
||
});
|
||
remote.forEach(conversation => {
|
||
const unread = conversation.id === this.activeId && canMarkReadNow() ? 0 : Number(conversation.unread || 0);
|
||
merged.set(conversation.id, {
|
||
...(merged.get(conversation.id) || {}),
|
||
...conversation,
|
||
unread
|
||
});
|
||
});
|
||
this.conversations = sortConversations(Array.from(merged.values())).slice(0, 100);
|
||
if (!this.conversations.length) {
|
||
this.activeId = '';
|
||
this.messagesByConversation = {};
|
||
this.visibleMessagesByConversation = {};
|
||
this.optimisticMessagesByConversation = {};
|
||
writeLocalConversations(this.conversations);
|
||
return;
|
||
}
|
||
if (!this.conversations.find(item => item.id === this.activeId)) {
|
||
this.activeId = this.conversations[0].id;
|
||
}
|
||
writeLocalConversations(this.conversations);
|
||
this.loadActiveMessages();
|
||
},
|
||
togglePinnedConversation(conversationId) {
|
||
const conversation = this.conversations.find(item => item.id === conversationId);
|
||
if (!conversation) return;
|
||
conversation.pinnedAt = Number(conversation.pinnedAt || conversation.top || 0) > 0 ? 0 : Date.now();
|
||
conversation.top = conversation.pinnedAt;
|
||
this.conversations = sortConversations(this.conversations);
|
||
writeLocalConversations(this.conversations);
|
||
},
|
||
appendMessage(conversationId, message) {
|
||
if (!this.messagesByConversation[conversationId]) {
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: []
|
||
};
|
||
}
|
||
if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent')) {
|
||
this.keepOptimisticMessage(conversationId, message);
|
||
}
|
||
if (!hasExactMessage(this.messagesByConversation[conversationId], message)) {
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: [...this.messagesByConversation[conversationId], message]
|
||
};
|
||
}
|
||
this.updateConversationFromMessage(conversationId, message);
|
||
this.syncVisibleMessages(conversationId);
|
||
writeLocalConversations(this.conversations);
|
||
},
|
||
removeMessages(conversationId, messages) {
|
||
const ids = new Set(messages.flatMap(message => [message.id, message.messageUid].filter(Boolean).map(String)));
|
||
const filterMessages = list => (list || []).filter(message => {
|
||
return ![message.id, message.messageUid].filter(Boolean).some(id => ids.has(String(id)));
|
||
});
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: filterMessages(this.messagesByConversation[conversationId])
|
||
};
|
||
this.visibleMessagesByConversation = {
|
||
...this.visibleMessagesByConversation,
|
||
[conversationId]: filterMessages(this.visibleMessagesByConversation[conversationId])
|
||
};
|
||
this.optimisticMessagesByConversation = {
|
||
...this.optimisticMessagesByConversation,
|
||
[conversationId]: filterMessages(this.optimisticMessagesByConversation[conversationId])
|
||
};
|
||
this.selectedMessageIds = this.selectedMessageIds.filter(id => !ids.has(String(id)));
|
||
},
|
||
replaceLocalMessage(conversationId, targetMessage, nextMessage) {
|
||
const keys = new Set([targetMessage.id, targetMessage.messageUid].filter(Boolean).map(String));
|
||
const replaceInList = list => (list || []).map(message => {
|
||
const matched = [message.id, message.messageUid].filter(Boolean).some(id => keys.has(String(id)));
|
||
return matched ? {
|
||
...message,
|
||
...nextMessage
|
||
} : message;
|
||
});
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: replaceInList(this.messagesByConversation[conversationId])
|
||
};
|
||
this.visibleMessagesByConversation = {
|
||
...this.visibleMessagesByConversation,
|
||
[conversationId]: replaceInList(this.visibleMessagesByConversation[conversationId])
|
||
};
|
||
},
|
||
updateConversationFromMessage(conversationId, message) {
|
||
const conversation = this.conversations.find(item => item.id === conversationId);
|
||
if (!conversation) {
|
||
return;
|
||
}
|
||
conversation.subtitle = message.text || conversation.subtitle || '';
|
||
conversation.updatedAt = messageActivityTimestamp(message) || Date.now();
|
||
if (message.direction === 'in') {
|
||
conversation.unread = conversationId === this.activeId ? 0 : Number(conversation.unread || 0) + 1;
|
||
}
|
||
this.conversations = [...this.conversations].sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));
|
||
},
|
||
appendVisibleMessage(conversationId, message) {
|
||
const messages = this.visibleMessagesByConversation[conversationId] || [];
|
||
this.visibleMessagesByConversation = {
|
||
...this.visibleMessagesByConversation,
|
||
[conversationId]: [...messages.filter(item => item.id !== message.id), message].sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0))
|
||
};
|
||
},
|
||
replaceMessage(conversationId, message) {
|
||
if (!this.messagesByConversation[conversationId]) {
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: []
|
||
};
|
||
}
|
||
if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent' || message.status === 'failed')) {
|
||
this.keepOptimisticMessage(conversationId, message);
|
||
}
|
||
const index = this.messagesByConversation[conversationId].findIndex(item => item.id === message.id);
|
||
if (index >= 0) {
|
||
const messages = [...this.messagesByConversation[conversationId]];
|
||
messages.splice(index, 1, message);
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: messages
|
||
};
|
||
} else {
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversationId]: [...this.messagesByConversation[conversationId], message]
|
||
};
|
||
}
|
||
this.syncVisibleMessages(conversationId);
|
||
},
|
||
syncVisibleMessages(conversationId) {
|
||
this.visibleMessagesByConversation = {
|
||
...this.visibleMessagesByConversation,
|
||
[conversationId]: mergeVisibleMessages(this.optimisticMessagesByConversation[conversationId] || [], this.messagesByConversation[conversationId] || [])
|
||
};
|
||
},
|
||
keepOptimisticMessage(conversationId, message) {
|
||
if (!this.optimisticMessagesByConversation[conversationId]) {
|
||
this.optimisticMessagesByConversation = {
|
||
...this.optimisticMessagesByConversation,
|
||
[conversationId]: []
|
||
};
|
||
}
|
||
const messages = this.optimisticMessagesByConversation[conversationId];
|
||
const index = messages.findIndex(item => item.id === message.id);
|
||
let nextMessages;
|
||
if (index >= 0) {
|
||
nextMessages = [...messages];
|
||
nextMessages.splice(index, 1, message);
|
||
} else {
|
||
nextMessages = [...messages, message];
|
||
}
|
||
this.optimisticMessagesByConversation = {
|
||
...this.optimisticMessagesByConversation,
|
||
[conversationId]: nextMessages
|
||
};
|
||
},
|
||
pruneOptimisticMessages(conversationId, syncedMessages) {
|
||
const messages = this.optimisticMessagesByConversation[conversationId] || [];
|
||
if (!messages.length) {
|
||
return;
|
||
}
|
||
this.optimisticMessagesByConversation = {
|
||
...this.optimisticMessagesByConversation,
|
||
[conversationId]: messages.filter(message => {
|
||
const remoteMatched = syncedMessages.some(syncedMessage => {
|
||
return syncedMessage.id !== message.id && isSameMessage(syncedMessage, message);
|
||
});
|
||
if (remoteMatched && message.status !== 'failed') {
|
||
return false;
|
||
}
|
||
return Date.now() - Number(message.displayTimestamp || message.timestamp || 0) < 30000 || message.status === 'failed';
|
||
})
|
||
};
|
||
},
|
||
loadActiveMessages(options = {}) {
|
||
const syncOptions = typeof options === 'boolean' ? {
|
||
allowReadReceipt: options
|
||
} : options;
|
||
const conversation = this.activeConversation;
|
||
if (!conversation) {
|
||
return;
|
||
}
|
||
this.loading = true;
|
||
const messages = _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.getMessages(conversation, 30);
|
||
this.pruneOptimisticMessages(conversation.id, messages);
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[conversation.id]: mergeVisibleMessages(this.messagesByConversation[conversation.id] || [], messages)
|
||
};
|
||
this.syncVisibleMessages(conversation.id);
|
||
this.loading = false;
|
||
this.syncActiveMessages(syncOptions);
|
||
},
|
||
async syncActiveMessages(options = {}) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation) {
|
||
return;
|
||
}
|
||
const wantsReadReceipt = Boolean(options.allowReadReceipt);
|
||
const explicitReadReceipt = wantsReadReceipt && canMarkReadNow({
|
||
userAction: Boolean(options.userAction)
|
||
});
|
||
const pollingReadReceipt = canMarkReadNow();
|
||
const markRead = explicitReadReceipt || pollingReadReceipt;
|
||
if (this.syncInFlight) {
|
||
if (wantsReadReceipt) {
|
||
this.pendingReadReceiptConversationId = conversation.id;
|
||
}
|
||
return;
|
||
}
|
||
this.syncInFlight = true;
|
||
const syncedConversationId = conversation.id;
|
||
const previousMessages = this.messagesByConversation[syncedConversationId] || [];
|
||
try {
|
||
const messages = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.fetchRemoteMessages(conversation, 50, {
|
||
markRead,
|
||
includeConversations: Boolean(options.includeConversations)
|
||
});
|
||
const remotePinnedKey = String(messages.pinnedMessageUid || '');
|
||
if (remotePinnedKey) {
|
||
const pinnedMessage = messages.find(item => messageStableKey(item) === remotePinnedKey);
|
||
this.pinnedMessagesByConversation = {
|
||
...this.pinnedMessagesByConversation,
|
||
[syncedConversationId]: pinnedMessage ? {
|
||
key: remotePinnedKey,
|
||
id: remotePinnedKey,
|
||
text: messagePreviewText(pinnedMessage),
|
||
type: pinnedMessage.type || 'text',
|
||
attachment: pinnedMessage.attachment ? {
|
||
...pinnedMessage.attachment
|
||
} : null,
|
||
senderName: pinnedMessage.senderName || pinnedMessage.from || '',
|
||
timestamp: Number(pinnedMessage.displayTimestamp || pinnedMessage.timestamp || Date.now())
|
||
} : {
|
||
key: remotePinnedKey,
|
||
id: remotePinnedKey,
|
||
text: '[置顶消息]'
|
||
}
|
||
};
|
||
writePinnedMessages(this.pinnedMessagesByConversation);
|
||
}
|
||
const editedIncomingMessages = incomingEditedMessages(previousMessages, messages);
|
||
this.pruneOptimisticMessages(syncedConversationId, messages);
|
||
this.messagesByConversation = {
|
||
...this.messagesByConversation,
|
||
[syncedConversationId]: mergeVisibleMessages(this.messagesByConversation[syncedConversationId] || [], messages)
|
||
};
|
||
this.syncVisibleMessages(syncedConversationId);
|
||
if (editedIncomingMessages.length && syncedConversationId === this.activeId) {
|
||
this.focusMessage(editedIncomingMessages.sort((a, b) => messageActivityTimestamp(b) - messageActivityTimestamp(a))[0]);
|
||
playNotificationSound();
|
||
}
|
||
const latest = messages.reduce((latestMessage, message) => {
|
||
if (!latestMessage || messageActivityTimestamp(message) > messageActivityTimestamp(latestMessage)) {
|
||
return message;
|
||
}
|
||
return latestMessage;
|
||
}, null);
|
||
if (latest) {
|
||
conversation.subtitle = messagePreviewText(latest);
|
||
conversation.updatedAt = messageActivityTimestamp(latest);
|
||
writeLocalConversations(this.conversations);
|
||
}
|
||
} catch (error) {
|
||
// Keep the local view usable if a polling request misses.
|
||
} finally {
|
||
this.syncInFlight = false;
|
||
if (this.pendingReadReceiptConversationId === this.activeId && canMarkReadNow()) {
|
||
this.pendingReadReceiptConversationId = '';
|
||
window.setTimeout(() => this.syncActiveMessages({
|
||
allowReadReceipt: true
|
||
}), 0);
|
||
}
|
||
}
|
||
},
|
||
scheduleActiveMessagesSync(options = {}, delay = 500) {
|
||
if (!this.activeId || typeof document !== 'undefined' && document.visibilityState !== 'visible') {
|
||
return;
|
||
}
|
||
window.clearTimeout(this.syncAfterSendTimer);
|
||
this.syncAfterSendTimer = window.setTimeout(() => {
|
||
this.syncAfterSendTimer = null;
|
||
this.syncActiveMessages(options);
|
||
}, Math.max(0, Number(delay) || 0));
|
||
},
|
||
startMessageSync() {
|
||
this.bindReadPresenceEvents();
|
||
if (!this.syncTimer) {
|
||
this.syncTimer = window.setInterval(() => {
|
||
if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
|
||
this.syncActiveMessages();
|
||
}
|
||
}, Math.max(250, _config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.syncIntervalMs));
|
||
}
|
||
if (!this.conversationSyncTimer) {
|
||
this.conversationSyncTimer = window.setInterval(() => {
|
||
if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__/* .realtimeNotifications */ .w.isConnected()) {
|
||
this.refreshRemoteConversations();
|
||
}
|
||
}, Math.max(5000, _config__WEBPACK_IMPORTED_MODULE_21__/* .appConfig */ .U.syncIntervalMs * 2));
|
||
this.refreshRemoteConversations();
|
||
}
|
||
},
|
||
handleRealtimeNotification() {
|
||
window.clearTimeout(this.realtimeSyncTimer);
|
||
this.realtimeSyncTimer = window.setTimeout(() => {
|
||
this.refreshRemoteConversations();
|
||
this.scheduleActiveMessagesSync({
|
||
allowReadReceipt: canMarkReadNow(),
|
||
includeConversations: true
|
||
}, 300);
|
||
}, 300);
|
||
},
|
||
bindReadPresenceEvents() {
|
||
if (this.readPresenceEventsBound || typeof window === 'undefined' || typeof document === 'undefined') {
|
||
return;
|
||
}
|
||
this.readPresenceEventsBound = true;
|
||
const syncWhenReadable = () => {
|
||
if (canMarkReadNow()) {
|
||
this.refreshRemoteConversations();
|
||
this.scheduleActiveMessagesSync({
|
||
allowReadReceipt: true
|
||
}, 200);
|
||
}
|
||
};
|
||
window.addEventListener('focus', syncWhenReadable);
|
||
document.addEventListener('visibilitychange', syncWhenReadable);
|
||
},
|
||
async refreshRemoteConversations() {
|
||
this.bindImEvents();
|
||
this.usingDemoData = false;
|
||
if (this.conversationSyncInFlight) {
|
||
return;
|
||
}
|
||
this.conversationSyncInFlight = true;
|
||
try {
|
||
const remoteConversations = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.fetchRemoteConversations(50);
|
||
this.applyRemoteConversations(remoteConversations);
|
||
} catch (error) {
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.refreshConversationList();
|
||
} finally {
|
||
this.conversationSyncInFlight = false;
|
||
}
|
||
},
|
||
setActionNotice(message) {
|
||
this.actionNotice = message;
|
||
this.actionError = '';
|
||
window.clearTimeout(this.actionNoticeTimer);
|
||
this.actionNoticeTimer = window.setTimeout(() => {
|
||
this.actionNotice = '';
|
||
this.actionNoticeTimer = null;
|
||
}, 3000);
|
||
},
|
||
setActionError(message) {
|
||
this.actionError = message;
|
||
this.actionNotice = '';
|
||
window.clearTimeout(this.actionNoticeTimer);
|
||
},
|
||
focusMessage(message) {
|
||
const key = messageStableKey(message);
|
||
if (!key) {
|
||
return;
|
||
}
|
||
this.attentionMessageId = key;
|
||
window.clearTimeout(this.attentionMessageTimer);
|
||
this.attentionMessageTimer = window.setTimeout(() => {
|
||
if (this.attentionMessageId === key) {
|
||
this.attentionMessageId = '';
|
||
}
|
||
}, 2800);
|
||
},
|
||
async handleMessageAction({
|
||
action,
|
||
message
|
||
}) {
|
||
if (!message) {
|
||
return;
|
||
}
|
||
if (action === 'copy') {
|
||
await this.copyMessages([message]);
|
||
} else if (action === 'edit') {
|
||
this.startEditMessage(message);
|
||
} else if (action === 'delete') {
|
||
this.deleteMessages([message]);
|
||
} else if (action === 'forward') {
|
||
this.startForward([message]);
|
||
} else if (action === 'favorite') {
|
||
this.toggleFavorite(message);
|
||
} else if (action === 'pin') {
|
||
this.togglePinnedMessage(message);
|
||
} else if (action === 'detail') {
|
||
await this.openMessageDetail(message);
|
||
} else if (action === 'quote') {
|
||
this.quoteMessage(message);
|
||
} else if (action === 'select') {
|
||
this.enterSelectionMode(message);
|
||
} else if (action === 'recall') {
|
||
await this.recallMessage(message);
|
||
}
|
||
},
|
||
async openMessageDetail(message) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation || !message) {
|
||
return;
|
||
}
|
||
const key = messageStableKey(message);
|
||
this.messageDetailOpen = true;
|
||
this.messageDetailLoading = true;
|
||
this.messageDetailError = '';
|
||
this.messageDetail = {
|
||
messageUid: key,
|
||
conversationType: conversation.type || conversation.raw?.type || 'single',
|
||
sentAt: Number(message.displayTimestamp || message.timestamp || 0),
|
||
editedAt: Number(message.editedAt || 0),
|
||
recalled: isRecalledMessage(message),
|
||
localOnly: true,
|
||
sender: {
|
||
uid: message.from || '',
|
||
name: message.senderName || message.from || ''
|
||
}
|
||
};
|
||
try {
|
||
if (!/^\d+$/.test(key)) {
|
||
this.messageDetailError = '本地临时消息暂无送达/已读详情';
|
||
return;
|
||
}
|
||
const detail = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.getMessageDetail(conversation, message);
|
||
this.messageDetail = detail || this.messageDetail;
|
||
} catch (error) {
|
||
this.messageDetailError = error.message || '消息详情加载失败';
|
||
} finally {
|
||
this.messageDetailLoading = false;
|
||
}
|
||
},
|
||
closeMessageDetail() {
|
||
this.messageDetailOpen = false;
|
||
this.messageDetailLoading = false;
|
||
this.messageDetailError = '';
|
||
this.messageDetail = null;
|
||
},
|
||
async copyMessages(messages) {
|
||
const text = messages.map(message => message.text || '').join('\n');
|
||
if (!text.trim()) {
|
||
return;
|
||
}
|
||
try {
|
||
await writeClipboard(text);
|
||
this.setActionNotice(messages.length > 1 ? '已复制所选消息' : '已复制');
|
||
} catch (error) {
|
||
this.setActionError('复制失败');
|
||
}
|
||
},
|
||
deleteMessages(messages) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation || !messages.length) {
|
||
return;
|
||
}
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.hideMessages(conversation, messages);
|
||
this.removeMessages(conversation.id, messages);
|
||
if (!this.selectedMessageIds.length) {
|
||
this.selectionMode = false;
|
||
}
|
||
this.setActionNotice(messages.length > 1 ? '已删除所选消息' : '已删除');
|
||
},
|
||
toggleFavorite(message) {
|
||
const key = messageStableKey(message);
|
||
if (!key) {
|
||
return;
|
||
}
|
||
const index = this.favoriteMessages.findIndex(item => item.key === key);
|
||
if (index >= 0) {
|
||
this.favoriteMessages.splice(index, 1);
|
||
if (this.activeFavoriteKey === key) {
|
||
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
|
||
}
|
||
this.setActionNotice('已取消收藏');
|
||
} else {
|
||
const conversation = this.conversations.find(item => item.id === message.conversationId) || {};
|
||
this.favoriteMessages.unshift({
|
||
key,
|
||
id: message.id,
|
||
messageUid: message.messageUid,
|
||
conversationId: message.conversationId,
|
||
conversationTitle: conversation.title || message.conversationTitle || '',
|
||
type: message.type || 'text',
|
||
text: message.text || '',
|
||
preview: messagePreviewText(message),
|
||
senderName: message.senderName || message.from || '',
|
||
timestamp: Number(message.displayTimestamp || message.timestamp || Date.now()),
|
||
editedAt: Number(message.editedAt || 0),
|
||
recalled: isRecalledMessage(message),
|
||
recallStatus: message.recallStatus || (isRecalledMessage(message) ? '已撤回' : ''),
|
||
attachment: message.attachment ? {
|
||
...message.attachment
|
||
} : null
|
||
});
|
||
this.activeFavoriteKey = key;
|
||
this.setActionNotice('已收藏');
|
||
}
|
||
this.favoriteMessages = this.favoriteMessages.slice(0, 200);
|
||
writeFavoriteMessages(this.favoriteMessages);
|
||
},
|
||
async togglePinnedMessage(message) {
|
||
const conversationId = message?.conversationId || this.activeId;
|
||
const key = messageStableKey(message);
|
||
if (!conversationId || !key) return;
|
||
const current = this.pinnedMessagesByConversation[conversationId];
|
||
const next = {
|
||
...this.pinnedMessagesByConversation
|
||
};
|
||
if (current && current.key === key) {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, '').catch(error => this.setActionError(error.message || '取消置顶失败'));
|
||
delete next[conversationId];
|
||
this.setActionNotice('已取消置顶');
|
||
} else {
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, key);
|
||
} catch (error) {
|
||
this.setActionError(error.message || '置顶失败');
|
||
return;
|
||
}
|
||
next[conversationId] = {
|
||
key,
|
||
id: key,
|
||
text: messagePreviewText(message),
|
||
type: message.type || 'text',
|
||
attachment: message.attachment ? {
|
||
...message.attachment
|
||
} : null,
|
||
senderName: message.senderName || message.from || '',
|
||
timestamp: Number(message.displayTimestamp || message.timestamp || Date.now())
|
||
};
|
||
this.setActionNotice('消息已置顶');
|
||
}
|
||
this.pinnedMessagesByConversation = next;
|
||
writePinnedMessages(next);
|
||
},
|
||
async clearPinnedMessage() {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.setPinnedMessage(this.activeConversation, '').catch(error => this.setActionError(error.message || '取消置顶失败'));
|
||
const next = {
|
||
...this.pinnedMessagesByConversation
|
||
};
|
||
delete next[this.activeId];
|
||
this.pinnedMessagesByConversation = next;
|
||
writePinnedMessages(next);
|
||
this.setActionNotice('已取消置顶');
|
||
},
|
||
setActiveFavorite(key) {
|
||
this.activeFavoriteKey = String(key || '');
|
||
},
|
||
removeFavorite(key) {
|
||
const value = String(key || '');
|
||
if (!value) {
|
||
return;
|
||
}
|
||
this.favoriteMessages = this.favoriteMessages.filter(message => message.key !== value);
|
||
if (this.activeFavoriteKey === value) {
|
||
this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';
|
||
}
|
||
writeFavoriteMessages(this.favoriteMessages);
|
||
},
|
||
quoteMessage(message) {
|
||
this.quotedMessage = {
|
||
...message,
|
||
quoteText: quotePrefix(message)
|
||
};
|
||
this.setActionNotice('已引用,输入后发送');
|
||
},
|
||
cancelQuote() {
|
||
this.quotedMessage = null;
|
||
},
|
||
enterSelectionMode(message = null) {
|
||
this.selectionMode = true;
|
||
if (message) {
|
||
const key = messageStableKey(message);
|
||
this.selectedMessageIds = key ? [key] : [];
|
||
}
|
||
},
|
||
toggleSelectedMessage(message) {
|
||
const key = messageStableKey(message);
|
||
if (!key) {
|
||
return;
|
||
}
|
||
const selected = new Set(this.selectedMessageIds);
|
||
if (selected.has(key)) {
|
||
selected.delete(key);
|
||
} else {
|
||
selected.add(key);
|
||
}
|
||
this.selectedMessageIds = Array.from(selected);
|
||
this.selectionMode = this.selectedMessageIds.length > 0;
|
||
},
|
||
clearSelection() {
|
||
this.selectionMode = false;
|
||
this.selectedMessageIds = [];
|
||
},
|
||
copySelectedMessages() {
|
||
return this.copyMessages(this.selectedMessages);
|
||
},
|
||
deleteSelectedMessages() {
|
||
this.deleteMessages(this.selectedMessages);
|
||
},
|
||
startForward(messages) {
|
||
this.forwardingMessages = messages.filter(message => message?.text || message?.attachment?.url);
|
||
if (!this.forwardingMessages.length) {
|
||
this.setActionError('没有可转发的消息');
|
||
}
|
||
},
|
||
startForwardSelectedMessages() {
|
||
this.startForward(this.selectedMessages);
|
||
},
|
||
cancelForward() {
|
||
this.forwardingMessages = [];
|
||
},
|
||
startEditMessage(message) {
|
||
const isResend = isRecalledMessage(message);
|
||
if (!isResend && !message?.text) {
|
||
this.setActionError('没有可编辑的文字内容');
|
||
return;
|
||
}
|
||
this.editingMessage = message;
|
||
this.editingText = message.text || '';
|
||
this.editingMode = isResend ? 'resend' : 'edit';
|
||
},
|
||
cancelEditMessage() {
|
||
this.editingMessage = null;
|
||
this.editingText = '';
|
||
this.editingMode = '';
|
||
},
|
||
async completeEditMessage() {
|
||
const conversation = this.activeConversation;
|
||
const message = this.editingMessage;
|
||
const text = this.editingText.trim();
|
||
const isResend = this.editingMode === 'resend' || isRecalledMessage(message);
|
||
if (!conversation || !message) {
|
||
this.cancelEditMessage();
|
||
return;
|
||
}
|
||
if (!text) {
|
||
this.setActionError('编辑内容不能为空');
|
||
return;
|
||
}
|
||
if (!isResend && text === String(message.text || '').trim()) {
|
||
this.cancelEditMessage();
|
||
return;
|
||
}
|
||
try {
|
||
if (isResend) {
|
||
await this.sendTextToConversation(conversation, text);
|
||
this.cancelEditMessage();
|
||
this.setActionNotice('已重新发送');
|
||
return;
|
||
}
|
||
const editedMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.editMessage(conversation, message, text);
|
||
this.replaceLocalMessage(conversation.id, message, editedMessage);
|
||
if (messageActivityTimestamp(editedMessage) >= Number(conversation.updatedAt || 0)) {
|
||
conversation.subtitle = editedMessage.text;
|
||
conversation.updatedAt = messageActivityTimestamp(editedMessage);
|
||
writeLocalConversations(this.conversations);
|
||
}
|
||
this.cancelEditMessage();
|
||
this.setActionNotice('已编辑');
|
||
} catch (error) {
|
||
this.setActionError(error.message || '编辑失败');
|
||
}
|
||
},
|
||
async completeForward(targetConversationId) {
|
||
const target = this.conversations.find(conversation => conversation.id === targetConversationId);
|
||
if (!target || !this.forwardingMessages.length) {
|
||
return;
|
||
}
|
||
try {
|
||
for (const message of this.forwardingMessages) {
|
||
if (message.attachment?.url) {
|
||
const response = await fetch((0,_services_mediaProxy__WEBPACK_IMPORTED_MODULE_24__/* .imageDisplayUrl */ .B)(message.attachment.url));
|
||
if (!response.ok) throw new Error('图片读取失败');
|
||
const blob = await response.blob();
|
||
const type = message.attachment.type || message.type || 'file';
|
||
const file = new File([blob], message.attachment.name || (type === 'image' ? '转发图片.jpg' : '转发文件'), {
|
||
type: message.attachment.mime || blob.type || 'application/octet-stream'
|
||
});
|
||
const sent = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.sendAttachmentMessage(target, {
|
||
type,
|
||
file,
|
||
text: message.text || ''
|
||
});
|
||
if (sent?.status === 'failed') throw new Error(sent.error || '转发失败');
|
||
} else if (message.text) {
|
||
await this.sendTextToConversation(target, message.text);
|
||
}
|
||
}
|
||
this.forwardingMessages = [];
|
||
this.clearSelection();
|
||
this.setActionNotice('已转发');
|
||
} catch (error) {
|
||
this.setActionError(error.message || '转发失败');
|
||
}
|
||
},
|
||
async recallMessage(message) {
|
||
const conversation = this.activeConversation;
|
||
if (!conversation) {
|
||
return;
|
||
}
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.recallMessage(conversation, message);
|
||
if (message.direction !== 'out') {
|
||
this.removeMessages(conversation.id, [message]);
|
||
this.setActionNotice('已撤回');
|
||
this.syncActiveMessages();
|
||
return;
|
||
}
|
||
this.replaceLocalMessage(conversation.id, message, {
|
||
status: 'recalled',
|
||
deliveryStatus: '',
|
||
recalled: true,
|
||
recallStatus: '已撤回'
|
||
});
|
||
this.setActionNotice('已撤回');
|
||
} catch (error) {
|
||
this.setActionError(error.message || '撤回失败');
|
||
}
|
||
},
|
||
async createGroup(options = {}) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
if (!session.userId) {
|
||
this.setActionError('请先登录');
|
||
return false;
|
||
}
|
||
try {
|
||
const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.createGroup(session.userId, options);
|
||
this.upsertConversation(conversation);
|
||
this.setActiveConversation(conversation.id);
|
||
this.setActionNotice(options.channel ? '公告群已创建' : '群组已创建');
|
||
this.refreshRemoteConversations();
|
||
return true;
|
||
} catch (error) {
|
||
this.setActionError(error.message || (options.channel ? '创建公告群失败' : '创建群组失败'));
|
||
return false;
|
||
}
|
||
},
|
||
async joinGroup(groupKey) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
if (!session.userId) {
|
||
this.setActionError('请先登录');
|
||
return false;
|
||
}
|
||
try {
|
||
const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.joinGroup(session.userId, groupKey);
|
||
this.upsertConversation(conversation);
|
||
this.setActiveConversation(conversation.id);
|
||
this.setActionNotice('已加入群组');
|
||
this.refreshRemoteConversations();
|
||
return true;
|
||
} catch (error) {
|
||
this.setActionError(error.message || '加入群组失败');
|
||
return false;
|
||
}
|
||
},
|
||
async broadcastMessage(targetIds, text) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
if (!session.userId) {
|
||
this.setActionError('请先登录');
|
||
return false;
|
||
}
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.broadcastMessage(session.userId, targetIds, text);
|
||
const successCount = Number(result.successCount || 0);
|
||
const failedCount = Number(result.failedCount || 0);
|
||
this.setActionNotice(failedCount > 0 ? `已群发 ${successCount} 条,失败 ${failedCount} 条` : `已群发 ${successCount} 条`);
|
||
this.refreshRemoteConversations();
|
||
return true;
|
||
} catch (error) {
|
||
this.setActionError(error.message || '群发失败');
|
||
return false;
|
||
}
|
||
},
|
||
async leaveGroup(conversation) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
if (!session.userId || !conversation?.target) {
|
||
this.setActionError('缺少群组信息');
|
||
return false;
|
||
}
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.leaveGroup(session.userId, conversation.target);
|
||
this.removeConversation(conversation.id);
|
||
this.setActionNotice('已退出群组');
|
||
this.refreshRemoteConversations();
|
||
return true;
|
||
} catch (error) {
|
||
this.setActionError(error.message || '退出群组失败');
|
||
return false;
|
||
}
|
||
},
|
||
async dismissGroup(conversation) {
|
||
const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__/* .useSessionStore */ .B)();
|
||
if (!session.userId || !conversation?.target) {
|
||
this.setActionError('缺少群组信息');
|
||
return false;
|
||
}
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_20__/* .imClient */ .wD.dismissGroup(session.userId, conversation.target);
|
||
this.removeConversation(conversation.id);
|
||
this.setActionNotice('群组已解散');
|
||
this.refreshRemoteConversations();
|
||
return true;
|
||
} catch (error) {
|
||
this.setActionError(error.message || '解散群组失败');
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "w", 0, /* binding */ useConversationStore
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1414:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2261);
|
||
|
||
const useNavigationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_0__/* .defineStore */ .nY)('navigation', {
|
||
state: () => ({
|
||
section: 'messages'
|
||
}),
|
||
actions: {
|
||
showMessages() {
|
||
this.section = 'messages';
|
||
},
|
||
showContacts() {
|
||
this.section = 'contacts';
|
||
},
|
||
showFavorites() {
|
||
this.section = 'favorites';
|
||
}
|
||
}
|
||
});
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "l", 0, /* binding */ useNavigationStore
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 926:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4423);
|
||
/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__);
|
||
/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2261);
|
||
/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5051);
|
||
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2169);
|
||
|
||
|
||
|
||
|
||
const STORAGE_KEY = 'qmt-web-im-session';
|
||
function normalizeStoredPortrait(portrait) {
|
||
return portrait || '';
|
||
}
|
||
function nextProfilePortrait(profilePortrait, currentPortrait) {
|
||
return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);
|
||
}
|
||
function inferAccountType(account) {
|
||
return String(account || '').includes('@') ? 2 : 1;
|
||
}
|
||
const useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_1__/* .defineStore */ .nY)('session', {
|
||
state: () => ({
|
||
isAuthenticated: false,
|
||
connecting: false,
|
||
connected: false,
|
||
connectionStatusText: '未连接',
|
||
userId: '',
|
||
token: '',
|
||
displayName: '',
|
||
portrait: '',
|
||
error: '',
|
||
sdkVersion: '',
|
||
eventsBound: false
|
||
}),
|
||
actions: {
|
||
restore() {
|
||
const raw = localStorage.getItem(STORAGE_KEY);
|
||
if (!raw) {
|
||
return;
|
||
}
|
||
try {
|
||
const session = JSON.parse(raw);
|
||
if (session.appServer !== _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
return;
|
||
}
|
||
if (session.userId && session.token) {
|
||
if (!session.clientId) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
return;
|
||
}
|
||
this.userId = session.userId;
|
||
this.token = session.token;
|
||
this.displayName = session.displayName || session.userId;
|
||
this.portrait = normalizeStoredPortrait(session.portrait);
|
||
this.isAuthenticated = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.restoreClientId(session.clientId);
|
||
this.connect();
|
||
this.refreshProfile();
|
||
}
|
||
} catch (error) {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
}
|
||
},
|
||
async loginWithPassword(account, password, type = inferAccountType(account)) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithPassword(account, password, type);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async loginWithCode(account, code) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.loginWithCode(account, code);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async completePcSessionLogin(result) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
} catch (error) {
|
||
this.error = error.message || '扫码登录失败';
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
async register(payload) {
|
||
this.error = '';
|
||
this.connecting = true;
|
||
try {
|
||
const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.register(payload);
|
||
this.applyLoginResult(result);
|
||
await this.connect();
|
||
return result;
|
||
} catch (error) {
|
||
this.error = error.message || '注册失败';
|
||
return null;
|
||
} finally {
|
||
this.connecting = false;
|
||
}
|
||
},
|
||
applyLoginResult(result) {
|
||
this.userId = result.userId || result.uid || result.id || '';
|
||
this.token = result.token || result.imToken || '';
|
||
this.displayName = result.displayName || result.userName || result.name || this.userId;
|
||
this.portrait = normalizeStoredPortrait(result.portrait);
|
||
this.isAuthenticated = Boolean(this.userId && this.token);
|
||
this.persistSession();
|
||
},
|
||
persistSession() {
|
||
localStorage.setItem(STORAGE_KEY, JSON.stringify({
|
||
userId: this.userId,
|
||
token: this.token,
|
||
displayName: this.displayName,
|
||
portrait: this.portrait,
|
||
clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getClientId(),
|
||
appServer: _config__WEBPACK_IMPORTED_MODULE_3__/* .appConfig */ .U.appServer
|
||
}));
|
||
},
|
||
applyProfile(profile) {
|
||
if (!profile) {
|
||
return;
|
||
}
|
||
this.userId = profile.userId || profile.uid || this.userId;
|
||
this.displayName = profile.displayName || profile.name || this.displayName || this.userId;
|
||
this.portrait = nextProfilePortrait(profile.portrait, this.portrait);
|
||
this.persistSession();
|
||
},
|
||
async refreshProfile() {
|
||
if (!this.userId) {
|
||
return null;
|
||
}
|
||
try {
|
||
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getProfile(this.userId);
|
||
this.applyProfile(profile);
|
||
return profile;
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
},
|
||
async saveProfile({
|
||
displayName,
|
||
portraitFile
|
||
}) {
|
||
if (!this.userId) {
|
||
throw new Error('请先登录');
|
||
}
|
||
const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.updateProfile(this.userId, {
|
||
displayName,
|
||
portraitFile
|
||
});
|
||
this.applyProfile(profile);
|
||
return profile;
|
||
},
|
||
async changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
}) {
|
||
if (!this.userId) {
|
||
throw new Error('请先登录');
|
||
}
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.changePassword({
|
||
oldPassword,
|
||
newPassword
|
||
});
|
||
await this.logout();
|
||
return true;
|
||
},
|
||
async resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
}) {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.resetPasswordWithCode({
|
||
mobile,
|
||
resetCode,
|
||
newPassword
|
||
});
|
||
return true;
|
||
},
|
||
async connect() {
|
||
if (!this.userId || !this.token) {
|
||
return;
|
||
}
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.ensureSdk();
|
||
this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.getSdkVersion();
|
||
this.bindImEvents();
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.connect(this.userId, this.token);
|
||
},
|
||
bindImEvents() {
|
||
if (this.eventsBound) {
|
||
return;
|
||
}
|
||
this.eventsBound = true;
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.on('connectionStatusChanged', status => {
|
||
this.connected = status.connected;
|
||
this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');
|
||
});
|
||
},
|
||
async logout() {
|
||
try {
|
||
await _services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.logout?.();
|
||
} catch (error) {
|
||
this.error = error.message || '退出登录失败';
|
||
} finally {
|
||
_services_imClient__WEBPACK_IMPORTED_MODULE_2__/* .imClient */ .wD.disconnect();
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
this.$reset();
|
||
}
|
||
}
|
||
}
|
||
});
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, [
|
||
/* harmony export */ "B", 0, /* binding */ useSessionStore
|
||
/* harmony export */ ]);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7067:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4208);
|
||
|
||
|
||
|
||
const __exports__ = _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9531:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6736);
|
||
|
||
|
||
|
||
const __exports__ = _ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3727:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4524);
|
||
|
||
|
||
|
||
const __exports__ = _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 7014:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9843);
|
||
|
||
|
||
|
||
const __exports__ = _ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1653:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5990);
|
||
|
||
|
||
|
||
const __exports__ = _MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9847:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3172);
|
||
|
||
|
||
|
||
const __exports__ = _MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3351:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9828);
|
||
|
||
|
||
|
||
const __exports__ = _ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 163:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1880);
|
||
|
||
|
||
|
||
const __exports__ = _FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9123:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8040);
|
||
|
||
|
||
|
||
const __exports__ = _FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 578:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(103);
|
||
|
||
|
||
|
||
const __exports__ = _ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 371:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5896);
|
||
|
||
|
||
|
||
const __exports__ = _ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 8328:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony import */ var _NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1169);
|
||
|
||
|
||
|
||
const __exports__ = _NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A;
|
||
|
||
/* harmony default export */ __webpack_exports__.A = (__exports__);
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4208:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4677);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 6736:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2511);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 4524:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8607);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9843:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7562);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5990:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6935);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3172:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4021);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 9828:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3915);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1880:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9829);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 8040:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6415);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 103:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5684);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 5896:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4621);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1169:
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||
/* harmony export */ A: function() { return /* reexport safe */ _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__.A; }
|
||
/* harmony export */ });
|
||
/* harmony import */ var _node_modules_thread_loader_dist_cjs_js_node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_1_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7420);
|
||
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
/************************************************************************/
|
||
/******/ // The module cache
|
||
/******/ var __webpack_module_cache__ = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/ // Check if module is in cache
|
||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||
/******/ if (cachedModule !== undefined) {
|
||
/******/ return cachedModule.exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
/******/ // no module.id needed
|
||
/******/ // no module.loaded needed
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = __webpack_modules__;
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ /* webpack/runtime/chunk loaded */
|
||
/******/ !function() {
|
||
/******/ var deferred = [];
|
||
/******/ __webpack_require__.O = function(result, chunkIds, fn, priority) {
|
||
/******/ if(chunkIds) {
|
||
/******/ priority = priority || 0;
|
||
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
|
||
/******/ deferred[i] = [chunkIds, fn, priority];
|
||
/******/ return;
|
||
/******/ }
|
||
/******/ var notFulfilled = Infinity;
|
||
/******/ for (var i = 0; i < deferred.length; i++) {
|
||
/******/ var chunkIds = deferred[i][0];
|
||
/******/ var fn = deferred[i][1];
|
||
/******/ var priority = deferred[i][2];
|
||
/******/ var fulfilled = true;
|
||
/******/ for (var j = 0; j < chunkIds.length; j++) {
|
||
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {
|
||
/******/ chunkIds.splice(j--, 1);
|
||
/******/ } else {
|
||
/******/ fulfilled = false;
|
||
/******/ if(priority < notFulfilled) notFulfilled = priority;
|
||
/******/ }
|
||
/******/ }
|
||
/******/ if(fulfilled) {
|
||
/******/ deferred.splice(i--, 1)
|
||
/******/ var r = fn();
|
||
/******/ if (r !== undefined) result = r;
|
||
/******/ }
|
||
/******/ }
|
||
/******/ return result;
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/compat get default export */
|
||
/******/ !function() {
|
||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||
/******/ __webpack_require__.n = function(module) {
|
||
/******/ var getter = module && module.__esModule ?
|
||
/******/ function() { return module['default']; } :
|
||
/******/ function() { return module; };
|
||
/******/ __webpack_require__.d(getter, { a: getter });
|
||
/******/ return getter;
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/define property getters */
|
||
/******/ !function() {
|
||
/******/ // define getter/value functions for harmony exports
|
||
/******/ __webpack_require__.d = function(exports, definition) {
|
||
/******/ if(Array.isArray(definition)) {
|
||
/******/ var i = 0;
|
||
/******/ while(i < definition.length) {
|
||
/******/ var key = definition[i++];
|
||
/******/ var binding = definition[i++];
|
||
/******/ if(!__webpack_require__.o(exports, key)) {
|
||
/******/ if(binding === 0) {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
|
||
/******/ } else {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
|
||
/******/ }
|
||
/******/ } else if(binding === 0) { i++; }
|
||
/******/ }
|
||
/******/ } else {
|
||
/******/ for(var key in definition) {
|
||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||
/******/ }
|
||
/******/ }
|
||
/******/ }
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/global */
|
||
/******/ !function() {
|
||
/******/ __webpack_require__.g = (function() {
|
||
/******/ if (typeof globalThis === 'object') return globalThis;
|
||
/******/ try {
|
||
/******/ return this || new Function('return this')();
|
||
/******/ } catch (e) {
|
||
/******/ if (typeof window === 'object') return window;
|
||
/******/ }
|
||
/******/ })();
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||
/******/ !function() {
|
||
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/make namespace object */
|
||
/******/ !function() {
|
||
/******/ // define __esModule on exports
|
||
/******/ __webpack_require__.r = function(exports) {
|
||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||
/******/ }
|
||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/set anonymous default export name */
|
||
/******/ !function() {
|
||
/******/ // set .name for anonymous default exports per ES spec
|
||
/******/ __webpack_require__.dn = function(x) {
|
||
/******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
|
||
/******/ };
|
||
/******/ }();
|
||
/******/
|
||
/******/ /* webpack/runtime/jsonp chunk loading */
|
||
/******/ !function() {
|
||
/******/ // no baseURI
|
||
/******/
|
||
/******/ // object to store loaded and loading chunks
|
||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
||
/******/ var installedChunks = {
|
||
/******/ 524: 0
|
||
/******/ };
|
||
/******/
|
||
/******/ // no chunk on demand loading
|
||
/******/
|
||
/******/ // no prefetching
|
||
/******/
|
||
/******/ // no preloaded
|
||
/******/
|
||
/******/ // no HMR
|
||
/******/
|
||
/******/ // no HMR manifest
|
||
/******/
|
||
/******/ __webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };
|
||
/******/
|
||
/******/ // install a JSONP callback for chunk loading
|
||
/******/ var webpackJsonpCallback = function(parentChunkLoadingFunction, data) {
|
||
/******/ var chunkIds = data[0];
|
||
/******/ var moreModules = data[1];
|
||
/******/ var runtime = data[2];
|
||
/******/ // add "moreModules" to the modules object,
|
||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||
/******/ var moduleId, chunkId, i = 0;
|
||
/******/ if(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {
|
||
/******/ for(moduleId in moreModules) {
|
||
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
||
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
||
/******/ }
|
||
/******/ }
|
||
/******/ if(runtime) var result = runtime(__webpack_require__);
|
||
/******/ }
|
||
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
||
/******/ for(;i < chunkIds.length; i++) {
|
||
/******/ chunkId = chunkIds[i];
|
||
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
||
/******/ installedChunks[chunkId][0]();
|
||
/******/ }
|
||
/******/ installedChunks[chunkId] = 0;
|
||
/******/ }
|
||
/******/ return __webpack_require__.O(result);
|
||
/******/ }
|
||
/******/
|
||
/******/ var chunkLoadingGlobal = self["webpackChunkjc_web_im"] = self["webpackChunkjc_web_im"] || [];
|
||
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
||
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
||
/******/ }();
|
||
/******/
|
||
/************************************************************************/
|
||
/******/
|
||
/******/ // startup
|
||
/******/ // Load entry module and return exports
|
||
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
||
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(1406); })
|
||
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
||
/******/
|
||
/******/ })()
|
||
;
|
||
//# sourceMappingURL=app.1158390e.js.map
|