1045 lines
667 KiB
JavaScript
1045 lines
667 KiB
JavaScript
/*
|
||
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
||
* This devtool is neither made for production nor for readable output files.
|
||
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||
* or disable the default devtool with "devtool: false".
|
||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||
*/
|
||
/******/ (function() { // webpackBootstrap
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/LoginView.vue */ \"./src/components/LoginView.vue\");\n/* harmony import */ var _components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/ChatShell.vue */ \"./src/components/ChatShell.vue\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stores/session */ \"./src/stores/session.js\");\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'App',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_3__.useSessionStore)();\n (0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {\n session.restore();\n });\n const __returned__ = {\n session,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_0__.onMounted,\n LoginView: _components_LoginView_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n ChatShell: _components_ChatShell_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n get useSessionStore() {\n return _stores_session__WEBPACK_IMPORTED_MODULE_3__.useSessionStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/App.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js":
|
||
/*!******************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js ***!
|
||
\******************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sidebar/NavigationRail.vue */ \"./src/components/sidebar/NavigationRail.vue\");\n/* harmony import */ var _sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sidebar/ConversationList.vue */ \"./src/components/sidebar/ConversationList.vue\");\n/* harmony import */ var _sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sidebar/ContactList.vue */ \"./src/components/sidebar/ContactList.vue\");\n/* harmony import */ var _chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./chat/ChatPanel.vue */ \"./src/components/chat/ChatPanel.vue\");\n/* harmony import */ var _contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./contacts/ContactPanel.vue */ \"./src/components/contacts/ContactPanel.vue\");\n/* harmony import */ var _favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./favorites/FavoriteList.vue */ \"./src/components/favorites/FavoriteList.vue\");\n/* harmony import */ var _favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./favorites/FavoritePanel.vue */ \"./src/components/favorites/FavoritePanel.vue\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/stores/navigation */ \"./src/stores/navigation.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'ChatShell',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_8__.useConversationStore)();\n const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_9__.useNavigationStore)();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_10__.useContactStore)();\n (0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {\n conversations.refreshRemoteConversations();\n contacts.refreshContacts();\n });\n const __returned__ = {\n conversations,\n navigation,\n contacts,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_0__.onMounted,\n NavigationRail: _sidebar_NavigationRail_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n ConversationList: _sidebar_ConversationList_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n ContactList: _sidebar_ContactList_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"],\n ChatPanel: _chat_ChatPanel_vue__WEBPACK_IMPORTED_MODULE_4__[\"default\"],\n ContactPanel: _contacts_ContactPanel_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n FavoriteList: _favorites_FavoriteList_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"],\n FavoritePanel: _favorites_FavoritePanel_vue__WEBPACK_IMPORTED_MODULE_7__[\"default\"],\n get useConversationStore() {\n return _stores_conversations__WEBPACK_IMPORTED_MODULE_8__.useConversationStore;\n },\n get useNavigationStore() {\n return _stores_navigation__WEBPACK_IMPORTED_MODULE_9__.useNavigationStore;\n },\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_10__.useContactStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/ChatShell.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=script&setup=true&lang=js":
|
||
/*!******************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=script&setup=true&lang=js ***!
|
||
\******************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jr-qrcode */ \"./node_modules/jr-qrcode/dist/jr-qrcode.js\");\n/* harmony import */ var jr_qrcode__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jr_qrcode__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/stores/session */ \"./src/stores/session.js\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n\n\n\n\n\n\n\nconst QR_CODE_PREFIX_PC_SESSION = 'wildfirechat://pcsession/';\nconst defaultPlatformLogo = '/favicon.ico';\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'LoginView',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_5__.useSessionStore)();\n const view = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('login');\n const loginMode = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('phone');\n const loginAccount = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const loginPassword = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const registerType = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)(1);\n const registerForm = (0,vue__WEBPACK_IMPORTED_MODULE_3__.reactive)({\n number: '',\n code: '',\n password: '',\n confirmPassword: '',\n invitationCode: ''\n });\n const sendingCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)(false);\n const info = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const qrStatus = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('idle');\n const qrCodeImage = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const qrSessionToken = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const qrUserName = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const qrUserPortrait = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n let qrGeneration = 0;\n let qrExpireTimer = null;\n const defaultPlatformName = _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.appName;\n const platformName = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)(defaultPlatformName);\n const platformLogo = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)(defaultPlatformLogo);\n const canSubmitLogin = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => loginAccount.value.length >= 3 && loginPassword.value.length >= 1);\n const canRequestEmailCode = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => registerType.value === 2 && /\\S+@\\S+\\.\\S+/.test(registerForm.number));\n const canSubmitRegister = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => {\n if (registerForm.password.length < 1 || registerForm.password !== registerForm.confirmPassword) {\n return false;\n }\n if (registerType.value === 2) {\n return canRequestEmailCode.value && registerForm.code.length >= 1;\n }\n return registerForm.number.length >= 5;\n });\n const qrUserInitial = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => String(qrUserName.value || 'U').slice(0, 1).toUpperCase());\n const qrStatusTitle = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => {\n if (session.connecting || qrStatus.value === 'confirmed') {\n return '正在进入';\n }\n if (qrStatus.value === 'loading') {\n return '正在生成二维码';\n }\n if (qrStatus.value === 'scanned') {\n return qrUserName.value ? `${qrUserName.value} 已扫码` : '已扫码,待确认';\n }\n if (qrStatus.value === 'expired') {\n return '二维码已过期';\n }\n if (qrStatus.value === 'error') {\n return '二维码加载失败';\n }\n return '扫码登录';\n });\n const qrStatusText = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => {\n if (session.connecting || qrStatus.value === 'confirmed') {\n return '登录信息已确认,正在建立连接';\n }\n if (qrStatus.value === 'loading') {\n return '正在创建扫码登录会话';\n }\n if (qrStatus.value === 'scanned') {\n return '请在手机 App 上确认登录';\n }\n if (qrStatus.value === 'expired') {\n return '请刷新二维码后重新扫码';\n }\n if (qrStatus.value === 'error') {\n return '请稍后重试';\n }\n return '使用已登录的手机 App 扫描二维码';\n });\n const qrRefreshText = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => {\n if (qrStatus.value === 'loading') {\n return '生成中...';\n }\n if (qrStatus.value === 'expired' || qrStatus.value === 'error') {\n return '重新生成二维码';\n }\n return '刷新二维码';\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_3__.onMounted)(() => {\n loadPlatformConfig();\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_3__.onBeforeUnmount)(() => {\n stopQrLogin();\n });\n function clearFormMessage() {\n session.error = '';\n info.value = '';\n }\n function setLoginMode(mode) {\n loginMode.value = mode;\n loginAccount.value = '';\n loginPassword.value = '';\n clearFormMessage();\n if (mode === 'qr') {\n startQrLogin();\n return;\n }\n stopQrLogin();\n }\n async function submitLogin() {\n clearFormMessage();\n const type = loginMode.value === 'email' ? 2 : 1;\n await session.loginWithPassword(loginAccount.value, loginPassword.value, type);\n }\n function switchRegisterType(type) {\n registerType.value = type;\n registerForm.number = '';\n registerForm.code = '';\n registerForm.password = '';\n registerForm.confirmPassword = '';\n registerForm.invitationCode = '';\n clearFormMessage();\n }\n async function requestEmailCode() {\n clearFormMessage();\n sendingCode.value = true;\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_6__.imClient.requestAuthCode(registerForm.number);\n info.value = '邮箱验证码已发送,请在当前注册表单中填写后继续。';\n } catch (error) {\n session.error = error.message || '验证码发送失败';\n } finally {\n sendingCode.value = false;\n }\n }\n async function submitRegister() {\n clearFormMessage();\n if (registerForm.password !== registerForm.confirmPassword) {\n session.error = '两次输入的密码不一致';\n return;\n }\n const result = await session.register({\n type: registerType.value,\n number: registerForm.number,\n code: registerType.value === 2 ? registerForm.code : '',\n password: registerForm.password,\n invitationCode: registerForm.invitationCode\n });\n if (result) {\n info.value = '注册成功,正在进入系统。';\n }\n }\n function openRegister() {\n clearFormMessage();\n stopQrLogin();\n view.value = 'register';\n }\n function backToLogin() {\n clearFormMessage();\n loginMode.value = 'phone';\n stopQrLogin();\n view.value = 'login';\n }\n function resetQrState() {\n qrStatus.value = 'idle';\n qrCodeImage.value = '';\n qrSessionToken.value = '';\n qrUserName.value = '';\n qrUserPortrait.value = '';\n }\n function clearQrExpireTimer() {\n if (qrExpireTimer) {\n window.clearTimeout(qrExpireTimer);\n qrExpireTimer = null;\n }\n }\n function stopQrLogin() {\n qrGeneration += 1;\n clearQrExpireTimer();\n resetQrState();\n }\n function refreshQrLogin() {\n startQrLogin(true);\n }\n async function startQrLogin(force = false) {\n if (loginMode.value !== 'qr') {\n return;\n }\n if (!force && qrSessionToken.value && qrCodeImage.value && !['expired', 'error'].includes(qrStatus.value)) {\n return;\n }\n qrGeneration += 1;\n const generation = qrGeneration;\n clearQrExpireTimer();\n clearFormMessage();\n qrStatus.value = 'loading';\n qrCodeImage.value = '';\n qrSessionToken.value = '';\n qrUserName.value = '';\n qrUserPortrait.value = '';\n try {\n const pcSession = await _services_imClient__WEBPACK_IMPORTED_MODULE_6__.imClient.createPcSession();\n if (generation !== qrGeneration || loginMode.value !== 'qr') {\n return;\n }\n const token = String(pcSession.token || '');\n if (!token) {\n throw new Error('服务端没有返回扫码 token');\n }\n qrSessionToken.value = token;\n qrCodeImage.value = jr_qrcode__WEBPACK_IMPORTED_MODULE_2___default().getQrBase64(QR_CODE_PREFIX_PC_SESSION + token);\n qrStatus.value = 'waiting';\n const expireMs = Math.max(30000, Math.min(Number(pcSession.expired || 300000), 300000));\n qrExpireTimer = window.setTimeout(() => {\n if (generation === qrGeneration && qrStatus.value !== 'confirmed' && !session.isAuthenticated) {\n qrStatus.value = 'expired';\n }\n }, expireMs);\n pollQrLogin(generation, token);\n } catch (error) {\n if (generation !== qrGeneration) {\n return;\n }\n qrStatus.value = 'error';\n session.error = error.message || '二维码加载失败';\n }\n }\n async function pollQrLogin(generation, token) {\n try {\n while (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {\n const payload = await _services_imClient__WEBPACK_IMPORTED_MODULE_6__.imClient.loginWithPcSession(token);\n if (generation !== qrGeneration || loginMode.value !== 'qr') {\n return;\n }\n const code = Number(payload.code);\n const data = payload.data || payload.result || {};\n const status = Number(data.status);\n if (code === 0 && data.imToken) {\n qrStatus.value = 'confirmed';\n clearQrExpireTimer();\n await session.completePcSessionLogin(data);\n return;\n }\n if (code === 20042 || status === 1 || status === 3) {\n qrStatus.value = 'scanned';\n qrUserName.value = data.userName || data.displayName || qrUserName.value;\n qrUserPortrait.value = data.portrait || qrUserPortrait.value;\n await delay(1000);\n continue;\n }\n if (status === 0 || code === 13) {\n qrStatus.value = 'waiting';\n await delay(1000);\n continue;\n }\n if (status === 4) {\n qrStatus.value = 'expired';\n session.error = payload.message || '扫码登录已取消';\n return;\n }\n if (payload.message) {\n throw new Error(payload.message);\n }\n await delay(1000);\n }\n } catch (error) {\n if (generation === qrGeneration && loginMode.value === 'qr' && !session.isAuthenticated) {\n qrStatus.value = 'error';\n session.error = error.message || '扫码登录失败';\n }\n }\n }\n function delay(ms) {\n return new Promise(resolve => window.setTimeout(resolve, ms));\n }\n async function loadPlatformConfig() {\n try {\n const response = await axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"].get(_config__WEBPACK_IMPORTED_MODULE_4__.appConfig.platformConfigApi, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '平台配置加载失败');\n }\n const config = response.data?.result || {};\n const name = String(config.platformName || '').trim();\n const logo = String(config.logoUrl || config.logo || '').trim();\n const version = String(config.version || '').trim();\n platformName.value = name || defaultPlatformName;\n platformLogo.value = resolveBrandLogo(logo, version);\n } catch (error) {\n platformName.value = defaultPlatformName;\n platformLogo.value = defaultPlatformLogo;\n }\n applyDocumentBrand();\n }\n function resolveBrandLogo(value, version = '') {\n const logo = String(value || '').trim();\n if (!logo) {\n return defaultPlatformLogo;\n }\n if (/^(https?:|data:|blob:)/i.test(logo)) {\n return appendBrandVersion(logo, version);\n }\n if (logo.startsWith('//')) {\n return appendBrandVersion(`${window.location.protocol}${logo}`, version);\n }\n const base = logo.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.adminServer : `${_config__WEBPACK_IMPORTED_MODULE_4__.appConfig.adminServer}/`;\n return appendBrandVersion(new URL(logo, base).toString(), version);\n }\n function appendBrandVersion(url, version) {\n if (!version || /^(data:|blob:)/i.test(url)) {\n return url;\n }\n const parsed = new URL(url, window.location.href);\n parsed.searchParams.set('v', version);\n return parsed.toString();\n }\n function applyDocumentBrand() {\n if (typeof document === 'undefined') {\n return;\n }\n document.title = platformName.value || defaultPlatformName;\n let icon = document.querySelector('link[rel=\"icon\"]');\n if (!icon) {\n icon = document.createElement('link');\n icon.setAttribute('rel', 'icon');\n document.head.appendChild(icon);\n }\n icon.setAttribute('href', platformLogo.value || defaultPlatformLogo);\n }\n function handleBrandLogoError() {\n if (platformLogo.value !== defaultPlatformLogo) {\n platformLogo.value = defaultPlatformLogo;\n applyDocumentBrand();\n }\n }\n const __returned__ = {\n session,\n view,\n loginMode,\n loginAccount,\n loginPassword,\n registerType,\n registerForm,\n sendingCode,\n info,\n QR_CODE_PREFIX_PC_SESSION,\n qrStatus,\n qrCodeImage,\n qrSessionToken,\n qrUserName,\n qrUserPortrait,\n get qrGeneration() {\n return qrGeneration;\n },\n set qrGeneration(v) {\n qrGeneration = v;\n },\n get qrExpireTimer() {\n return qrExpireTimer;\n },\n set qrExpireTimer(v) {\n qrExpireTimer = v;\n },\n defaultPlatformName,\n defaultPlatformLogo,\n platformName,\n platformLogo,\n canSubmitLogin,\n canRequestEmailCode,\n canSubmitRegister,\n qrUserInitial,\n qrStatusTitle,\n qrStatusText,\n qrRefreshText,\n clearFormMessage,\n setLoginMode,\n submitLogin,\n switchRegisterType,\n requestEmailCode,\n submitRegister,\n openRegister,\n backToLogin,\n resetQrState,\n clearQrExpireTimer,\n stopQrLogin,\n refreshQrLogin,\n startQrLogin,\n pollQrLogin,\n delay,\n loadPlatformConfig,\n resolveBrandLogo,\n appendBrandVersion,\n applyDocumentBrand,\n handleBrandLogoError,\n get axios() {\n return axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n },\n get jrQRCode() {\n return (jr_qrcode__WEBPACK_IMPORTED_MODULE_2___default());\n },\n computed: vue__WEBPACK_IMPORTED_MODULE_3__.computed,\n onBeforeUnmount: vue__WEBPACK_IMPORTED_MODULE_3__.onBeforeUnmount,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_3__.onMounted,\n reactive: vue__WEBPACK_IMPORTED_MODULE_3__.reactive,\n ref: vue__WEBPACK_IMPORTED_MODULE_3__.ref,\n get appConfig() {\n return _config__WEBPACK_IMPORTED_MODULE_4__.appConfig;\n },\n get useSessionStore() {\n return _stores_session__WEBPACK_IMPORTED_MODULE_5__.useSessionStore;\n },\n get imClient() {\n return _services_imClient__WEBPACK_IMPORTED_MODULE_6__.imClient;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/LoginView.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!***********************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\***********************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.set.difference.v2.js */ \"./node_modules/core-js/modules/es.set.difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.set.intersection.v2.js */ \"./node_modules/core-js/modules/es.set.intersection.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.set.is-disjoint-from.v2.js */ \"./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.set.is-subset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-subset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.set.is-superset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-superset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/es.set.symmetric-difference.v2.js */ \"./node_modules/core-js/modules/es.set.symmetric-difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! core-js/modules/es.set.union.v2.js */ \"./node_modules/core-js/modules/es.set.union.v2.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _MessageList_vue__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MessageList.vue */ \"./src/components/chat/MessageList.vue\");\n/* harmony import */ var _MessageComposer_vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MessageComposer.vue */ \"./src/components/chat/MessageComposer.vue\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @/stores/session */ \"./src/stores/session.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'ChatPanel',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_16__.useConversationStore)();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_17__.useContactStore)();\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_18__.useSessionStore)();\n const activeConversation = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => conversations.activeConversation);\n const groupMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);\n const singleProfileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);\n const singleAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const singleProfileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);\n const singleProfileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const singleProfileError = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const groupPanel = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const groupBusy = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);\n const groupDetail = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);\n const groupMembers = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)([]);\n const groupAliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const manageSection = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const selectedAdminIds = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)([]);\n const selectedKickIds = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)([]);\n const transferTargetId = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)({\n name: '',\n announcement: '',\n welcomeText: ''\n });\n const muteDraft = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)({\n mode: 'off',\n scheduleType: 'once',\n startsAtLocal: '',\n endsAtLocal: '',\n dailyStart: '09:00',\n dailyEnd: '18:00'\n });\n const muteSaveNotice = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const muteSaveError = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('');\n const singlePeerId = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n if (!activeConversation.value || isGroupConversation.value) {\n return '';\n }\n return String(activeConversation.value.target || activeConversation.value.raw?.target || activeConversation.value.id?.replace(/^single-/, '') || '');\n });\n const singleContact = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n const peerId = singlePeerId.value;\n if (!peerId) {\n return null;\n }\n return contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || null;\n });\n const singleProfile = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n const contact = singleContact.value;\n const conversation = activeConversation.value || {};\n const rawUser = contact?.rawUser || {};\n const displayName = contact?.alias || rawUser.displayName || rawUser.name || contact?.title || conversation.title || singlePeerId.value || '未知用户';\n const rawName = rawUser.displayName || rawUser.name || contact?.title || conversation.title || '';\n return {\n uid: singlePeerId.value,\n displayName,\n rawName,\n mobile: rawUser.mobile || conversation.raw?.mobile || '',\n address: rawUser.address || conversation.raw?.address || '',\n portrait: contact?.portrait || conversation.portrait || '',\n avatarText: String(displayName || '?').slice(0, 1).toUpperCase(),\n alias: contact?.alias || ''\n };\n });\n const isGroupConversation = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n return ['group', 'channel'].includes(activeConversation.value?.type) || activeConversation.value?.raw?.type === 'group';\n });\n const currentGroupRole = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n return groupDetail.value?.myRole || activeConversation.value?.role || activeConversation.value?.raw?.role || '';\n });\n const isGroupOwner = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => currentGroupRole.value === 'owner');\n const canManageGroup = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => ['owner', 'admin'].includes(currentGroupRole.value));\n const adminCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => groupMembers.value.filter(member => member.role !== 'owner'));\n const transferableMembers = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => groupMembers.value.filter(member => member.role !== 'owner'));\n const messageDetail = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => conversations.messageDetail || null);\n const messageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => messageDetail.value?.group || null);\n const isMessageDetailGroup = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n return messageDetail.value?.conversationType === 'group' || Boolean(messageDetail.value?.group);\n });\n const messageDetailCounts = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n return messageDetailGroup.value?.counts || {\n read: 0,\n unread: 0,\n undelivered: 0,\n total: 0\n };\n });\n const kickCandidateMembers = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n return groupMembers.value.filter(member => {\n if (member.uid === session.userId || member.role === 'owner') {\n return false;\n }\n if (currentGroupRole.value === 'admin') {\n return member.role === 'member';\n }\n return currentGroupRole.value === 'owner';\n });\n });\n const statusText = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {\n if (activeConversation.value?.type === 'channel' && !conversations.canSendActiveConversation) {\n return '公告群,仅管理员可发言';\n }\n return session.connectionStatusText || (session.connected ? '已连接' : '未连接');\n });\n function formatDetailTime(value) {\n const timestamp = Number(value || 0);\n if (!timestamp) {\n return '暂无';\n }\n return new Intl.DateTimeFormat('zh-CN', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone\n }).format(timestamp);\n }\n function detailMemberName(member) {\n return member?.name || member?.displayName || member?.rawName || member?.uid || '-';\n }\n function detailMemberAvatar(member) {\n return String(detailMemberName(member) || '?').slice(0, 1).toUpperCase();\n }\n function detailRoleLabel(role) {\n if (role === 'owner') {\n return '群主';\n }\n if (role === 'admin') {\n return '管理员';\n }\n return '';\n }\n function closeGroupMenu() {\n groupMenuOpen.value = false;\n }\n function toggleGroupMenu() {\n if (!isGroupConversation.value) {\n return;\n }\n groupMenuOpen.value = !groupMenuOpen.value;\n }\n async function openSingleProfile() {\n if (!activeConversation.value || isGroupConversation.value) {\n return;\n }\n closeGroupMenu();\n singleProfileNotice.value = '';\n singleProfileError.value = '';\n singleAliasDraft.value = singleProfile.value.alias || '';\n singleProfileOpen.value = true;\n contacts.refreshContacts().then(() => {\n if (singleProfileOpen.value) {\n singleAliasDraft.value = singleProfile.value.alias || '';\n }\n }).catch(() => {});\n }\n function closeSingleProfile() {\n if (singleProfileSaving.value) {\n return;\n }\n singleProfileOpen.value = false;\n singleProfileNotice.value = '';\n singleProfileError.value = '';\n }\n async function saveSingleAlias() {\n const peerId = singleProfile.value.uid;\n if (!peerId || singleProfileSaving.value) {\n return;\n }\n singleProfileSaving.value = true;\n singleProfileNotice.value = '';\n singleProfileError.value = '';\n try {\n const ok = await contacts.updateContactAlias(peerId, singleAliasDraft.value);\n if (!ok) {\n singleProfileError.value = contacts.actionError || '备注名修改失败';\n return;\n }\n await contacts.refreshContacts({\n force: true\n }).catch(() => {});\n const refreshedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === peerId) || singleContact.value;\n const nextTitle = refreshedContact?.title || singleAliasDraft.value || singleProfile.value.rawName || singleProfile.value.displayName || peerId;\n conversations.upsertConversation({\n ...activeConversation.value,\n title: nextTitle,\n portrait: refreshedContact?.portrait || activeConversation.value?.portrait || '',\n avatarText: String(nextTitle || '?').slice(0, 1).toUpperCase(),\n raw: {\n ...(activeConversation.value?.raw || {}),\n target: peerId,\n mobile: refreshedContact?.rawUser?.mobile || activeConversation.value?.raw?.mobile || '',\n address: refreshedContact?.rawUser?.address || activeConversation.value?.raw?.address || '',\n alias: refreshedContact?.alias || singleAliasDraft.value\n }\n });\n singleAliasDraft.value = refreshedContact?.alias || singleAliasDraft.value;\n singleProfileNotice.value = '备注名已保存';\n } catch (error) {\n singleProfileError.value = error.message || '备注名修改失败';\n } finally {\n singleProfileSaving.value = false;\n }\n }\n function handleSenderProfileUpdated() {\n contacts.refreshContacts({\n force: true\n }).catch(() => {});\n conversations.syncActiveMessages({\n allowReadReceipt: true\n });\n if (groupPanel.value === 'members') {\n loadGroupMembers();\n }\n }\n function closeGroupPanel() {\n groupPanel.value = '';\n groupBusy.value = false;\n clearMuteSaveFeedback();\n }\n async function loadGroupDetail() {\n if (!session.userId || !activeConversation.value?.target) {\n return null;\n }\n groupBusy.value = true;\n try {\n groupDetail.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.getGroupDetail(session.userId, activeConversation.value.target);\n return groupDetail.value;\n } catch (error) {\n conversations.setActionError(error.message || '群资料加载失败');\n return null;\n } finally {\n groupBusy.value = false;\n }\n }\n async function openGroupOverview() {\n if (!isGroupConversation.value) {\n return;\n }\n closeGroupMenu();\n groupPanel.value = 'overview';\n await loadGroupDetail();\n }\n async function openGroupMembers() {\n closeGroupMenu();\n groupPanel.value = 'members';\n await loadGroupMembers();\n }\n async function loadGroupMembers() {\n groupBusy.value = true;\n try {\n groupMembers.value = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.getGroupMembers(session.userId, activeConversation.value.target);\n selectedAdminIds.value = groupMembers.value.filter(member => member.role === 'admin').map(member => member.uid);\n return groupMembers.value;\n } catch (error) {\n conversations.setActionError(error.message || '群员加载失败');\n return [];\n } finally {\n groupBusy.value = false;\n }\n }\n async function openGroupAlias() {\n closeGroupMenu();\n groupPanel.value = 'alias';\n const detail = await loadGroupDetail();\n groupAliasDraft.value = detail?.myAlias || '';\n }\n function msToLocalInput(value) {\n const timestamp = Number(value || 0);\n if (!timestamp) {\n return '';\n }\n const date = new Date(timestamp);\n const local = new Date(date.getTime() - date.getTimezoneOffset() * 60000);\n return local.toISOString().slice(0, 16);\n }\n function localInputToMs(value) {\n return value ? new Date(value).getTime() : 0;\n }\n function prepareManagementDrafts() {\n clearMuteSaveFeedback();\n profileDraft.value = {\n name: groupDetail.value?.name || activeConversation.value?.title || '',\n announcement: groupDetail.value?.announcement || '',\n welcomeText: groupDetail.value?.welcomeText || ''\n };\n const setting = groupDetail.value?.muteSetting || {};\n muteDraft.value = {\n mode: setting.mode || 'off',\n scheduleType: setting.scheduleType || 'once',\n startsAtLocal: msToLocalInput(setting.startsAtMs),\n endsAtLocal: msToLocalInput(setting.endsAtMs),\n dailyStart: setting.dailyStart || '09:00',\n dailyEnd: setting.dailyEnd || '18:00'\n };\n }\n function clearMuteSaveFeedback() {\n muteSaveNotice.value = '';\n muteSaveError.value = '';\n }\n async function openGroupManage() {\n if (!canManageGroup.value) {\n return;\n }\n closeGroupMenu();\n groupPanel.value = 'manage';\n manageSection.value = isGroupOwner.value ? 'admins' : 'profile';\n await loadGroupDetail();\n prepareManagementDrafts();\n await loadGroupMembers();\n }\n async function openTransferGroup() {\n groupPanel.value = 'transfer';\n transferTargetId.value = '';\n await loadGroupMembers();\n }\n async function saveGroupAlias() {\n if (!activeConversation.value?.target || groupBusy.value) {\n return;\n }\n groupBusy.value = true;\n try {\n const alias = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.updateGroupAlias(session.userId, activeConversation.value.target, groupAliasDraft.value);\n groupDetail.value = {\n ...(groupDetail.value || {}),\n myAlias: alias\n };\n conversations.setActionNotice('本群昵称已保存');\n closeGroupPanel();\n } catch (error) {\n conversations.setActionError(error.message || '本群昵称保存失败');\n } finally {\n groupBusy.value = false;\n }\n }\n function toggleAdmin(userId) {\n const selected = new Set(selectedAdminIds.value);\n if (selected.has(userId)) {\n selected.delete(userId);\n } else {\n selected.add(userId);\n }\n selectedAdminIds.value = Array.from(selected);\n }\n function toggleKick(userId) {\n const selected = new Set(selectedKickIds.value);\n if (selected.has(userId)) {\n selected.delete(userId);\n } else {\n selected.add(userId);\n }\n selectedKickIds.value = Array.from(selected);\n }\n async function saveGroupAdmins() {\n if (!activeConversation.value?.target || groupBusy.value) {\n return;\n }\n groupBusy.value = true;\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.setGroupAdmins(session.userId, activeConversation.value.target, selectedAdminIds.value);\n groupMembers.value = groupMembers.value.map(member => {\n if (member.role === 'owner') {\n return member;\n }\n return {\n ...member,\n role: selectedAdminIds.value.includes(member.uid) ? 'admin' : 'member'\n };\n });\n conversations.setActionNotice('管理员已更新');\n } catch (error) {\n conversations.setActionError(error.message || '管理员设置失败');\n } finally {\n groupBusy.value = false;\n }\n }\n async function saveGroupProfile() {\n if (!activeConversation.value?.target || groupBusy.value) {\n return;\n }\n groupBusy.value = true;\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.updateGroupProfile(session.userId, activeConversation.value.target, profileDraft.value);\n groupDetail.value = {\n ...(groupDetail.value || {}),\n name: result.name,\n announcement: result.announcement,\n welcomeText: result.welcomeText\n };\n conversations.upsertConversation({\n ...activeConversation.value,\n title: result.name,\n avatarText: String(result.name || '?').slice(0, 1).toUpperCase(),\n updatedAt: Number(result.updatedAt || Date.now())\n });\n conversations.setActionNotice('群资料已保存');\n } catch (error) {\n conversations.setActionError(error.message || '群资料保存失败');\n } finally {\n groupBusy.value = false;\n }\n }\n async function kickSelectedMembers() {\n if (!selectedKickIds.value.length || groupBusy.value) {\n return;\n }\n if (!window.confirm('确认将所选成员移出群组?')) {\n return;\n }\n groupBusy.value = true;\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.kickGroupMembers(session.userId, activeConversation.value.target, selectedKickIds.value);\n const removed = new Set(result.removedIds || selectedKickIds.value);\n groupMembers.value = groupMembers.value.filter(member => !removed.has(member.uid));\n selectedKickIds.value = [];\n conversations.setActionNotice('已移出群组');\n } catch (error) {\n conversations.setActionError(error.message || '踢人失败');\n } finally {\n groupBusy.value = false;\n }\n }\n async function saveMuteSetting() {\n if (!activeConversation.value?.target || groupBusy.value) {\n return;\n }\n clearMuteSaveFeedback();\n groupBusy.value = true;\n try {\n const setting = await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.updateGroupMuteSetting(session.userId, activeConversation.value.target, {\n mode: muteDraft.value.mode,\n scheduleType: muteDraft.value.scheduleType,\n startsAtMs: localInputToMs(muteDraft.value.startsAtLocal),\n endsAtMs: localInputToMs(muteDraft.value.endsAtLocal),\n dailyStart: muteDraft.value.dailyStart,\n dailyEnd: muteDraft.value.dailyEnd\n });\n groupDetail.value = {\n ...(groupDetail.value || {}),\n muteSetting: setting\n };\n muteSaveNotice.value = '禁言设置已保存';\n } catch (error) {\n muteSaveError.value = error.message || '禁言设置保存失败';\n } finally {\n groupBusy.value = false;\n }\n }\n async function leaveCurrentGroup() {\n if (!activeConversation.value || groupBusy.value) {\n return;\n }\n if (!window.confirm('确认退出该群组?')) {\n return;\n }\n groupBusy.value = true;\n const ok = await conversations.leaveGroup(activeConversation.value);\n groupBusy.value = false;\n if (ok) {\n closeGroupPanel();\n }\n }\n async function dismissCurrentGroup() {\n if (!activeConversation.value || groupBusy.value) {\n return;\n }\n if (!window.confirm('确认解散该群组?所有成员都将不可继续使用该群。')) {\n return;\n }\n groupBusy.value = true;\n const ok = await conversations.dismissGroup(activeConversation.value);\n groupBusy.value = false;\n if (ok) {\n closeGroupPanel();\n }\n }\n async function transferCurrentGroup() {\n if (!activeConversation.value?.target || !transferTargetId.value || groupBusy.value) {\n return;\n }\n if (!window.confirm('确认将群主转让给该成员?')) {\n return;\n }\n groupBusy.value = true;\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient.transferGroup(session.userId, activeConversation.value.target, transferTargetId.value);\n groupDetail.value = {\n ...(groupDetail.value || {}),\n myRole: 'member'\n };\n activeConversation.value.role = 'member';\n if (activeConversation.value.raw) {\n activeConversation.value.raw.role = 'member';\n }\n conversations.setActionNotice('群组已转让');\n closeGroupPanel();\n conversations.refreshRemoteConversations();\n } catch (error) {\n conversations.setActionError(error.message || '转让群组失败');\n } finally {\n groupBusy.value = false;\n }\n }\n function memberAvatar(member) {\n return String(member.displayName || member.uid || '?').slice(0, 1).toUpperCase();\n }\n document.addEventListener('click', closeGroupMenu);\n (0,vue__WEBPACK_IMPORTED_MODULE_12__.onBeforeUnmount)(() => {\n document.removeEventListener('click', closeGroupMenu);\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_12__.watch)(() => activeConversation.value?.id, () => {\n closeGroupMenu();\n closeSingleProfile();\n closeGroupPanel();\n groupDetail.value = null;\n groupMembers.value = [];\n groupAliasDraft.value = '';\n selectedAdminIds.value = [];\n selectedKickIds.value = [];\n transferTargetId.value = '';\n manageSection.value = '';\n });\n const __returned__ = {\n conversations,\n contacts,\n session,\n activeConversation,\n groupMenuOpen,\n singleProfileOpen,\n singleAliasDraft,\n singleProfileSaving,\n singleProfileNotice,\n singleProfileError,\n groupPanel,\n groupBusy,\n groupDetail,\n groupMembers,\n groupAliasDraft,\n manageSection,\n selectedAdminIds,\n selectedKickIds,\n transferTargetId,\n profileDraft,\n muteDraft,\n muteSaveNotice,\n muteSaveError,\n singlePeerId,\n singleContact,\n singleProfile,\n isGroupConversation,\n currentGroupRole,\n isGroupOwner,\n canManageGroup,\n adminCandidateMembers,\n transferableMembers,\n messageDetail,\n messageDetailGroup,\n isMessageDetailGroup,\n messageDetailCounts,\n kickCandidateMembers,\n statusText,\n formatDetailTime,\n detailMemberName,\n detailMemberAvatar,\n detailRoleLabel,\n closeGroupMenu,\n toggleGroupMenu,\n openSingleProfile,\n closeSingleProfile,\n saveSingleAlias,\n handleSenderProfileUpdated,\n closeGroupPanel,\n loadGroupDetail,\n openGroupOverview,\n openGroupMembers,\n loadGroupMembers,\n openGroupAlias,\n msToLocalInput,\n localInputToMs,\n prepareManagementDrafts,\n clearMuteSaveFeedback,\n openGroupManage,\n openTransferGroup,\n saveGroupAlias,\n toggleAdmin,\n toggleKick,\n saveGroupAdmins,\n saveGroupProfile,\n kickSelectedMembers,\n saveMuteSetting,\n leaveCurrentGroup,\n dismissCurrentGroup,\n transferCurrentGroup,\n memberAvatar,\n computed: vue__WEBPACK_IMPORTED_MODULE_12__.computed,\n onBeforeUnmount: vue__WEBPACK_IMPORTED_MODULE_12__.onBeforeUnmount,\n ref: vue__WEBPACK_IMPORTED_MODULE_12__.ref,\n watch: vue__WEBPACK_IMPORTED_MODULE_12__.watch,\n MessageList: _MessageList_vue__WEBPACK_IMPORTED_MODULE_13__[\"default\"],\n MessageComposer: _MessageComposer_vue__WEBPACK_IMPORTED_MODULE_14__[\"default\"],\n get imClient() {\n return _services_imClient__WEBPACK_IMPORTED_MODULE_15__.imClient;\n },\n get useConversationStore() {\n return _stores_conversations__WEBPACK_IMPORTED_MODULE_16__.useConversationStore;\n },\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_17__.useContactStore;\n },\n get useSessionStore() {\n return _stores_session__WEBPACK_IMPORTED_MODULE_18__.useSessionStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/ChatPanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*****************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*****************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'MessageComposer',\n props: {\n disabled: {\n type: Boolean,\n default: false\n },\n quoteMessage: {\n type: Object,\n default: null\n }\n },\n emits: ['send', 'send-attachment', 'cancel-quote'],\n setup(__props, {\n expose: __expose,\n emit: __emit\n }) {\n __expose();\n const props = __props;\n const emit = __emit;\n const text = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)('');\n const emojiOpen = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(false);\n const dropActive = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(false);\n const textareaEl = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n const imageInput = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n const fileInput = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n let dragDepth = 0;\n const emojiList = ['😀', '😄', '😂', '😊', '😍', '😘', '😎', '😢', '😡', '👍', '🙏', '👏', '💪', '🎉', '❤️', '🔥', '🌹', '☕', '✅', '⭐', '💰', '🎁', '🤝', '👌'];\n function submit() {\n const value = text.value.trim();\n if (!value) {\n return;\n }\n emit('send', value);\n text.value = '';\n emojiOpen.value = false;\n }\n function toggleEmojiPicker() {\n emojiOpen.value = !emojiOpen.value;\n }\n function insertEmoji(emoji) {\n const element = textareaEl.value;\n if (!element) {\n text.value += emoji;\n return;\n }\n const start = element.selectionStart ?? text.value.length;\n const end = element.selectionEnd ?? text.value.length;\n text.value = `${text.value.slice(0, start)}${emoji}${text.value.slice(end)}`;\n requestAnimationFrame(() => {\n element.focus();\n const cursor = start + emoji.length;\n element.setSelectionRange(cursor, cursor);\n });\n }\n function chooseImage() {\n imageInput.value?.click();\n }\n function chooseFile() {\n fileInput.value?.click();\n }\n function attachmentTypeForFile(file, fallbackType = 'file') {\n if (file?.type?.startsWith('image/')) {\n return 'image';\n }\n return fallbackType === 'image' ? 'image' : 'file';\n }\n function emitFiles(files, fallbackType = 'file') {\n if (props.disabled) {\n return;\n }\n const validFiles = Array.from(files || []).filter(file => file instanceof File && file.size > 0);\n if (!validFiles.length) {\n return;\n }\n const caption = text.value.trim();\n validFiles.forEach((file, index) => {\n emit('send-attachment', {\n type: attachmentTypeForFile(file, fallbackType),\n file,\n text: index === 0 ? caption : ''\n });\n });\n text.value = '';\n emojiOpen.value = false;\n }\n function selectAttachment(event, type) {\n const input = event.target;\n const files = input.files ? Array.from(input.files) : [];\n input.value = '';\n if (!files.length || props.disabled) {\n return;\n }\n emitFiles(files, type);\n }\n function hasDraggedFiles(event) {\n const types = Array.from(event.dataTransfer?.types || []);\n return types.includes('Files');\n }\n function handleDragEnter(event) {\n if (props.disabled || !hasDraggedFiles(event)) {\n return;\n }\n dragDepth += 1;\n dropActive.value = true;\n event.dataTransfer.dropEffect = 'copy';\n }\n function handleDragOver(event) {\n if (props.disabled || !hasDraggedFiles(event)) {\n return;\n }\n dropActive.value = true;\n event.dataTransfer.dropEffect = 'copy';\n }\n function handleDragLeave() {\n dragDepth = Math.max(0, dragDepth - 1);\n if (dragDepth === 0) {\n dropActive.value = false;\n }\n }\n function filesFromDataTransfer(dataTransfer) {\n const items = Array.from(dataTransfer?.items || []);\n const files = items.filter(item => item.kind === 'file' && !item.webkitGetAsEntry?.()?.isDirectory).map(item => item.getAsFile()).filter(Boolean);\n if (files.length) {\n return files;\n }\n return Array.from(dataTransfer?.files || []);\n }\n function handleDrop(event) {\n dragDepth = 0;\n dropActive.value = false;\n if (props.disabled) {\n return;\n }\n emitFiles(filesFromDataTransfer(event.dataTransfer));\n }\n function imageFilesFromClipboard(clipboardData) {\n return Array.from(clipboardData?.items || []).filter(item => item.kind === 'file' && item.type.startsWith('image/')).map(item => item.getAsFile()).filter(Boolean);\n }\n function handlePaste(event) {\n if (props.disabled) {\n return;\n }\n const imageFiles = imageFilesFromClipboard(event.clipboardData);\n if (!imageFiles.length) {\n return;\n }\n event.preventDefault();\n emitFiles(imageFiles, 'image');\n }\n const __returned__ = {\n props,\n emit,\n text,\n emojiOpen,\n dropActive,\n textareaEl,\n imageInput,\n fileInput,\n get dragDepth() {\n return dragDepth;\n },\n set dragDepth(v) {\n dragDepth = v;\n },\n emojiList,\n submit,\n toggleEmojiPicker,\n insertEmoji,\n chooseImage,\n chooseFile,\n attachmentTypeForFile,\n emitFiles,\n selectAttachment,\n hasDraggedFiles,\n handleDragEnter,\n handleDragOver,\n handleDragLeave,\n filesFromDataTransfer,\n handleDrop,\n imageFilesFromClipboard,\n handlePaste,\n ref: vue__WEBPACK_IMPORTED_MODULE_5__.ref\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageComposer.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/services/mediaProxy */ \"./src/services/mediaProxy.js\");\n\n\n\n\n\n\n\n\nconst IMAGE_MIN_SCALE = 0.5;\nconst IMAGE_MAX_SCALE = 6;\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'MessageList',\n props: {\n messages: {\n type: Array,\n default: () => []\n },\n selectionMode: {\n type: Boolean,\n default: false\n },\n selectedMessageIds: {\n type: Array,\n default: () => []\n },\n favoriteMessageIds: {\n type: Array,\n default: () => []\n },\n attentionMessageId: {\n type: String,\n default: ''\n },\n canRecallOthers: {\n type: Boolean,\n default: false\n }\n },\n emits: ['message-action', 'toggle-select', 'sender-profile-updated'],\n setup(__props, {\n expose: __expose,\n emit: __emit\n }) {\n __expose();\n const props = __props;\n const emit = __emit;\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_6__.useContactStore)();\n const listEl = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n const viewerStage = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n const contextMenu = (0,vue__WEBPACK_IMPORTED_MODULE_5__.reactive)({\n visible: false,\n x: 0,\n y: 0,\n message: null\n });\n const imageViewer = (0,vue__WEBPACK_IMPORTED_MODULE_5__.reactive)({\n visible: false,\n url: '',\n name: '',\n scale: 1,\n rotation: 0,\n offsetX: 0,\n offsetY: 0,\n dragging: false,\n dragStartX: 0,\n dragStartY: 0,\n dragOffsetX: 0,\n dragOffsetY: 0\n });\n const senderProfile = (0,vue__WEBPACK_IMPORTED_MODULE_5__.reactive)({\n visible: false,\n uid: '',\n displayName: '',\n rawName: '',\n mobile: '',\n address: '',\n portrait: '',\n avatarText: '',\n role: '',\n roleLabel: '',\n contactAlias: '',\n groupAlias: '',\n isContact: false,\n aliasDraft: '',\n saving: false,\n adding: false,\n notice: '',\n error: ''\n });\n const imageViewerStyle = (0,vue__WEBPACK_IMPORTED_MODULE_5__.computed)(() => ({\n transform: `translate3d(${imageViewer.offsetX}px, ${imageViewer.offsetY}px, 0) scale(${imageViewer.scale}) rotate(${imageViewer.rotation}deg)`\n }));\n const menuItems = (0,vue__WEBPACK_IMPORTED_MODULE_5__.computed)(() => {\n if (!contextMenu.message) {\n return [];\n }\n const isOwnMessage = contextMenu.message.direction === 'out';\n if (isRecalledMessage(contextMenu.message)) {\n return [...(isOwnMessage ? [{\n action: 'edit',\n label: '编辑'\n }] : []), {\n action: 'copy',\n label: '复制'\n }, {\n action: 'delete',\n label: '删除'\n }, {\n action: 'detail',\n label: '详情'\n }];\n }\n const favoriteLabel = isFavorite(contextMenu.message) ? '取消收藏' : '收藏';\n const items = [{\n action: 'copy',\n label: '复制'\n }, {\n action: 'delete',\n label: '删除'\n }, {\n action: 'forward',\n label: '转发'\n }, {\n action: 'favorite',\n label: favoriteLabel\n }, {\n action: 'quote',\n label: '引用'\n }, {\n action: 'select',\n label: '多选'\n }, {\n action: 'detail',\n label: '详情'\n }];\n if (isOwnMessage) {\n items.unshift({\n action: 'edit',\n label: '编辑'\n });\n items.push({\n action: 'recall',\n label: '撤回'\n });\n } else if (props.canRecallOthers) {\n items.push({\n action: 'recall',\n label: '撤回'\n });\n }\n return items;\n });\n function scrollToBottom() {\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.nextTick)(() => {\n if (listEl.value) {\n listEl.value.scrollTop = listEl.value.scrollHeight;\n }\n });\n }\n function scrollToMessage(messageId) {\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.nextTick)(() => {\n if (!listEl.value || !messageId) {\n return;\n }\n const row = Array.from(listEl.value.querySelectorAll('.message-row')).find(element => element.dataset.messageKey === messageId);\n if (row) {\n row.scrollIntoView({\n block: 'center',\n behavior: 'smooth'\n });\n }\n });\n }\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.watch)(() => props.messages.map(message => `${message.id}:${message.status}:${message.deliveryStatus || ''}:${message.messageUid || ''}:${message.recalled ? '1' : ''}`).join('|'), scrollToBottom, {\n immediate: true\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.watch)(() => props.attentionMessageId, scrollToMessage);\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.onMounted)(() => {\n document.addEventListener('click', closeMenu);\n document.addEventListener('keydown', closeMenuOnEscape);\n document.addEventListener('pointermove', moveImageDrag);\n document.addEventListener('pointerup', stopImageDrag);\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.onBeforeUnmount)(() => {\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', closeMenuOnEscape);\n document.removeEventListener('pointermove', moveImageDrag);\n document.removeEventListener('pointerup', stopImageDrag);\n });\n function messageIdentity(message) {\n return String(message.messageUid || message.id || '');\n }\n function canOpenMessageMenu(message) {\n return message && message.status !== 'failed' && message.status !== 'sending';\n }\n function isSelected(message) {\n return props.selectedMessageIds.includes(messageIdentity(message));\n }\n function isFavorite(message) {\n return props.favoriteMessageIds.includes(messageIdentity(message));\n }\n function isAttention(message) {\n return props.attentionMessageId === messageIdentity(message);\n }\n function isRecallNotice(message) {\n return message.direction === 'out' && (message.recalled || message.status === 'recalled');\n }\n function isRecalledMessage(message) {\n return message.recalled || message.status === 'recalled';\n }\n function isImageMessage(message) {\n return message?.type === 'image' && message?.attachment?.url;\n }\n function isFileMessage(message) {\n return message?.type === 'file' && message?.attachment?.url;\n }\n function isGroupMessage(message) {\n return ['group', 'channel'].includes(message?.conversationType || '');\n }\n function showGroupSender(message) {\n return isGroupMessage(message) && message?.direction === 'in';\n }\n function senderRoleLabel(message) {\n const role = message?.senderProfile?.role || message?.senderRole || '';\n if (role === 'owner') {\n return '群主';\n }\n if (role === 'admin') {\n return '管理员';\n }\n return '';\n }\n function groupSenderName(message) {\n return message?.senderName || message?.senderProfile?.displayName || message?.from || '未知用户';\n }\n function groupSenderAvatarText(message) {\n return String(groupSenderName(message) || '?').slice(0, 1).toUpperCase();\n }\n function openSenderProfile(message) {\n const profile = message?.senderProfile || {};\n const uid = profile.uid || message?.from || '';\n const cachedContact = contacts.contacts.find(contact => String(contact.uid || contact.id || '') === uid) || null;\n const cachedAlias = String(cachedContact?.alias || '').trim();\n const contactAlias = String(profile.contactAlias || cachedAlias || profile.remarkAlias || '').trim();\n const groupAlias = String(profile.groupAlias || '').trim();\n const rawName = profile.rawName || cachedContact?.rawUser?.displayName || cachedContact?.rawUser?.name || cachedContact?.title || groupSenderName(message);\n const displayName = contactAlias || groupAlias || rawName || uid;\n senderProfile.visible = true;\n senderProfile.uid = uid;\n senderProfile.displayName = displayName;\n senderProfile.rawName = rawName || '';\n senderProfile.mobile = profile.mobile || cachedContact?.rawUser?.mobile || '';\n senderProfile.address = profile.address || cachedContact?.address || cachedContact?.rawUser?.address || '';\n senderProfile.portrait = profile.portrait || cachedContact?.portrait || message?.senderPortrait || '';\n senderProfile.avatarText = String(displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();\n senderProfile.role = profile.role || message?.senderRole || '';\n senderProfile.roleLabel = senderRoleLabel(message);\n senderProfile.contactAlias = contactAlias;\n senderProfile.groupAlias = groupAlias;\n senderProfile.isContact = Boolean(profile.isContact || cachedContact);\n senderProfile.aliasDraft = contactAlias;\n senderProfile.saving = false;\n senderProfile.adding = false;\n senderProfile.notice = '';\n senderProfile.error = '';\n closeMenu();\n }\n function closeSenderProfile() {\n if (senderProfile.saving || senderProfile.adding) {\n return;\n }\n senderProfile.visible = false;\n }\n async function addSenderAsContact() {\n if (!senderProfile.uid || senderProfile.adding || senderProfile.saving) {\n return;\n }\n senderProfile.adding = true;\n senderProfile.notice = '';\n senderProfile.error = '';\n const ok = await contacts.addContact(senderProfile.uid);\n if (ok || String(contacts.actionError || '').includes('已经是联系人')) {\n senderProfile.isContact = true;\n const alias = senderProfile.aliasDraft.trim();\n let aliasSaved = false;\n if (alias) {\n aliasSaved = await contacts.updateContactAlias(senderProfile.uid, alias);\n if (aliasSaved) {\n senderProfile.contactAlias = alias;\n senderProfile.displayName = alias;\n senderProfile.avatarText = String(alias || senderProfile.uid || '?').slice(0, 1).toUpperCase();\n }\n }\n await contacts.refreshContacts({\n force: true\n }).catch(() => {});\n if (alias && !aliasSaved) {\n senderProfile.notice = '';\n senderProfile.error = contacts.actionError ? `已添加为好友,但${contacts.actionError}` : '已添加为好友,但备注名同步失败';\n } else {\n senderProfile.notice = alias ? '已添加为好友,备注名已保存' : ok ? '已添加为好友' : '已是好友';\n }\n emit('sender-profile-updated', {\n userId: senderProfile.uid\n });\n } else {\n senderProfile.error = contacts.actionError || '添加好友失败';\n }\n senderProfile.adding = false;\n }\n async function saveSenderAlias() {\n if (!senderProfile.uid || senderProfile.saving || senderProfile.adding) {\n return;\n }\n senderProfile.saving = true;\n senderProfile.notice = '';\n senderProfile.error = '';\n const ok = await contacts.updateContactAlias(senderProfile.uid, senderProfile.aliasDraft);\n if (ok) {\n await contacts.refreshContacts({\n force: true\n }).catch(() => {});\n const alias = senderProfile.aliasDraft.trim();\n senderProfile.contactAlias = alias;\n senderProfile.displayName = alias || senderProfile.groupAlias || senderProfile.rawName || senderProfile.uid;\n senderProfile.avatarText = String(senderProfile.displayName || senderProfile.uid || '?').slice(0, 1).toUpperCase();\n senderProfile.notice = '备注名已保存';\n emit('sender-profile-updated', {\n userId: senderProfile.uid\n });\n } else {\n senderProfile.error = contacts.actionError || '备注名修改失败';\n }\n senderProfile.saving = false;\n }\n function roleBubbleClass(message) {\n const role = message?.senderRole || '';\n if (role === 'owner') {\n return 'role-bubble-owner';\n }\n if (role === 'admin') {\n return 'role-bubble-admin';\n }\n return '';\n }\n function formatFileSize(size) {\n const bytes = Number(size || 0);\n if (bytes >= 1024 * 1024) {\n return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;\n }\n if (bytes >= 1024) {\n return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;\n }\n return bytes > 0 ? `${bytes} B` : '';\n }\n function handleMessageClick(message) {\n if (props.selectionMode) {\n emit('toggle-select', message);\n }\n }\n function handleImageClick(message) {\n if (props.selectionMode) {\n emit('toggle-select', message);\n return;\n }\n openImageViewer(message);\n }\n function openImageViewer(message) {\n const attachment = message?.attachment || {};\n if (!attachment.url) {\n return;\n }\n closeMenu();\n imageViewer.visible = true;\n imageViewer.url = (0,_services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__.imageDisplayUrl)(attachment.url);\n imageViewer.name = attachment.name || 'image';\n resetImageViewer();\n }\n function closeImageViewer() {\n imageViewer.visible = false;\n imageViewer.dragging = false;\n }\n function resetImageViewer() {\n imageViewer.scale = 1;\n imageViewer.rotation = 0;\n imageViewer.offsetX = 0;\n imageViewer.offsetY = 0;\n }\n function clampImageScale(value) {\n return Math.min(IMAGE_MAX_SCALE, Math.max(IMAGE_MIN_SCALE, Number(value.toFixed(2))));\n }\n function setImageScale(value, originX = null, originY = null) {\n const previousScale = imageViewer.scale;\n const nextScale = clampImageScale(value);\n if (nextScale === previousScale) {\n return;\n }\n if (originX !== null && originY !== null && viewerStage.value) {\n const rect = viewerStage.value.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const ratio = nextScale / previousScale - 1;\n imageViewer.offsetX -= (originX - centerX - imageViewer.offsetX) * ratio;\n imageViewer.offsetY -= (originY - centerY - imageViewer.offsetY) * ratio;\n }\n imageViewer.scale = nextScale;\n if (nextScale <= 1) {\n imageViewer.offsetX = 0;\n imageViewer.offsetY = 0;\n }\n }\n function zoomImage(delta) {\n setImageScale(imageViewer.scale + delta);\n }\n function rotateImage() {\n imageViewer.rotation = (imageViewer.rotation + 90) % 360;\n }\n function handleImageWheel(event) {\n const factor = event.deltaY < 0 ? 1.12 : 1 / 1.12;\n setImageScale(imageViewer.scale * factor, event.clientX, event.clientY);\n }\n function startImageDrag(event) {\n if (!imageViewer.visible || imageViewer.scale <= 1) {\n return;\n }\n imageViewer.dragging = true;\n imageViewer.dragStartX = event.clientX;\n imageViewer.dragStartY = event.clientY;\n imageViewer.dragOffsetX = imageViewer.offsetX;\n imageViewer.dragOffsetY = imageViewer.offsetY;\n }\n function moveImageDrag(event) {\n if (!imageViewer.dragging) {\n return;\n }\n imageViewer.offsetX = imageViewer.dragOffsetX + event.clientX - imageViewer.dragStartX;\n imageViewer.offsetY = imageViewer.dragOffsetY + event.clientY - imageViewer.dragStartY;\n }\n function stopImageDrag() {\n imageViewer.dragging = false;\n }\n function saveViewerImage() {\n if (!imageViewer.url) {\n return;\n }\n const downloadUrl = new URL('/api/media_download.php', window.location.origin);\n downloadUrl.searchParams.set('url', imageViewer.url);\n downloadUrl.searchParams.set('name', imageViewer.name || 'image');\n const link = document.createElement('a');\n link.href = downloadUrl.toString();\n link.download = imageViewer.name || 'image';\n document.body.appendChild(link);\n link.click();\n link.remove();\n }\n function openMenu(event, message) {\n if (!canOpenMessageMenu(message)) {\n closeMenu();\n return;\n }\n contextMenu.visible = true;\n contextMenu.message = message;\n contextMenu.x = Math.min(event.clientX, window.innerWidth - 148);\n contextMenu.y = Math.min(event.clientY, window.innerHeight - 352);\n }\n function closeMenu() {\n contextMenu.visible = false;\n contextMenu.message = null;\n }\n function closeMenuOnEscape(event) {\n if (event.key === 'Escape') {\n if (senderProfile.visible) {\n closeSenderProfile();\n }\n if (imageViewer.visible) {\n closeImageViewer();\n }\n closeMenu();\n }\n }\n function chooseMenuAction(action) {\n if (contextMenu.message) {\n emit('message-action', {\n action,\n message: contextMenu.message\n });\n }\n closeMenu();\n }\n function formatTime(timestamp) {\n return new Intl.DateTimeFormat('zh-CN', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone\n }).format(timestamp);\n }\n function deliveryState(message) {\n if (message.direction !== 'out' || message.status === 'failed' || message.status === 'recalled' || message.recalled) {\n return '';\n }\n const state = message.deliveryStatus || message.status;\n if (state === 'read') {\n return 'read';\n }\n if (state === 'delivered') {\n return 'delivered';\n }\n if (state === 'sent') {\n return 'sent';\n }\n return '';\n }\n function deliveryTitle(message) {\n const state = deliveryState(message);\n if (state === 'read') {\n return '对方已读';\n }\n if (state === 'delivered') {\n return '已送达对方';\n }\n if (state === 'sent') {\n return '已送出';\n }\n return '';\n }\n function failureText(message) {\n if (message.status === 'failed') {\n if (message.errorCode) {\n return message.error ? `失败:${message.error}(${message.errorCode})` : `失败:${message.errorCode}`;\n }\n return message.error ? `失败:${message.error}` : '失败';\n }\n return '';\n }\n const __returned__ = {\n props,\n emit,\n contacts,\n listEl,\n viewerStage,\n contextMenu,\n IMAGE_MIN_SCALE,\n IMAGE_MAX_SCALE,\n imageViewer,\n senderProfile,\n imageViewerStyle,\n menuItems,\n scrollToBottom,\n scrollToMessage,\n messageIdentity,\n canOpenMessageMenu,\n isSelected,\n isFavorite,\n isAttention,\n isRecallNotice,\n isRecalledMessage,\n isImageMessage,\n isFileMessage,\n isGroupMessage,\n showGroupSender,\n senderRoleLabel,\n groupSenderName,\n groupSenderAvatarText,\n openSenderProfile,\n closeSenderProfile,\n addSenderAsContact,\n saveSenderAlias,\n roleBubbleClass,\n formatFileSize,\n handleMessageClick,\n handleImageClick,\n openImageViewer,\n closeImageViewer,\n resetImageViewer,\n clampImageScale,\n setImageScale,\n zoomImage,\n rotateImage,\n handleImageWheel,\n startImageDrag,\n moveImageDrag,\n stopImageDrag,\n saveViewerImage,\n openMenu,\n closeMenu,\n closeMenuOnEscape,\n chooseMenuAction,\n formatTime,\n deliveryState,\n deliveryTitle,\n failureText,\n computed: vue__WEBPACK_IMPORTED_MODULE_5__.computed,\n nextTick: vue__WEBPACK_IMPORTED_MODULE_5__.nextTick,\n onBeforeUnmount: vue__WEBPACK_IMPORTED_MODULE_5__.onBeforeUnmount,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_5__.onMounted,\n reactive: vue__WEBPACK_IMPORTED_MODULE_5__.reactive,\n ref: vue__WEBPACK_IMPORTED_MODULE_5__.ref,\n watch: vue__WEBPACK_IMPORTED_MODULE_5__.watch,\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_6__.useContactStore;\n },\n get imageDisplayUrl() {\n return _services_mediaProxy__WEBPACK_IMPORTED_MODULE_7__.imageDisplayUrl;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!******************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\******************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'ContactPanel',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_1__.useContactStore)();\n const contact = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => contacts.activeContact);\n const remarkName = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => contact.value?.alias || '未设置');\n const username = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => contact.value?.rawUser?.displayName || contact.value?.rawUser?.name || contact.value?.uid || '');\n const mobile = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => contact.value?.rawUser?.mobile || '未知');\n const address = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => contact.value?.rawUser?.address || '未知');\n const editingAlias = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false);\n const aliasDraft = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('');\n const aliasSaving = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false);\n const aliasError = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('');\n (0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(contact, () => {\n editingAlias.value = false;\n aliasError.value = '';\n });\n function openAliasEditor() {\n aliasDraft.value = contact.value?.alias || '';\n aliasError.value = '';\n editingAlias.value = true;\n }\n function closeAliasEditor() {\n if (aliasSaving.value) {\n return;\n }\n editingAlias.value = false;\n aliasError.value = '';\n }\n async function submitAlias() {\n if (!contact.value) {\n return;\n }\n aliasSaving.value = true;\n aliasError.value = '';\n const ok = await contacts.updateContactAlias(contact.value.uid, aliasDraft.value);\n aliasSaving.value = false;\n if (ok) {\n editingAlias.value = false;\n return;\n }\n aliasError.value = contacts.actionError || '备注名修改失败';\n }\n const __returned__ = {\n contacts,\n contact,\n remarkName,\n username,\n mobile,\n address,\n editingAlias,\n aliasDraft,\n aliasSaving,\n aliasError,\n openAliasEditor,\n closeAliasEditor,\n submitAlias,\n computed: vue__WEBPACK_IMPORTED_MODULE_0__.computed,\n ref: vue__WEBPACK_IMPORTED_MODULE_0__.ref,\n watch: vue__WEBPACK_IMPORTED_MODULE_0__.watch,\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_1__.useContactStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/contacts/ContactPanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*******************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*******************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'FavoriteList',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_3__.useConversationStore)();\n const activeKey = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => conversations.activeFavorite?.key || '');\n function favoriteTitle(item) {\n if (item.conversationTitle) {\n return item.conversationTitle;\n }\n const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);\n return conversation?.title || item.conversationId || '未知会话';\n }\n function favoritePreview(item) {\n if (item.recalled) {\n return `[${item.recallStatus || '已撤回'}]`;\n }\n if (item.preview) {\n return item.preview;\n }\n if (item.text) {\n return item.text;\n }\n if (item.type === 'image') {\n return '[图片]';\n }\n if (item.type === 'file') {\n return `[文件] ${item.attachment?.name || '文件'}`;\n }\n return '(无文字内容)';\n }\n function formatFavoriteTime(timestamp) {\n const value = Number(timestamp || 0);\n if (!value) {\n return '';\n }\n return new Intl.DateTimeFormat('zh-CN', {\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false\n }).format(value);\n }\n const __returned__ = {\n conversations,\n activeKey,\n favoriteTitle,\n favoritePreview,\n formatFavoriteTime,\n computed: vue__WEBPACK_IMPORTED_MODULE_2__.computed,\n get useConversationStore() {\n return _stores_conversations__WEBPACK_IMPORTED_MODULE_3__.useConversationStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoriteList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!********************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\********************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/stores/navigation */ \"./src/stores/navigation.js\");\n/* harmony import */ var _services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/services/mediaProxy */ \"./src/services/mediaProxy.js\");\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'FavoritePanel',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_3__.useConversationStore)();\n const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_4__.useNavigationStore)();\n const favorite = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => conversations.activeFavorite);\n const notice = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const error = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n function clearFeedback() {\n notice.value = '';\n error.value = '';\n }\n function favoriteTitle(item) {\n if (item.conversationTitle) {\n return item.conversationTitle;\n }\n const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);\n return conversation?.title || item.conversationId || '未知会话';\n }\n function favoriteText(item) {\n return item.text || '';\n }\n function isImageFavorite(item) {\n return item?.type === 'image' && item?.attachment?.url;\n }\n function isFileFavorite(item) {\n return item?.type === 'file' && item?.attachment?.url;\n }\n function favoriteCopyText(item) {\n if (!item) {\n return '';\n }\n if (item.text) {\n return item.text;\n }\n if (item.recalled) {\n return item.recallStatus || '已撤回';\n }\n if (isImageFavorite(item)) {\n return item.attachment.url;\n }\n if (isFileFavorite(item)) {\n return `${item.attachment.name || '文件'} ${item.attachment.url}`.trim();\n }\n return item.preview || '';\n }\n function formatFileSize(size) {\n const bytes = Number(size || 0);\n if (bytes >= 1024 * 1024) {\n return `${(bytes / 1024 / 1024).toFixed(bytes >= 10 * 1024 * 1024 ? 0 : 1)} MB`;\n }\n if (bytes >= 1024) {\n return `${(bytes / 1024).toFixed(bytes >= 10 * 1024 ? 0 : 1)} KB`;\n }\n return bytes > 0 ? `${bytes} B` : '';\n }\n function formatFavoriteTime(timestamp) {\n const value = Number(timestamp || 0);\n if (!value) {\n return '';\n }\n return new Intl.DateTimeFormat('zh-CN', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false\n }).format(value);\n }\n async function copyFavorite() {\n clearFeedback();\n const text = favoriteCopyText(favorite.value || {}).trim();\n if (!text) {\n error.value = '没有可复制的文字内容';\n return;\n }\n try {\n await writeClipboard(text);\n notice.value = '已复制';\n } catch (copyError) {\n error.value = '复制失败';\n }\n }\n async function writeClipboard(text) {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n const element = document.createElement('textarea');\n element.value = text;\n element.setAttribute('readonly', 'readonly');\n element.style.position = 'fixed';\n element.style.left = '-9999px';\n document.body.appendChild(element);\n element.select();\n document.execCommand('copy');\n document.body.removeChild(element);\n }\n function openConversation() {\n clearFeedback();\n const item = favorite.value;\n if (!item?.conversationId) {\n error.value = '缺少原会话信息';\n return;\n }\n const conversation = conversations.conversations.find(entry => entry.id === item.conversationId);\n if (!conversation) {\n error.value = '原会话暂未加载,请刷新会话后再试';\n conversations.refreshRemoteConversations();\n return;\n }\n navigation.showMessages();\n conversations.setActiveConversation(item.conversationId);\n window.setTimeout(() => {\n conversations.focusMessage({\n id: item.id || item.key,\n messageUid: item.messageUid || item.key\n });\n }, 450);\n }\n function removeFavorite() {\n clearFeedback();\n const key = favorite.value?.key || '';\n if (!key) {\n return;\n }\n conversations.removeFavorite(key);\n notice.value = '已取消收藏';\n }\n const __returned__ = {\n conversations,\n navigation,\n favorite,\n notice,\n error,\n clearFeedback,\n favoriteTitle,\n favoriteText,\n isImageFavorite,\n isFileFavorite,\n favoriteCopyText,\n formatFileSize,\n formatFavoriteTime,\n copyFavorite,\n writeClipboard,\n openConversation,\n removeFavorite,\n computed: vue__WEBPACK_IMPORTED_MODULE_2__.computed,\n ref: vue__WEBPACK_IMPORTED_MODULE_2__.ref,\n get useConversationStore() {\n return _stores_conversations__WEBPACK_IMPORTED_MODULE_3__.useConversationStore;\n },\n get useNavigationStore() {\n return _stores_navigation__WEBPACK_IMPORTED_MODULE_4__.useNavigationStore;\n },\n get imageDisplayUrl() {\n return _services_mediaProxy__WEBPACK_IMPORTED_MODULE_5__.imageDisplayUrl;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoritePanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!****************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\****************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'ContactList',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_4__.useContactStore)();\n const keyword = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const addingContact = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)(false);\n const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_3__.ref)('');\n const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_3__.computed)(() => {\n const value = keyword.value.toLowerCase();\n if (!value) {\n return contacts.contacts;\n }\n return contacts.contacts.filter(item => {\n return item.title.toLowerCase().includes(value) || item.subtitle.toLowerCase().includes(value) || item.uid.toLowerCase().includes(value);\n });\n });\n function openAddContact() {\n contacts.actionError = '';\n contacts.actionInfo = '';\n addKeyword.value = '';\n addingContact.value = true;\n }\n function closeAddContact() {\n addingContact.value = false;\n }\n async function submitAddContact() {\n const added = await contacts.addContact(addKeyword.value);\n if (added) {\n window.setTimeout(() => {\n addingContact.value = false;\n }, 500);\n }\n }\n const __returned__ = {\n contacts,\n keyword,\n addingContact,\n addKeyword,\n filteredContacts,\n openAddContact,\n closeAddContact,\n submitAddContact,\n computed: vue__WEBPACK_IMPORTED_MODULE_3__.computed,\n ref: vue__WEBPACK_IMPORTED_MODULE_3__.ref,\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_4__.useContactStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ContactList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*********************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*********************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.flat-map.js */ \"./node_modules/core-js/modules/es.iterator.flat-map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.iterator.some.js */ \"./node_modules/core-js/modules/es.iterator.some.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert.js */ \"./node_modules/core-js/modules/es.map.get-or-insert.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert-computed.js */ \"./node_modules/core-js/modules/es.map.get-or-insert-computed.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.set.difference.v2.js */ \"./node_modules/core-js/modules/es.set.difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/es.set.intersection.v2.js */ \"./node_modules/core-js/modules/es.set.intersection.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! core-js/modules/es.set.is-disjoint-from.v2.js */ \"./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! core-js/modules/es.set.is-subset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-subset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! core-js/modules/es.set.is-superset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-superset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! core-js/modules/es.set.symmetric-difference.v2.js */ \"./node_modules/core-js/modules/es.set.symmetric-difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! core-js/modules/es.set.union.v2.js */ \"./node_modules/core-js/modules/es.set.union.v2.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'ConversationList',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_17__.useConversationStore)();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_18__.useContactStore)();\n const actionMenuOpen = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)(false);\n const activeAction = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const actionBusy = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)(false);\n const searchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const addKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const groupName = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const groupAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const groupWelcomeText = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const joinGroupKey = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const broadcastText = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const channelName = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const channelAnnouncement = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const contactKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)('');\n const selectedContactIds = (0,vue__WEBPACK_IMPORTED_MODULE_16__.ref)([]);\n const actionTitles = {\n addContact: '添加联系人',\n createGroup: '新建群组',\n joinGroup: '加入群组',\n broadcast: '群发助手',\n createChannel: '创建频道/公告群'\n };\n const submitLabels = {\n addContact: '添加',\n createGroup: '创建',\n joinGroup: '加入',\n broadcast: '发送',\n createChannel: '创建'\n };\n const actionTitle = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => actionTitles[activeAction.value] || '');\n const submitLabel = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => submitLabels[activeAction.value] || '确定');\n const modalError = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => contacts.actionError || conversations.actionError);\n const modalInfo = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => contacts.actionInfo || conversations.actionNotice);\n const normalizedSearchKeyword = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => searchKeyword.value.trim().toLowerCase());\n const contactsByUid = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => {\n const map = new Map();\n contacts.contacts.forEach(contact => {\n const uid = String(contact.uid || contact.id || '');\n if (uid) {\n map.set(uid, contact);\n }\n });\n return map;\n });\n const filteredConversationItems = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => {\n const keyword = normalizedSearchKeyword.value;\n if (!keyword) {\n return conversations.conversations.map(item => conversationResult(item));\n }\n const conversationResults = conversations.conversations.filter(item => matchesConversation(item, keyword, contactForConversation(item))).map(item => conversationResult(item));\n const conversationTargets = new Set(conversations.conversations.filter(item => item.type === 'single').map(item => conversationTarget(item)));\n const contactResults = contacts.contacts.filter(item => !conversationTargets.has(String(item.uid || item.id || ''))).filter(item => matchesContact(item, keyword)).map(item => contactResult(item));\n return [...conversationResults, ...contactResults];\n });\n const filteredContacts = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => {\n const keyword = contactKeyword.value.toLowerCase();\n if (!keyword) {\n return contacts.contacts;\n }\n return contacts.contacts.filter(item => {\n return String(item.title || '').toLowerCase().includes(keyword) || String(item.subtitle || '').toLowerCase().includes(keyword) || String(item.uid || '').toLowerCase().includes(keyword);\n });\n });\n const submitDisabled = (0,vue__WEBPACK_IMPORTED_MODULE_16__.computed)(() => {\n if (activeAction.value === 'addContact') {\n return !addKeyword.value;\n }\n if (activeAction.value === 'createGroup') {\n return !groupName.value || !selectedContactIds.value.length;\n }\n if (activeAction.value === 'joinGroup') {\n return !joinGroupKey.value;\n }\n if (activeAction.value === 'broadcast') {\n return !broadcastText.value || !selectedContactIds.value.length;\n }\n if (activeAction.value === 'createChannel') {\n return !channelName.value;\n }\n return true;\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_16__.onMounted)(() => {\n contacts.refreshContacts().catch(() => {});\n });\n const ContactPicker = (0,vue__WEBPACK_IMPORTED_MODULE_16__.defineComponent)({\n name: 'ContactPicker',\n props: {\n contacts: {\n type: Array,\n default: () => []\n },\n selectedIds: {\n type: Array,\n default: () => []\n },\n keyword: {\n type: String,\n default: ''\n },\n emptyText: {\n type: String,\n default: '暂无联系人'\n }\n },\n emits: ['toggle', 'update:keyword'],\n setup(props, {\n emit\n }) {\n return () => (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('div', {\n class: 'contact-picker'\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('input', {\n value: props.keyword,\n placeholder: '搜索联系人',\n onInput: event => emit('update:keyword', event.target.value)\n }), (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('div', {\n class: 'contact-picker-list'\n }, props.contacts.length ? props.contacts.map(contact => (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('button', {\n key: contact.uid,\n type: 'button',\n class: ['contact-picker-row', {\n selected: props.selectedIds.includes(contact.uid)\n }],\n onClick: () => emit('toggle', contact.uid)\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('span', {\n class: 'contact-check'\n }, props.selectedIds.includes(contact.uid) ? '✓' : ''), contact.portrait ? (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('img', {\n class: 'conversation-avatar image-avatar',\n src: contact.portrait,\n alt: ''\n }) : (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('span', {\n class: 'conversation-avatar'\n }, contact.avatarText), (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('span', {\n class: 'contact-picker-copy'\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('strong', contact.title), (0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('small', contact.subtitle)])])) : [(0,vue__WEBPACK_IMPORTED_MODULE_16__.h)('div', {\n class: 'contact-picker-empty'\n }, props.emptyText)])]);\n }\n });\n function searchableValues(...values) {\n return values.flatMap(value => {\n if (Array.isArray(value)) {\n return value;\n }\n if (value && typeof value === 'object') {\n return Object.values(value);\n }\n return [value];\n }).map(value => String(value || '').toLowerCase()).filter(Boolean);\n }\n function matchesKeyword(values, keyword) {\n const compactKeyword = keyword.replace(/[^\\p{L}\\p{N}]+/gu, '');\n return searchableValues(values).some(value => {\n if (value.includes(keyword)) {\n return true;\n }\n if (!compactKeyword) {\n return false;\n }\n return value.replace(/[^\\p{L}\\p{N}]+/gu, '').includes(compactKeyword);\n });\n }\n function conversationTarget(item) {\n if (item.type !== 'single') {\n return String(item.target || item.raw?.target || item.id || '');\n }\n return String(item.target || item.raw?.target || item.id.replace(/^single-/, '') || '');\n }\n function contactForConversation(item) {\n const target = conversationTarget(item);\n return target ? contactsByUid.value.get(target) || null : null;\n }\n function matchesConversation(item, keyword, contact = null) {\n 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);\n }\n function matchesContact(item, keyword) {\n return matchesKeyword([item.title, item.subtitle, item.uid, item.id, item.alias, item.address, item.rawUser, item.rawFriend], keyword);\n }\n function conversationResult(item) {\n return {\n ...item,\n resultKind: 'conversation',\n resultKey: `conversation-${item.id}`\n };\n }\n function contactResult(contact) {\n return {\n id: contact.id,\n resultKind: 'contact',\n resultKey: `contact-${contact.uid || contact.id}`,\n contact,\n title: contact.title,\n subtitle: contact.subtitle,\n portrait: contact.portrait,\n avatarText: contact.avatarText,\n unread: 0\n };\n }\n function isListItemActive(item) {\n if (item.resultKind === 'conversation') {\n return item.id === conversations.activeId;\n }\n return `single-${item.contact?.uid || item.id}` === conversations.activeId;\n }\n function selectListItem(item) {\n if (item.resultKind === 'contact') {\n contacts.openChat(item.contact);\n return;\n }\n conversations.setActiveConversation(item.id);\n }\n function clearStoreMessages() {\n contacts.actionError = '';\n contacts.actionInfo = '';\n conversations.actionError = '';\n conversations.actionNotice = '';\n }\n function resetActionFields() {\n addKeyword.value = '';\n groupName.value = '';\n groupAnnouncement.value = '';\n groupWelcomeText.value = '';\n joinGroupKey.value = '';\n broadcastText.value = '';\n channelName.value = '';\n channelAnnouncement.value = '';\n contactKeyword.value = '';\n selectedContactIds.value = [];\n clearStoreMessages();\n }\n function toggleActionMenu() {\n actionMenuOpen.value = !actionMenuOpen.value;\n }\n function closeActionMenu() {\n actionMenuOpen.value = false;\n }\n function openAction(action) {\n resetActionFields();\n activeAction.value = action;\n actionMenuOpen.value = false;\n if (['createGroup', 'broadcast', 'createChannel'].includes(action)) {\n contacts.refreshContacts({\n force: true\n });\n }\n }\n function closeActionModal() {\n activeAction.value = '';\n actionBusy.value = false;\n resetActionFields();\n }\n function toggleContact(contactId) {\n const selected = new Set(selectedContactIds.value);\n if (selected.has(contactId)) {\n selected.delete(contactId);\n } else {\n selected.add(contactId);\n }\n selectedContactIds.value = Array.from(selected);\n }\n async function submitAction() {\n if (submitDisabled.value || actionBusy.value) {\n return;\n }\n actionBusy.value = true;\n clearStoreMessages();\n try {\n let ok = false;\n if (activeAction.value === 'addContact') {\n ok = await contacts.addContact(addKeyword.value);\n if (ok && contacts.activeContact) {\n contacts.openChat(contacts.activeContact);\n }\n } else if (activeAction.value === 'createGroup') {\n ok = await conversations.createGroup({\n name: groupName.value,\n announcement: groupAnnouncement.value,\n welcomeText: groupWelcomeText.value,\n memberIds: selectedContactIds.value\n });\n } else if (activeAction.value === 'joinGroup') {\n ok = await conversations.joinGroup(joinGroupKey.value);\n } else if (activeAction.value === 'broadcast') {\n ok = await conversations.broadcastMessage(selectedContactIds.value, broadcastText.value);\n } else if (activeAction.value === 'createChannel') {\n ok = await conversations.createGroup({\n name: channelName.value,\n memberIds: selectedContactIds.value,\n announcement: channelAnnouncement.value,\n channel: true\n });\n }\n if (ok) {\n window.setTimeout(closeActionModal, 450);\n }\n } finally {\n actionBusy.value = false;\n }\n }\n document.addEventListener('click', closeActionMenu);\n (0,vue__WEBPACK_IMPORTED_MODULE_16__.onBeforeUnmount)(() => {\n document.removeEventListener('click', closeActionMenu);\n });\n function formatUnread(value) {\n const count = Number(value || 0);\n return count > 99 ? '99+' : String(count);\n }\n const __returned__ = {\n conversations,\n contacts,\n actionMenuOpen,\n activeAction,\n actionBusy,\n searchKeyword,\n addKeyword,\n groupName,\n groupAnnouncement,\n groupWelcomeText,\n joinGroupKey,\n broadcastText,\n channelName,\n channelAnnouncement,\n contactKeyword,\n selectedContactIds,\n actionTitles,\n submitLabels,\n actionTitle,\n submitLabel,\n modalError,\n modalInfo,\n normalizedSearchKeyword,\n contactsByUid,\n filteredConversationItems,\n filteredContacts,\n submitDisabled,\n ContactPicker,\n searchableValues,\n matchesKeyword,\n conversationTarget,\n contactForConversation,\n matchesConversation,\n matchesContact,\n conversationResult,\n contactResult,\n isListItemActive,\n selectListItem,\n clearStoreMessages,\n resetActionFields,\n toggleActionMenu,\n closeActionMenu,\n openAction,\n closeActionModal,\n toggleContact,\n submitAction,\n formatUnread,\n computed: vue__WEBPACK_IMPORTED_MODULE_16__.computed,\n defineComponent: vue__WEBPACK_IMPORTED_MODULE_16__.defineComponent,\n h: vue__WEBPACK_IMPORTED_MODULE_16__.h,\n onBeforeUnmount: vue__WEBPACK_IMPORTED_MODULE_16__.onBeforeUnmount,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_16__.onMounted,\n ref: vue__WEBPACK_IMPORTED_MODULE_16__.ref,\n get useConversationStore() {\n return _stores_conversations__WEBPACK_IMPORTED_MODULE_17__.useConversationStore;\n },\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_18__.useContactStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ConversationList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*******************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*******************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/stores/session */ \"./src/stores/session.js\");\n/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/stores/navigation */ \"./src/stores/navigation.js\");\n/* harmony import */ var _stores_contacts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/stores/contacts */ \"./src/stores/contacts.js\");\n\n\n\n\n\n\nconst CROP_OUTPUT_SIZE = 512;\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n __name: 'NavigationRail',\n setup(__props, {\n expose: __expose\n }) {\n __expose();\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_3__.useSessionStore)();\n const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_4__.useNavigationStore)();\n const contacts = (0,_stores_contacts__WEBPACK_IMPORTED_MODULE_5__.useContactStore)();\n const settingsItems = [{\n key: 'notifications',\n label: '通知设置'\n }, {\n key: 'password',\n label: '更改密码'\n }, {\n key: 'wallet',\n label: '钱包管理'\n }, {\n key: 'language',\n label: '切换语言'\n }, {\n key: 'feedback',\n label: '问题反馈'\n }];\n const initials = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => (session.displayName || session.userId || 'Q').slice(0, 1).toUpperCase());\n const settingsOpen = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\n const settingsSection = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('password');\n const passwordSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\n const settingsNotice = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const settingsError = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const profileOpen = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\n const profileSaving = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\n const profileNotice = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const profileError = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const profileFile = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(null);\n const profilePreview = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)('');\n const portraitInput = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(null);\n const cropperCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(null);\n const cropperPreviewCanvas = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(null);\n const profileDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)({\n displayName: ''\n });\n const passwordDraft = (0,vue__WEBPACK_IMPORTED_MODULE_2__.reactive)({\n oldPassword: '',\n newPassword: '',\n confirmPassword: ''\n });\n const currentAvatarUrl = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => profilePreview.value || session.portrait || '');\n const activeSettingsItem = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => settingsItems.find(item => item.key === settingsSection.value) || settingsItems[0]);\n const avatarPreviewViewer = (0,vue__WEBPACK_IMPORTED_MODULE_2__.reactive)({\n open: false,\n url: '',\n scale: 1,\n offsetX: 0,\n offsetY: 0,\n dragging: false,\n dragStartX: 0,\n dragStartY: 0,\n dragOffsetX: 0,\n dragOffsetY: 0\n });\n const avatarCropper = (0,vue__WEBPACK_IMPORTED_MODULE_2__.reactive)({\n open: false,\n loaded: false,\n busy: false,\n error: '',\n objectUrl: '',\n fileName: 'avatar.jpg',\n image: null,\n baseScale: 1,\n scale: 1,\n rotation: 0,\n offsetX: 0,\n offsetY: 0,\n dragging: false,\n dragStartX: 0,\n dragStartY: 0,\n dragOffsetX: 0,\n dragOffsetY: 0\n });\n const avatarPreviewStyle = (0,vue__WEBPACK_IMPORTED_MODULE_2__.computed)(() => ({\n transform: `translate3d(${avatarPreviewViewer.offsetX}px, ${avatarPreviewViewer.offsetY}px, 0) scale(${avatarPreviewViewer.scale})`\n }));\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onMounted)(() => {\n session.refreshProfile();\n window.addEventListener('resize', drawAvatarCropper);\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onBeforeUnmount)(() => {\n revokeProfilePreview();\n closeAvatarCropper();\n window.removeEventListener('resize', drawAvatarCropper);\n });\n function showContacts() {\n navigation.showContacts();\n contacts.refreshContacts();\n }\n function clearProfileFeedback() {\n profileNotice.value = '';\n profileError.value = '';\n }\n function clearSettingsFeedback() {\n settingsNotice.value = '';\n settingsError.value = '';\n }\n function resetPasswordDraft() {\n passwordDraft.oldPassword = '';\n passwordDraft.newPassword = '';\n passwordDraft.confirmPassword = '';\n }\n function openSettings() {\n settingsOpen.value = true;\n settingsSection.value = 'password';\n clearSettingsFeedback();\n }\n function closeSettings() {\n if (passwordSaving.value) {\n return;\n }\n settingsOpen.value = false;\n clearSettingsFeedback();\n resetPasswordDraft();\n }\n function selectSettingsSection(section) {\n settingsSection.value = section;\n clearSettingsFeedback();\n }\n function revokeProfilePreview() {\n if (profilePreview.value) {\n URL.revokeObjectURL(profilePreview.value);\n profilePreview.value = '';\n }\n }\n function revokeCropperObjectUrl() {\n if (avatarCropper.objectUrl) {\n URL.revokeObjectURL(avatarCropper.objectUrl);\n avatarCropper.objectUrl = '';\n }\n }\n async function openProfileEditor() {\n profileOpen.value = true;\n clearProfileFeedback();\n profileDraft.value.displayName = session.displayName || session.userId || '';\n const profile = await session.refreshProfile();\n if (profileOpen.value && profile) {\n profileDraft.value.displayName = session.displayName || session.userId || '';\n }\n }\n function closeProfileEditor() {\n profileOpen.value = false;\n profileFile.value = null;\n clearProfileFeedback();\n revokeProfilePreview();\n closeAvatarPreview();\n closeAvatarCropper();\n }\n function selectPortrait(event) {\n const file = event.target.files?.[0] || null;\n event.target.value = '';\n clearProfileFeedback();\n if (file) {\n openAvatarCropper(file);\n }\n }\n function choosePortraitFile() {\n portraitInput.value?.click();\n }\n function openAvatarPreview() {\n if (!currentAvatarUrl.value) {\n return;\n }\n avatarPreviewViewer.open = true;\n avatarPreviewViewer.url = currentAvatarUrl.value;\n resetAvatarPreview();\n }\n function closeAvatarPreview() {\n avatarPreviewViewer.open = false;\n avatarPreviewViewer.dragging = false;\n }\n function resetAvatarPreview() {\n avatarPreviewViewer.scale = 1;\n avatarPreviewViewer.offsetX = 0;\n avatarPreviewViewer.offsetY = 0;\n }\n function zoomAvatarPreview(factor) {\n avatarPreviewViewer.scale = Math.max(0.5, Math.min(6, Number((avatarPreviewViewer.scale * factor).toFixed(2))));\n if (avatarPreviewViewer.scale <= 1) {\n avatarPreviewViewer.offsetX = 0;\n avatarPreviewViewer.offsetY = 0;\n }\n }\n function handleAvatarPreviewWheel(event) {\n zoomAvatarPreview(event.deltaY < 0 ? 1.12 : 1 / 1.12);\n }\n function startAvatarPreviewDrag(event) {\n if (avatarPreviewViewer.scale <= 1) {\n return;\n }\n avatarPreviewViewer.dragging = true;\n avatarPreviewViewer.dragStartX = event.clientX;\n avatarPreviewViewer.dragStartY = event.clientY;\n avatarPreviewViewer.dragOffsetX = avatarPreviewViewer.offsetX;\n avatarPreviewViewer.dragOffsetY = avatarPreviewViewer.offsetY;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n }\n function moveAvatarPreviewDrag(event) {\n if (!avatarPreviewViewer.dragging) {\n return;\n }\n avatarPreviewViewer.offsetX = avatarPreviewViewer.dragOffsetX + event.clientX - avatarPreviewViewer.dragStartX;\n avatarPreviewViewer.offsetY = avatarPreviewViewer.dragOffsetY + event.clientY - avatarPreviewViewer.dragStartY;\n }\n function stopAvatarPreviewDrag() {\n avatarPreviewViewer.dragging = false;\n }\n function dropPortrait(event) {\n const file = Array.from(event.dataTransfer?.files || []).find(item => item.type.startsWith('image/'));\n if (file) {\n clearProfileFeedback();\n openAvatarCropper(file);\n }\n }\n function cropperStageSize() {\n const canvas = cropperCanvas.value;\n const rect = canvas?.getBoundingClientRect();\n const width = Math.max(280, Math.round(rect?.width || 360));\n const height = Math.max(280, Math.round(rect?.height || 360));\n return {\n width,\n height\n };\n }\n function cropperBoxSize() {\n const {\n width,\n height\n } = cropperStageSize();\n return Math.round(Math.min(width, height) * 0.74);\n }\n function rotatedImageSize() {\n const image = avatarCropper.image;\n if (!image) {\n return {\n width: 1,\n height: 1\n };\n }\n const quarterTurn = Math.abs(avatarCropper.rotation % 180) === 90;\n return {\n width: quarterTurn ? image.naturalHeight : image.naturalWidth,\n height: quarterTurn ? image.naturalWidth : image.naturalHeight\n };\n }\n function clampCropperOffset() {\n const cropSize = cropperBoxSize();\n const rotated = rotatedImageSize();\n const scaledWidth = rotated.width * avatarCropper.scale;\n const scaledHeight = rotated.height * avatarCropper.scale;\n const maxX = Math.max(0, (scaledWidth - cropSize) / 2);\n const maxY = Math.max(0, (scaledHeight - cropSize) / 2);\n avatarCropper.offsetX = Math.max(-maxX, Math.min(maxX, avatarCropper.offsetX));\n avatarCropper.offsetY = Math.max(-maxY, Math.min(maxY, avatarCropper.offsetY));\n }\n function updateCropperBaseScale() {\n const cropSize = cropperBoxSize();\n const rotated = rotatedImageSize();\n avatarCropper.baseScale = Math.max(cropSize / rotated.width, cropSize / rotated.height);\n avatarCropper.scale = Math.max(avatarCropper.baseScale, avatarCropper.scale || avatarCropper.baseScale);\n }\n function drawCanvasImage(canvas, width, height, outputScale = 1, cropOnly = false) {\n const image = avatarCropper.image;\n if (!canvas || !image) {\n return;\n }\n const dpr = cropOnly ? 1 : window.devicePixelRatio || 1;\n canvas.width = Math.round(width * dpr);\n canvas.height = Math.round(height * dpr);\n const context = canvas.getContext('2d');\n context.setTransform(dpr, 0, 0, dpr, 0, 0);\n context.clearRect(0, 0, width, height);\n context.fillStyle = '#eef4f7';\n context.fillRect(0, 0, width, height);\n context.save();\n context.translate(width / 2 + avatarCropper.offsetX * outputScale, height / 2 + avatarCropper.offsetY * outputScale);\n context.rotate(avatarCropper.rotation * Math.PI / 180);\n context.scale(avatarCropper.scale * outputScale, avatarCropper.scale * outputScale);\n context.drawImage(image, -image.naturalWidth / 2, -image.naturalHeight / 2);\n context.restore();\n if (!cropOnly) {\n const cropSize = cropperBoxSize();\n context.save();\n context.fillStyle = 'rgba(10, 18, 30, 0.42)';\n context.beginPath();\n context.rect(0, 0, width, height);\n context.rect((width - cropSize) / 2, (height - cropSize) / 2, cropSize, cropSize);\n context.fill('evenodd');\n context.restore();\n }\n }\n function drawAvatarCropper() {\n if (!avatarCropper.open || !avatarCropper.loaded) {\n return;\n }\n clampCropperOffset();\n const {\n width,\n height\n } = cropperStageSize();\n drawCanvasImage(cropperCanvas.value, width, height);\n const previewCanvas = cropperPreviewCanvas.value;\n if (previewCanvas) {\n drawCanvasImage(previewCanvas, 108, 108, 108 / cropperBoxSize(), true);\n }\n }\n function resetCropperTransform() {\n if (!avatarCropper.image) {\n return;\n }\n avatarCropper.rotation = 0;\n avatarCropper.offsetX = 0;\n avatarCropper.offsetY = 0;\n updateCropperBaseScale();\n avatarCropper.scale = avatarCropper.baseScale;\n drawAvatarCropper();\n }\n function openAvatarCropper(file) {\n if (!file.type.startsWith('image/')) {\n profileError.value = '请选择图片文件';\n return;\n }\n if (file.size > 8 * 1024 * 1024) {\n profileError.value = '头像图片不能超过8MB';\n return;\n }\n closeAvatarCropper();\n avatarCropper.open = true;\n avatarCropper.loaded = false;\n avatarCropper.error = '';\n avatarCropper.fileName = file.name || 'avatar.jpg';\n avatarCropper.objectUrl = URL.createObjectURL(file);\n const image = new Image();\n image.onload = () => {\n avatarCropper.image = image;\n avatarCropper.loaded = true;\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.nextTick)(resetCropperTransform);\n };\n image.onerror = () => {\n avatarCropper.error = '图片加载失败';\n avatarCropper.loaded = false;\n };\n image.src = avatarCropper.objectUrl;\n }\n function closeAvatarCropper() {\n avatarCropper.open = false;\n avatarCropper.loaded = false;\n avatarCropper.busy = false;\n avatarCropper.error = '';\n avatarCropper.image = null;\n avatarCropper.dragging = false;\n revokeCropperObjectUrl();\n }\n function zoomCropper(factor) {\n if (!avatarCropper.loaded) {\n return;\n }\n updateCropperBaseScale();\n avatarCropper.scale = Math.max(avatarCropper.baseScale, Math.min(avatarCropper.baseScale * 6, avatarCropper.scale * factor));\n drawAvatarCropper();\n }\n function rotateCropper(degrees) {\n if (!avatarCropper.loaded) {\n return;\n }\n avatarCropper.rotation = (avatarCropper.rotation + degrees + 360) % 360;\n updateCropperBaseScale();\n clampCropperOffset();\n drawAvatarCropper();\n }\n function handleCropperWheel(event) {\n zoomCropper(event.deltaY < 0 ? 1.08 : 1 / 1.08);\n }\n function startCropperDrag(event) {\n if (!avatarCropper.loaded) {\n return;\n }\n avatarCropper.dragging = true;\n avatarCropper.dragStartX = event.clientX;\n avatarCropper.dragStartY = event.clientY;\n avatarCropper.dragOffsetX = avatarCropper.offsetX;\n avatarCropper.dragOffsetY = avatarCropper.offsetY;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n }\n function moveCropperDrag(event) {\n if (!avatarCropper.dragging) {\n return;\n }\n avatarCropper.offsetX = avatarCropper.dragOffsetX + event.clientX - avatarCropper.dragStartX;\n avatarCropper.offsetY = avatarCropper.dragOffsetY + event.clientY - avatarCropper.dragStartY;\n drawAvatarCropper();\n }\n function stopCropperDrag() {\n avatarCropper.dragging = false;\n }\n function canvasToBlob(canvas, type = 'image/jpeg', quality = 0.9) {\n return new Promise((resolve, reject) => {\n canvas.toBlob(blob => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error('头像裁切失败'));\n }\n }, type, quality);\n });\n }\n async function confirmAvatarCrop() {\n if (!avatarCropper.loaded || avatarCropper.busy) {\n return;\n }\n avatarCropper.busy = true;\n avatarCropper.error = '';\n try {\n const outputCanvas = document.createElement('canvas');\n drawCanvasImage(outputCanvas, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE, CROP_OUTPUT_SIZE / cropperBoxSize(), true);\n const blob = await canvasToBlob(outputCanvas);\n const fileName = avatarCropper.fileName.replace(/\\.[^.]+$/, '') || 'avatar';\n const croppedFile = new File([blob], `${fileName}.jpg`, {\n type: 'image/jpeg'\n });\n profileFile.value = croppedFile;\n revokeProfilePreview();\n profilePreview.value = URL.createObjectURL(croppedFile);\n closeAvatarCropper();\n } catch (error) {\n avatarCropper.error = error.message || '头像裁切失败';\n } finally {\n avatarCropper.busy = false;\n }\n }\n async function saveProfile() {\n if (profileSaving.value || !profileDraft.value.displayName) {\n return;\n }\n clearProfileFeedback();\n profileSaving.value = true;\n try {\n await session.saveProfile({\n displayName: profileDraft.value.displayName,\n portraitFile: profileFile.value\n });\n profileFile.value = null;\n revokeProfilePreview();\n profileNotice.value = '资料已保存';\n contacts.refreshContacts({\n force: true\n });\n } catch (error) {\n profileError.value = error.message || '资料保存失败';\n } finally {\n profileSaving.value = false;\n }\n }\n async function savePassword() {\n if (passwordSaving.value) {\n return;\n }\n clearSettingsFeedback();\n const oldPassword = passwordDraft.oldPassword;\n const newPassword = passwordDraft.newPassword;\n const confirmPassword = passwordDraft.confirmPassword;\n if (!oldPassword || !newPassword || !confirmPassword) {\n settingsError.value = '请填写完整密码';\n return;\n }\n if (newPassword !== confirmPassword) {\n settingsError.value = '两次输入的新密码不一致';\n return;\n }\n if (oldPassword === newPassword) {\n settingsError.value = '新密码不能和当前密码相同';\n return;\n }\n passwordSaving.value = true;\n try {\n await session.changePassword({\n oldPassword,\n newPassword\n });\n resetPasswordDraft();\n settingsNotice.value = '密码已更新';\n } catch (error) {\n settingsError.value = error.message || '密码修改失败';\n } finally {\n passwordSaving.value = false;\n }\n }\n function logout() {\n closeSettings();\n contacts.clearContacts();\n session.logout();\n }\n const __returned__ = {\n session,\n navigation,\n contacts,\n settingsItems,\n initials,\n settingsOpen,\n settingsSection,\n passwordSaving,\n settingsNotice,\n settingsError,\n profileOpen,\n profileSaving,\n profileNotice,\n profileError,\n profileFile,\n profilePreview,\n portraitInput,\n cropperCanvas,\n cropperPreviewCanvas,\n profileDraft,\n passwordDraft,\n currentAvatarUrl,\n activeSettingsItem,\n avatarPreviewViewer,\n avatarCropper,\n avatarPreviewStyle,\n CROP_OUTPUT_SIZE,\n showContacts,\n clearProfileFeedback,\n clearSettingsFeedback,\n resetPasswordDraft,\n openSettings,\n closeSettings,\n selectSettingsSection,\n revokeProfilePreview,\n revokeCropperObjectUrl,\n openProfileEditor,\n closeProfileEditor,\n selectPortrait,\n choosePortraitFile,\n openAvatarPreview,\n closeAvatarPreview,\n resetAvatarPreview,\n zoomAvatarPreview,\n handleAvatarPreviewWheel,\n startAvatarPreviewDrag,\n moveAvatarPreviewDrag,\n stopAvatarPreviewDrag,\n dropPortrait,\n cropperStageSize,\n cropperBoxSize,\n rotatedImageSize,\n clampCropperOffset,\n updateCropperBaseScale,\n drawCanvasImage,\n drawAvatarCropper,\n resetCropperTransform,\n openAvatarCropper,\n closeAvatarCropper,\n zoomCropper,\n rotateCropper,\n handleCropperWheel,\n startCropperDrag,\n moveCropperDrag,\n stopCropperDrag,\n canvasToBlob,\n confirmAvatarCrop,\n saveProfile,\n savePassword,\n logout,\n computed: vue__WEBPACK_IMPORTED_MODULE_2__.computed,\n nextTick: vue__WEBPACK_IMPORTED_MODULE_2__.nextTick,\n onBeforeUnmount: vue__WEBPACK_IMPORTED_MODULE_2__.onBeforeUnmount,\n onMounted: vue__WEBPACK_IMPORTED_MODULE_2__.onMounted,\n reactive: vue__WEBPACK_IMPORTED_MODULE_2__.reactive,\n ref: vue__WEBPACK_IMPORTED_MODULE_2__.ref,\n get useSessionStore() {\n return _stores_session__WEBPACK_IMPORTED_MODULE_3__.useSessionStore;\n },\n get useNavigationStore() {\n return _stores_navigation__WEBPACK_IMPORTED_MODULE_4__.useNavigationStore;\n },\n get useContactStore() {\n return _stores_contacts__WEBPACK_IMPORTED_MODULE_5__.useContactStore;\n }\n };\n Object.defineProperty(__returned__, '__isScriptSetup', {\n enumerable: false,\n value: true\n });\n return __returned__;\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/NavigationRail.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90":
|
||
/*!******************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90 ***!
|
||
\******************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return !$setup.session.isAuthenticated ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"LoginView\"], {\n key: 0\n })) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"ChatShell\"], {\n key: 1\n }));\n}\n\n//# sourceURL=webpack://jc-web-im/./src/App.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=template&id=2fe58db8":
|
||
/*!***********************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=template&id=2fe58db8 ***!
|
||
\***********************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"app-shell\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"main\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)($setup[\"NavigationRail\"]), $setup.navigation.section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"ConversationList\"], {\n key: 0\n })) : $setup.navigation.section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"FavoriteList\"], {\n key: 1\n })) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"ContactList\"], {\n key: 2\n })), $setup.navigation.section === 'messages' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"ChatPanel\"], {\n key: 3\n })) : $setup.navigation.section === 'favorites' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"FavoritePanel\"], {\n key: 4\n })) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)($setup[\"ContactPanel\"], {\n key: 5\n }))]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/ChatShell.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=template&id=37959aa4":
|
||
/*!***********************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=template&id=37959aa4 ***!
|
||
\***********************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"login-page\"\n};\nconst _hoisted_2 = {\n class: \"login-panel\"\n};\nconst _hoisted_3 = {\n class: \"brand-lockup\"\n};\nconst _hoisted_4 = [\"src\", \"alt\"];\nconst _hoisted_5 = {\n class: \"login-tabs register-tabs\",\n style: {\n gridTemplateColumns: 'repeat(3, minmax(0, 1fr))'\n }\n};\nconst _hoisted_6 = [\"disabled\"];\nconst _hoisted_7 = [\"src\"];\nconst _hoisted_8 = {\n key: 1\n};\nconst _hoisted_9 = {\n key: 0,\n class: \"qr-scan-user\"\n};\nconst _hoisted_10 = [\"src\"];\nconst _hoisted_11 = {\n key: 1\n};\nconst _hoisted_12 = {\n class: \"qr-login-status\"\n};\nconst _hoisted_13 = [\"disabled\"];\nconst _hoisted_14 = [\"autocomplete\", \"inputmode\", \"placeholder\"];\nconst _hoisted_15 = [\"disabled\"];\nconst _hoisted_16 = {\n key: 2,\n class: \"form-error\"\n};\nconst _hoisted_17 = {\n key: 3,\n class: \"form-info\"\n};\nconst _hoisted_18 = {\n class: \"login-tabs register-tabs\",\n style: {\n gridTemplateColumns: 'repeat(2, minmax(0, 1fr))'\n }\n};\nconst _hoisted_19 = [\"autocomplete\", \"inputmode\", \"placeholder\"];\nconst _hoisted_20 = {\n key: 0\n};\nconst _hoisted_21 = {\n class: \"code-row\"\n};\nconst _hoisted_22 = [\"disabled\"];\nconst _hoisted_23 = [\"disabled\"];\nconst _hoisted_24 = {\n key: 1,\n class: \"form-error\"\n};\nconst _hoisted_25 = {\n key: 2,\n class: \"form-info\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"main\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"img\", {\n class: \"brand-mark\",\n src: $setup.platformLogo,\n alt: `${$setup.platformName} logo`,\n onError: $setup.handleBrandLogoError\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h1\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.platformName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\" <p>按照最新 App Server 文档接入的 Web IM 客户端</p> \")])]), $setup.view === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"form\", {\n key: 0,\n class: \"login-form\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submitLogin, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.loginMode === 'qr'\n }),\n onClick: _cache[0] || (_cache[0] = $event => $setup.setLoginMode('qr'))\n }, \"扫码登录\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.loginMode === 'phone'\n }),\n onClick: _cache[1] || (_cache[1] = $event => $setup.setLoginMode('phone'))\n }, \"手机号\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.loginMode === 'email'\n }),\n onClick: _cache[2] || (_cache[2] = $event => $setup.setLoginMode('email'))\n }, \"邮箱\", 2 /* CLASS */)]), $setup.loginMode === 'qr' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 0\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"qr-login-card\", {\n scanned: $setup.qrStatus === 'scanned',\n expired: $setup.qrStatus === 'expired',\n error: $setup.qrStatus === 'error'\n }])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"qr-code-button\",\n disabled: $setup.qrStatus === 'loading' || $setup.session.connecting,\n onClick: $setup.refreshQrLogin\n }, [$setup.qrCodeImage ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n src: $setup.qrCodeImage,\n alt: \"扫码登录二维码\"\n }, null, 8 /* PROPS */, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.qrStatus === 'loading' ? '生成中' : '点击刷新'), 1 /* TEXT */))], 8 /* PROPS */, _hoisted_6), $setup.qrStatus === 'scanned' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_9, [$setup.qrUserPortrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n src: $setup.qrUserPortrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_10)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.qrUserInitial), 1 /* TEXT */))])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.qrStatusTitle), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.qrStatusText), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-action\",\n disabled: $setup.qrStatus === 'loading' || $setup.session.connecting,\n onClick: $setup.refreshQrLogin\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.qrRefreshText), 9 /* TEXT, PROPS */, _hoisted_13)], 64 /* STABLE_FRAGMENT */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 1\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.loginMode === 'phone' ? '手机号' : '邮箱'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = $event => $setup.loginAccount = $event),\n autocomplete: $setup.loginMode === 'phone' ? 'username' : 'email',\n inputmode: $setup.loginMode === 'phone' ? 'tel' : 'email',\n placeholder: $setup.loginMode === 'phone' ? '请输入手机号' : '请输入邮箱'\n }, null, 8 /* PROPS */, _hoisted_14), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.loginAccount, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[4] || (_cache[4] = $event => $setup.loginPassword = $event),\n autocomplete: \"current-password\",\n type: \"password\",\n placeholder: \"请输入密码\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.loginPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-action\",\n disabled: $setup.session.connecting || !$setup.canSubmitLogin\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.session.connecting ? '登录中...' : '登录'), 9 /* TEXT, PROPS */, _hoisted_15)], 64 /* STABLE_FRAGMENT */)), $setup.session.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.session.error), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.info ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.info), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 32 /* NEED_HYDRATION */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"form\", {\n key: 1,\n class: \"login-form\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submitRegister, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_18, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.registerType === 1\n }),\n onClick: _cache[5] || (_cache[5] = $event => $setup.switchRegisterType(1))\n }, \"手机号注册\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.registerType === 2\n }),\n onClick: _cache[6] || (_cache[6] = $event => $setup.switchRegisterType(2))\n }, \"邮箱注册\", 2 /* CLASS */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.registerType === 1 ? '手机号' : '邮箱'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[7] || (_cache[7] = $event => $setup.registerForm.number = $event),\n autocomplete: $setup.registerType === 1 ? 'tel' : 'email',\n inputmode: $setup.registerType === 1 ? 'tel' : 'email',\n placeholder: $setup.registerType === 1 ? '请输入手机号' : '请输入邮箱'\n }, null, 8 /* PROPS */, _hoisted_19), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.registerForm.number, void 0, {\n trim: true\n }]])]), $setup.registerType === 2 ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"label\", _hoisted_20, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"邮箱验证码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[8] || (_cache[8] = $event => $setup.registerForm.code = $event),\n autocomplete: \"one-time-code\",\n inputmode: \"numeric\",\n placeholder: \"请输入邮箱验证码\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.registerForm.code, void 0, {\n trim: true\n }]]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"code-action\",\n disabled: $setup.sendingCode || !$setup.canRequestEmailCode,\n onClick: $setup.requestEmailCode\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.sendingCode ? '发送中' : '发送验证码'), 9 /* TEXT, PROPS */, _hoisted_22)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[9] || (_cache[9] = $event => $setup.registerForm.password = $event),\n autocomplete: \"new-password\",\n type: \"password\",\n placeholder: \"请输入密码\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.registerForm.password]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"确认密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[10] || (_cache[10] = $event => $setup.registerForm.confirmPassword = $event),\n autocomplete: \"new-password\",\n type: \"password\",\n placeholder: \"请再次输入密码\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.registerForm.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"邀请码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[11] || (_cache[11] = $event => $setup.registerForm.invitationCode = $event),\n autocomplete: \"off\",\n placeholder: \"没有可留空\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.registerForm.invitationCode, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-action\",\n disabled: $setup.session.connecting || !$setup.canSubmitRegister\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.session.connecting ? '注册中...' : '注册并登录'), 9 /* TEXT, PROPS */, _hoisted_23), $setup.session.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.session.error), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.info ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.info), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 32 /* NEED_HYDRATION */)), $setup.view === 'login' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 2,\n class: \"ghost-action\",\n type: \"button\",\n onClick: $setup.openRegister\n }, \" 新用户注册 \")) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 3,\n class: \"ghost-action\",\n type: \"button\",\n onClick: $setup.backToLogin\n }, \" 返回登录 \"))])]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/LoginView.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705":
|
||
/*!****************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705 ***!
|
||
\****************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\n\nconst _hoisted_1 = {\n class: \"chat-panel\"\n};\nconst _hoisted_2 = {\n class: \"chat-header\"\n};\nconst _hoisted_3 = [\"src\"];\nconst _hoisted_4 = {\n key: 1,\n class: \"chat-title-avatar\"\n};\nconst _hoisted_5 = {\n class: \"chat-title-copy\"\n};\nconst _hoisted_6 = [\"src\"];\nconst _hoisted_7 = {\n key: 1,\n class: \"chat-title-avatar\"\n};\nconst _hoisted_8 = {\n class: \"chat-title-copy\"\n};\nconst _hoisted_9 = {\n key: 2\n};\nconst _hoisted_10 = {\n class: \"header-actions chat-header-actions\"\n};\nconst _hoisted_11 = {\n key: 0,\n class: \"empty-chat\"\n};\nconst _hoisted_12 = {\n key: 2,\n class: \"selection-toolbar\"\n};\nconst _hoisted_13 = {\n class: \"forward-dialog\"\n};\nconst _hoisted_14 = [\"onClick\"];\nconst _hoisted_15 = {\n class: \"conversation-avatar\"\n};\nconst _hoisted_16 = {\n type: \"submit\"\n};\nconst _hoisted_17 = {\n class: \"group-dialog message-detail-dialog\"\n};\nconst _hoisted_18 = {\n key: 0,\n class: \"group-loading\"\n};\nconst _hoisted_19 = {\n class: \"group-profile message-detail-meta\"\n};\nconst _hoisted_20 = {\n key: 0\n};\nconst _hoisted_21 = {\n key: 0,\n class: \"inline-save-status error\"\n};\nconst _hoisted_22 = {\n class: \"message-detail-summary\"\n};\nconst _hoisted_23 = {\n class: \"message-detail-groups\"\n};\nconst _hoisted_24 = {\n class: \"message-detail-section\"\n};\nconst _hoisted_25 = {\n key: 0,\n class: \"message-detail-member-list\"\n};\nconst _hoisted_26 = [\"src\"];\nconst _hoisted_27 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_28 = {\n class: \"message-detail-member-main\"\n};\nconst _hoisted_29 = {\n class: \"message-detail-member-time\"\n};\nconst _hoisted_30 = {\n key: 2,\n class: \"message-detail-role\"\n};\nconst _hoisted_31 = {\n key: 1,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_32 = {\n class: \"message-detail-section\"\n};\nconst _hoisted_33 = {\n key: 0,\n class: \"message-detail-member-list\"\n};\nconst _hoisted_34 = [\"src\"];\nconst _hoisted_35 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_36 = {\n class: \"message-detail-member-main\"\n};\nconst _hoisted_37 = {\n class: \"message-detail-member-time\"\n};\nconst _hoisted_38 = {\n key: 2,\n class: \"message-detail-role\"\n};\nconst _hoisted_39 = {\n key: 1,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_40 = {\n class: \"message-detail-section\"\n};\nconst _hoisted_41 = {\n key: 0,\n class: \"message-detail-member-list\"\n};\nconst _hoisted_42 = [\"src\"];\nconst _hoisted_43 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_44 = {\n class: \"message-detail-member-main\"\n};\nconst _hoisted_45 = {\n key: 2,\n class: \"message-detail-role\"\n};\nconst _hoisted_46 = {\n key: 1,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_47 = {\n class: \"group-dialog single-profile-dialog\"\n};\nconst _hoisted_48 = {\n class: \"single-profile-summary\"\n};\nconst _hoisted_49 = [\"src\"];\nconst _hoisted_50 = {\n key: 1,\n class: \"profile-avatar\"\n};\nconst _hoisted_51 = {\n class: \"group-profile\"\n};\nconst _hoisted_52 = {\n class: \"single-profile-footer\"\n};\nconst _hoisted_53 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_54 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_55 = [\"disabled\"];\nconst _hoisted_56 = [\"disabled\"];\nconst _hoisted_57 = {\n key: 0,\n class: \"group-dialog\"\n};\nconst _hoisted_58 = {\n key: 0,\n class: \"group-loading\"\n};\nconst _hoisted_59 = {\n key: 1,\n class: \"group-profile\"\n};\nconst _hoisted_60 = [\"disabled\"];\nconst _hoisted_61 = [\"disabled\"];\nconst _hoisted_62 = [\"disabled\"];\nconst _hoisted_63 = {\n key: 1,\n class: \"group-dialog\"\n};\nconst _hoisted_64 = {\n key: 0,\n class: \"group-loading\"\n};\nconst _hoisted_65 = {\n key: 1,\n class: \"group-member-list\"\n};\nconst _hoisted_66 = [\"src\"];\nconst _hoisted_67 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_68 = {\n key: 0,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_69 = [\"disabled\"];\nconst _hoisted_70 = {\n key: 3,\n class: \"group-dialog\"\n};\nconst _hoisted_71 = {\n key: 0,\n class: \"group-loading\"\n};\nconst _hoisted_72 = {\n key: 1,\n class: \"group-member-list\"\n};\nconst _hoisted_73 = [\"onClick\"];\nconst _hoisted_74 = [\"src\"];\nconst _hoisted_75 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_76 = {\n key: 0,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_77 = [\"disabled\"];\nconst _hoisted_78 = {\n key: 4,\n class: \"group-dialog group-management-dialog\"\n};\nconst _hoisted_79 = {\n class: \"group-management-tabs\"\n};\nconst _hoisted_80 = {\n key: 0,\n class: \"group-loading\"\n};\nconst _hoisted_81 = {\n key: 1,\n class: \"group-manage-section\"\n};\nconst _hoisted_82 = {\n class: \"group-member-list\"\n};\nconst _hoisted_83 = [\"checked\", \"onChange\"];\nconst _hoisted_84 = [\"src\"];\nconst _hoisted_85 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_86 = {\n key: 0,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_87 = {\n key: 2,\n class: \"group-manage-section\"\n};\nconst _hoisted_88 = {\n key: 3,\n class: \"group-manage-section\"\n};\nconst _hoisted_89 = {\n class: \"group-member-list\"\n};\nconst _hoisted_90 = [\"checked\", \"onChange\"];\nconst _hoisted_91 = [\"src\"];\nconst _hoisted_92 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_93 = {\n key: 0,\n class: \"contact-picker-empty\"\n};\nconst _hoisted_94 = [\"disabled\"];\nconst _hoisted_95 = {\n key: 4,\n class: \"group-manage-section\"\n};\nconst _hoisted_96 = {\n key: 0,\n class: \"mute-time-grid\"\n};\nconst _hoisted_97 = {\n key: 1,\n class: \"mute-time-grid\"\n};\nconst _hoisted_98 = {\n class: \"mute-save-footer\"\n};\nconst _hoisted_99 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_100 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_101 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [$setup.isGroupConversation ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: 0,\n type: \"button\",\n class: \"chat-title-button\",\n onClick: $setup.openGroupOverview\n }, [$setup.activeConversation?.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"chat-title-avatar image-avatar\",\n src: $setup.activeConversation.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_3)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_4, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.activeConversation?.avatarText || '?'), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h2\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.activeConversation?.title || '未选择会话'), 1 /* TEXT */)])])) : $setup.activeConversation ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: 1,\n type: \"button\",\n class: \"chat-title-button\",\n onClick: $setup.openSingleProfile\n }, [$setup.singleProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"chat-title-avatar image-avatar\",\n src: $setup.singleProfile.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h2\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.activeConversation?.title || '未选择会话'), 1 /* TEXT */)])])) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"h2\", _hoisted_9, \"未选择会话\")), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.statusText), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_10, [_cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n class: \"icon-button\",\n title: \"搜索\"\n }, \"⌕\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n class: \"icon-button\",\n title: \"更多\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)($setup.toggleGroupMenu, [\"stop\"])\n }, \"⋯\"), $setup.groupMenuOpen && $setup.isGroupConversation ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 0,\n class: \"quick-action-menu chat-more-menu\",\n onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)(() => {}, [\"stop\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: $setup.openGroupMembers\n }, \"查看群员\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: $setup.openGroupAlias\n }, \"我在本群的昵称\"), $setup.canManageGroup ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: 0,\n type: \"button\",\n onClick: $setup.openGroupManage\n }, \"群组管理\")) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)])]), !$setup.activeConversation ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_11, _cache[30] || (_cache[30] = [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, \"选择一个会话\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"真实会话同步完成后,可以在左侧打开聊天\", -1 /* HOISTED */)]))) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createBlock)($setup[\"MessageList\"], {\n key: 1,\n messages: $setup.conversations.activeMessages,\n \"selection-mode\": $setup.conversations.selectionMode,\n \"selected-message-ids\": $setup.conversations.selectedMessageIds,\n \"favorite-message-ids\": $setup.conversations.favoriteMessageIds,\n \"attention-message-id\": $setup.conversations.attentionMessageId,\n \"can-recall-others\": $setup.canManageGroup && $setup.isGroupConversation,\n onMessageAction: $setup.conversations.handleMessageAction,\n onToggleSelect: $setup.conversations.toggleSelectedMessage,\n onSenderProfileUpdated: $setup.handleSenderProfileUpdated\n }, null, 8 /* PROPS */, [\"messages\", \"selection-mode\", \"selected-message-ids\", \"favorite-message-ids\", \"attention-message-id\", \"can-recall-others\", \"onMessageAction\", \"onToggleSelect\"])), $setup.conversations.selectionMode ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"已选 \" + (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.conversations.selectedMessageIds.length) + \" 条\", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[1] || (_cache[1] = (...args) => $setup.conversations.copySelectedMessages && $setup.conversations.copySelectedMessages(...args))\n }, \"复制\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[2] || (_cache[2] = (...args) => $setup.conversations.deleteSelectedMessages && $setup.conversations.deleteSelectedMessages(...args))\n }, \"删除\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[3] || (_cache[3] = (...args) => $setup.conversations.startForwardSelectedMessages && $setup.conversations.startForwardSelectedMessages(...args))\n }, \"转发\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[4] || (_cache[4] = (...args) => $setup.conversations.clearSelection && $setup.conversations.clearSelection(...args))\n }, \"取消\")])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createVNode)($setup[\"MessageComposer\"], {\n disabled: !$setup.activeConversation || !$setup.session.isAuthenticated || !$setup.conversations.canSendActiveConversation,\n \"quote-message\": $setup.conversations.quotedMessage,\n onCancelQuote: $setup.conversations.cancelQuote,\n onSend: $setup.conversations.sendText,\n onSendAttachment: $setup.conversations.sendAttachment\n }, null, 8 /* PROPS */, [\"disabled\", \"quote-message\", \"onCancelQuote\", \"onSend\", \"onSendAttachment\"]), $setup.conversations.forwardingMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 3,\n class: \"modal-backdrop\",\n onClick: _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)((...args) => $setup.conversations.cancelForward && $setup.conversations.cancelForward(...args), [\"self\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"转发给\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: _cache[5] || (_cache[5] = (...args) => $setup.conversations.cancelForward && $setup.conversations.cancelForward(...args))\n }, \"×\")]), ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.conversations.conversations, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: item.id,\n type: \"button\",\n class: \"forward-target\",\n onClick: $event => $setup.conversations.completeForward(item.id)\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(item.avatarText), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(item.title), 1 /* TEXT */)], 8 /* PROPS */, _hoisted_14);\n }), 128 /* KEYED_FRAGMENT */))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.conversations.editingMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 4,\n class: \"modal-backdrop\",\n onClick: _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)((...args) => $setup.conversations.cancelEditMessage && $setup.conversations.cancelEditMessage(...args), [\"self\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"form\", {\n class: \"edit-dialog\",\n onSubmit: _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)((...args) => $setup.conversations.completeEditMessage && $setup.conversations.completeEditMessage(...args), [\"prevent\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.conversations.editingMode === 'resend' ? '重新编辑' : '编辑消息'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: _cache[7] || (_cache[7] = (...args) => $setup.conversations.cancelEditMessage && $setup.conversations.cancelEditMessage(...args))\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[8] || (_cache[8] = $event => $setup.conversations.editingText = $event),\n maxlength: \"5000\",\n rows: \"5\",\n autofocus: \"\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.conversations.editingText]]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[9] || (_cache[9] = (...args) => $setup.conversations.cancelEditMessage && $setup.conversations.cancelEditMessage(...args))\n }, \"取消\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.conversations.editingMode === 'resend' ? '发送' : '保存'), 1 /* TEXT */)])], 32 /* NEED_HYDRATION */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.conversations.messageDetailOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 5,\n class: \"modal-backdrop\",\n onClick: _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)((...args) => $setup.conversations.closeMessageDetail && $setup.conversations.closeMessageDetail(...args), [\"self\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[32] || (_cache[32] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"消息详情\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: _cache[12] || (_cache[12] = (...args) => $setup.conversations.closeMessageDetail && $setup.conversations.closeMessageDetail(...args))\n }, \"×\")]), $setup.conversations.messageDetailLoading ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_18, \"正在加载\")) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, {\n key: 1\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dl\", _hoisted_19, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"发送时间\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.formatDetailTime($setup.messageDetail?.sentAt)), 1 /* TEXT */)]), $setup.messageDetail?.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_20, [_cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"编辑时间\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.formatDetailTime($setup.messageDetail.editedAt)), 1 /* TEXT */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[35] || (_cache[35] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"发送人\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberName($setup.messageDetail?.sender)), 1 /* TEXT */)]), !$setup.isMessageDetailGroup ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, {\n key: 1\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"接收人\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberName($setup.messageDetail?.receiver)), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[37] || (_cache[37] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"送达时间\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n 'message-detail-muted': !$setup.messageDetail?.deliveredAt\n })\n }, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetail?.deliveredAt ? $setup.formatDetailTime($setup.messageDetail.deliveredAt) : '未送达'), 3 /* TEXT, CLASS */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[38] || (_cache[38] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"已读时间\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n 'message-detail-muted': !$setup.messageDetail?.readAt\n })\n }, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetail?.readAt ? $setup.formatDetailTime($setup.messageDetail.readAt) : '未读'), 3 /* TEXT, CLASS */)])], 64 /* STABLE_FRAGMENT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]), $setup.conversations.messageDetailError ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.conversations.messageDetailError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.isMessageDetailGroup ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, {\n key: 1\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_22, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [_cache[39] || (_cache[39] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createTextVNode)(\"已读 \")), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.read || 0), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [_cache[40] || (_cache[40] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createTextVNode)(\"未读 \")), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.unread || 0), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [_cache[41] || (_cache[41] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createTextVNode)(\"未送达 \")), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.undelivered || 0), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [_cache[42] || (_cache[42] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createTextVNode)(\"成员 \")), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.total || 0), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_23, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[43] || (_cache[43] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, \"已读\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.read || 0) + \" 人\", 1 /* TEXT */)]), $setup.messageDetailGroup?.read?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_25, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.messageDetailGroup.read, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: `read-${member.uid}`,\n class: \"message-detail-member-row\"\n }, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_26)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_27, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_28, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberName(member)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.uid), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_29, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.formatDetailTime(member.time)), 1 /* TEXT */), $setup.detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_30, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailRoleLabel(member.role)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]);\n }), 128 /* KEYED_FRAGMENT */))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_31, \"暂无已读成员\"))]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_32, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[44] || (_cache[44] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, \"未读\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.unread || 0) + \" 人\", 1 /* TEXT */)]), $setup.messageDetailGroup?.unread?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_33, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.messageDetailGroup.unread, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: `unread-${member.uid}`,\n class: \"message-detail-member-row\"\n }, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_34)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_35, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_36, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberName(member)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.uid), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_37, \"送达 \" + (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.formatDetailTime(member.time)), 1 /* TEXT */), $setup.detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_38, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailRoleLabel(member.role)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]);\n }), 128 /* KEYED_FRAGMENT */))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_39, \"暂无未读成员\"))]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_40, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[45] || (_cache[45] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, \"未送达\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.messageDetailCounts.undelivered || 0) + \" 人\", 1 /* TEXT */)]), $setup.messageDetailGroup?.undelivered?.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_41, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.messageDetailGroup.undelivered, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: `undelivered-${member.uid}`,\n class: \"message-detail-member-row\"\n }, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_42)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_43, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", _hoisted_44, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailMemberName(member)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.uid), 1 /* TEXT */)]), _cache[46] || (_cache[46] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", {\n class: \"message-detail-member-time message-detail-muted\"\n }, \"未送达\", -1 /* HOISTED */)), $setup.detailRoleLabel(member.role) ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_45, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.detailRoleLabel(member.role)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]);\n }), 128 /* KEYED_FRAGMENT */))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_46, \"暂无未送达成员\"))])])], 64 /* STABLE_FRAGMENT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)], 64 /* STABLE_FRAGMENT */))])])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.singleProfileOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 6,\n class: \"modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)($setup.closeSingleProfile, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"section\", _hoisted_47, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[47] || (_cache[47] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"联系人资料\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeSingleProfile\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_48, [$setup.singleProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"profile-avatar image-avatar\",\n src: $setup.singleProfile.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_49)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_50, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.displayName), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dl\", _hoisted_51, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[48] || (_cache[48] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"用户ID\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.uid || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[49] || (_cache[49] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.rawName || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[50] || (_cache[50] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"手机号\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.mobile || '未知'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[51] || (_cache[51] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"地区\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfile.address || '未知'), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[52] || (_cache[52] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"备注名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[14] || (_cache[14] = $event => $setup.singleAliasDraft = $event),\n maxlength: \"32\",\n autocomplete: \"off\",\n placeholder: \"留空使用对方昵称\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.singleAliasDraft, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", _hoisted_52, [$setup.singleProfileNotice ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_53, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfileNotice), 1 /* TEXT */)) : $setup.singleProfileError ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_54, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfileError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n disabled: $setup.singleProfileSaving,\n onClick: $setup.closeSingleProfile\n }, \"取消\", 8 /* PROPS */, _hoisted_55), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.singleProfileSaving || !$setup.singleProfile.uid,\n onClick: $setup.saveSingleAlias\n }, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.singleProfileSaving ? '保存中...' : '保存备注'), 9 /* TEXT, PROPS */, _hoisted_56)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.groupPanel ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 7,\n class: \"modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)($setup.closeGroupPanel, [\"self\"])\n }, [$setup.groupPanel === 'overview' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_57, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[53] || (_cache[53] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"群概况\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeGroupPanel\n }, \"×\")]), $setup.groupBusy ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_58, \"正在加载\")) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"dl\", _hoisted_59, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[54] || (_cache[54] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"群名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.groupDetail?.name || $setup.activeConversation?.title || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[55] || (_cache[55] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"群ID\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.groupDetail?.groupId || $setup.activeConversation?.target || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[56] || (_cache[56] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"群说明\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.groupDetail?.announcement || '未设置'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", null, [_cache[57] || (_cache[57] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dt\", null, \"群主昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.groupDetail?.ownerName || '-'), 1 /* TEXT */)])])), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [$setup.isGroupOwner ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, {\n key: 0\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"danger-inline-action\",\n disabled: $setup.groupBusy,\n onClick: $setup.dismissCurrentGroup\n }, \"解散群组\", 8 /* PROPS */, _hoisted_60), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.groupBusy,\n onClick: $setup.openTransferGroup\n }, \"转让群组\", 8 /* PROPS */, _hoisted_61)], 64 /* STABLE_FRAGMENT */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: 1,\n type: \"button\",\n class: \"danger-inline-action\",\n disabled: $setup.groupBusy,\n onClick: $setup.leaveCurrentGroup\n }, \"退出群组\", 8 /* PROPS */, _hoisted_62))])])) : $setup.groupPanel === 'members' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_63, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[58] || (_cache[58] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"群员\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeGroupPanel\n }, \"×\")]), $setup.groupBusy ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_64, \"正在加载\")) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_65, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.groupMembers, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: member.uid,\n class: \"group-member-row\"\n }, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_66)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_67, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.memberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.displayName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.role === 'owner' ? '群主' : member.rawDisplayName), 1 /* TEXT */)])]);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.groupMembers.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_68, \"暂无群员\")) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]))])) : $setup.groupPanel === 'alias' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"form\", {\n key: 2,\n class: \"group-dialog\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_1__.withModifiers)($setup.saveGroupAlias, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[59] || (_cache[59] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"我在本群的昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeGroupPanel\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[60] || (_cache[60] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[15] || (_cache[15] = $event => $setup.groupAliasDraft = $event),\n maxlength: \"64\",\n autocomplete: \"off\",\n placeholder: \"留空使用个人昵称\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.groupAliasDraft, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.closeGroupPanel\n }, \"取消\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n class: \"primary-inline-action\",\n disabled: $setup.groupBusy\n }, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.groupBusy ? '保存中...' : '保存'), 9 /* TEXT, PROPS */, _hoisted_69)])], 32 /* NEED_HYDRATION */)) : $setup.groupPanel === 'transfer' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_70, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[61] || (_cache[61] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"转让群组\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeGroupPanel\n }, \"×\")]), $setup.groupBusy ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_71, \"正在加载\")) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_72, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.transferableMembers, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: member.uid,\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)([\"group-member-row selectable\", {\n selected: $setup.transferTargetId === member.uid\n }]),\n onClick: $event => $setup.transferTargetId = member.uid\n }, [member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_74)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_75, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.memberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.displayName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.rawDisplayName), 1 /* TEXT */)])], 10 /* CLASS, PROPS */, _hoisted_73);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.transferableMembers.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_76, \"暂无可转让成员\")) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)])), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.closeGroupPanel\n }, \"取消\"), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.groupBusy || !$setup.transferTargetId,\n onClick: $setup.transferCurrentGroup\n }, \"确认转让\", 8 /* PROPS */, _hoisted_77)])])) : $setup.groupPanel === 'manage' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_78, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"header\", null, [_cache[62] || (_cache[62] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"h3\", null, \"群组管理\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeGroupPanel\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"nav\", _hoisted_79, [$setup.isGroupOwner ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"button\", {\n key: 0,\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n active: $setup.manageSection === 'admins'\n }),\n onClick: _cache[16] || (_cache[16] = $event => $setup.manageSection = 'admins')\n }, \"管理员设置\", 2 /* CLASS */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n active: $setup.manageSection === 'profile'\n }),\n onClick: _cache[17] || (_cache[17] = $event => $setup.manageSection = 'profile')\n }, \"修改群资料\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n active: $setup.manageSection === 'kick'\n }),\n onClick: _cache[18] || (_cache[18] = $event => $setup.manageSection = 'kick')\n }, \"踢人\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)({\n active: $setup.manageSection === 'mute'\n }),\n onClick: _cache[19] || (_cache[19] = $event => $setup.manageSection = 'mute')\n }, \"禁言设置\", 2 /* CLASS */)]), $setup.groupBusy ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_80, \"正在加载\")) : $setup.manageSection === 'admins' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_81, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_82, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.adminCandidateMembers, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"label\", {\n key: member.uid,\n class: \"group-member-row selectable with-check\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n type: \"checkbox\",\n checked: $setup.selectedAdminIds.includes(member.uid),\n onChange: $event => $setup.toggleAdmin(member.uid)\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_83), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_84)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_85, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.memberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.displayName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.rawDisplayName), 1 /* TEXT */)])]);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.adminCandidateMembers.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_86, \"暂无可设置成员\")) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n onClick: $setup.saveGroupAdmins\n }, \"保存管理员\")])])) : $setup.manageSection === 'profile' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_87, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[63] || (_cache[63] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"群名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[20] || (_cache[20] = $event => $setup.profileDraft.name = $event),\n maxlength: \"128\",\n autocomplete: \"off\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.profileDraft.name, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[64] || (_cache[64] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"群说明\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[21] || (_cache[21] = $event => $setup.profileDraft.announcement = $event),\n maxlength: \"1000\",\n rows: \"3\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.profileDraft.announcement, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[65] || (_cache[65] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"欢迎词\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[22] || (_cache[22] = $event => $setup.profileDraft.welcomeText = $event),\n maxlength: \"1000\",\n rows: \"3\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.profileDraft.welcomeText, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n onClick: $setup.saveGroupProfile\n }, \"保存资料\")])])) : $setup.manageSection === 'kick' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_88, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"div\", _hoisted_89, [((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.renderList)($setup.kickCandidateMembers, member => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"label\", {\n key: member.uid,\n class: \"group-member-row selectable with-check\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n type: \"checkbox\",\n checked: $setup.selectedKickIds.includes(member.uid),\n onChange: $event => $setup.toggleKick(member.uid)\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_90), member.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: member.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_91)) : ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_92, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.memberAvatar(member)), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.displayName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)(member.role === 'admin' ? '管理员' : member.rawDisplayName), 1 /* TEXT */)])]);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.kickCandidateMembers.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_93, \"暂无可移除成员\")) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"danger-inline-action\",\n disabled: !$setup.selectedKickIds.length,\n onClick: $setup.kickSelectedMembers\n }, \"移出群组\", 8 /* PROPS */, _hoisted_94)])])) : $setup.manageSection === 'mute' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"section\", _hoisted_95, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[67] || (_cache[67] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"禁言模式\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"select\", {\n \"onUpdate:modelValue\": _cache[23] || (_cache[23] = $event => $setup.muteDraft.mode = $event),\n onChange: $setup.clearMuteSaveFeedback\n }, _cache[66] || (_cache[66] = [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"off\"\n }, \"关闭禁言\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"all_include_admins\"\n }, \"全体禁言包含管理员\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"all_except_admins\"\n }, \"除管理员外全体禁言\", -1 /* HOISTED */)]), 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelSelect, $setup.muteDraft.mode]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[69] || (_cache[69] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"时段类型\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"select\", {\n \"onUpdate:modelValue\": _cache[24] || (_cache[24] = $event => $setup.muteDraft.scheduleType = $event),\n onChange: $setup.clearMuteSaveFeedback\n }, _cache[68] || (_cache[68] = [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"manual\"\n }, \"立即禁言直到管理解除\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"once\"\n }, \"单次\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"option\", {\n value: \"daily\"\n }, \"每天固定时段\", -1 /* HOISTED */)]), 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelSelect, $setup.muteDraft.scheduleType]])]), $setup.muteDraft.mode !== 'off' && $setup.muteDraft.scheduleType === 'once' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_96, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[70] || (_cache[70] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"开始\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[25] || (_cache[25] = $event => $setup.muteDraft.startsAtLocal = $event),\n type: \"datetime-local\",\n onInput: $setup.clearMuteSaveFeedback\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.muteDraft.startsAtLocal]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[71] || (_cache[71] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"结束\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[26] || (_cache[26] = $event => $setup.muteDraft.endsAtLocal = $event),\n type: \"datetime-local\",\n onInput: $setup.clearMuteSaveFeedback\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.muteDraft.endsAtLocal]])])])) : $setup.muteDraft.mode !== 'off' && $setup.muteDraft.scheduleType === 'daily' ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", _hoisted_97, [(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[72] || (_cache[72] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"开始\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[27] || (_cache[27] = $event => $setup.muteDraft.dailyStart = $event),\n type: \"time\",\n onInput: $setup.clearMuteSaveFeedback\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.muteDraft.dailyStart]])]), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"label\", null, [_cache[73] || (_cache[73] = (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"span\", null, \"结束\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_1__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[28] || (_cache[28] = $event => $setup.muteDraft.dailyEnd = $event),\n type: \"time\",\n onInput: $setup.clearMuteSaveFeedback\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_1__.vModelText, $setup.muteDraft.dailyEnd]])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"footer\", _hoisted_98, [$setup.muteSaveNotice ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_99, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.muteSaveNotice), 1 /* TEXT */)) : $setup.muteSaveError ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"span\", _hoisted_100, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.muteSaveError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.groupBusy,\n onClick: $setup.saveMuteSetting\n }, \"保存禁言\", 8 /* PROPS */, _hoisted_101)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)])) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true), $setup.conversations.actionNotice || $setup.conversations.actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_1__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementBlock)(\"div\", {\n key: 8,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)([\"chat-toast\", {\n error: $setup.conversations.actionError\n }])\n }, (0,vue__WEBPACK_IMPORTED_MODULE_1__.toDisplayString)($setup.conversations.actionError || $setup.conversations.actionNotice), 3 /* TEXT, CLASS */)) : (0,vue__WEBPACK_IMPORTED_MODULE_1__.createCommentVNode)(\"v-if\", true)]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/ChatPanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580":
|
||
/*!**********************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580 ***!
|
||
\**********************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n key: 0,\n class: \"quote-preview\"\n};\nconst _hoisted_2 = {\n class: \"composer-tools\"\n};\nconst _hoisted_3 = [\"disabled\"];\nconst _hoisted_4 = [\"disabled\"];\nconst _hoisted_5 = [\"disabled\"];\nconst _hoisted_6 = [\"onClick\"];\nconst _hoisted_7 = [\"disabled\", \"onKeydown\"];\nconst _hoisted_8 = {\n class: \"composer-footer\"\n};\nconst _hoisted_9 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"form\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"message-composer\", {\n 'drop-active': $setup.dropActive\n }]),\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submit, [\"prevent\"]),\n onDragenter: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleDragEnter, [\"prevent\"]),\n onDragover: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleDragOver, [\"prevent\"]),\n onDragleave: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleDragLeave, [\"prevent\"]),\n onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleDrop, [\"prevent\"]),\n onPaste: $setup.handlePaste\n }, [$props.quoteMessage ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"引用\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(\" \" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.quoteMessage.quoteText || $props.quoteMessage.text), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"取消引用\",\n onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('cancel-quote'))\n }, \"×\")])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"表情\",\n disabled: $props.disabled,\n onClick: $setup.toggleEmojiPicker\n }, \"☺\", 8 /* PROPS */, _hoisted_3), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"图片\",\n disabled: $props.disabled,\n onClick: $setup.chooseImage\n }, \"▧\", 8 /* PROPS */, _hoisted_4), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"文件\",\n disabled: $props.disabled,\n onClick: $setup.chooseFile\n }, \"▤\", 8 /* PROPS */, _hoisted_5), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n ref: \"imageInput\",\n type: \"file\",\n accept: \"image/*\",\n multiple: \"\",\n onChange: _cache[1] || (_cache[1] = $event => $setup.selectAttachment($event, 'image'))\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n ref: \"fileInput\",\n type: \"file\",\n multiple: \"\",\n onChange: _cache[2] || (_cache[2] = $event => $setup.selectAttachment($event, 'file'))\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), $setup.emojiOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"emoji-picker\",\n onClick: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"]))\n }, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.emojiList, emoji => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n key: emoji,\n type: \"button\",\n onClick: $event => $setup.insertEmoji(emoji)\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(emoji), 9 /* TEXT, PROPS */, _hoisted_6);\n }), 64 /* STABLE_FRAGMENT */))])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n ref: \"textareaEl\",\n \"onUpdate:modelValue\": _cache[4] || (_cache[4] = $event => $setup.text = $event),\n disabled: $props.disabled,\n placeholder: \"输入消息\",\n rows: \"3\",\n onKeydown: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withKeys)((0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submit, [\"exact\", \"prevent\"]), [\"enter\"])\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_7), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.text]]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_8, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"Enter 发送,Shift + Enter 换行\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"send-button\",\n disabled: $props.disabled || !$setup.text.trim()\n }, \"发送\", 8 /* PROPS */, _hoisted_9)])], 34 /* CLASS, NEED_HYDRATION */);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageComposer.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04":
|
||
/*!******************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04 ***!
|
||
\******************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n ref: \"listEl\",\n class: \"message-list\"\n};\nconst _hoisted_2 = [\"data-message-key\", \"onClick\"];\nconst _hoisted_3 = {\n key: 0,\n class: \"message-select\"\n};\nconst _hoisted_4 = [\"checked\", \"onChange\"];\nconst _hoisted_5 = [\"title\", \"onClick\"];\nconst _hoisted_6 = [\"src\"];\nconst _hoisted_7 = {\n key: 1\n};\nconst _hoisted_8 = {\n class: \"message-stack\"\n};\nconst _hoisted_9 = [\"onClick\"];\nconst _hoisted_10 = {\n key: 0,\n class: \"message-sender-role\"\n};\nconst _hoisted_11 = [\"onContextmenu\"];\nconst _hoisted_12 = [\"onClick\"];\nconst _hoisted_13 = [\"src\", \"alt\"];\nconst _hoisted_14 = [\"href\"];\nconst _hoisted_15 = {\n class: \"message-file-main\"\n};\nconst _hoisted_16 = {\n key: 2\n};\nconst _hoisted_17 = {\n key: 0,\n class: \"recall-mark\"\n};\nconst _hoisted_18 = {\n key: 1,\n class: \"edit-mark\"\n};\nconst _hoisted_19 = {\n key: 2,\n class: \"favorite-mark\",\n title: \"已收藏\",\n \"aria-label\": \"已收藏\"\n};\nconst _hoisted_20 = [\"title\", \"aria-label\"];\nconst _hoisted_21 = {\n key: 0,\n class: \"delivery-check delivery-check-second\"\n};\nconst _hoisted_22 = {\n key: 4,\n class: \"delivery-error\"\n};\nconst _hoisted_23 = [\"onClick\"];\nconst _hoisted_24 = {\n class: \"image-viewer-toolbar\"\n};\nconst _hoisted_25 = {\n class: \"image-viewer-title\"\n};\nconst _hoisted_26 = [\"src\", \"alt\"];\nconst _hoisted_27 = {\n class: \"sender-profile-main\"\n};\nconst _hoisted_28 = [\"src\"];\nconst _hoisted_29 = {\n key: 1,\n class: \"profile-avatar\"\n};\nconst _hoisted_30 = {\n key: 2\n};\nconst _hoisted_31 = {\n class: \"sender-profile-fields\"\n};\nconst _hoisted_32 = {\n class: \"sender-profile-alias\"\n};\nconst _hoisted_33 = [\"disabled\"];\nconst _hoisted_34 = {\n class: \"sender-profile-actions\"\n};\nconst _hoisted_35 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_36 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_37 = [\"disabled\"];\nconst _hoisted_38 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($props.messages, message => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"article\", {\n key: message.id,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"message-row\", [message.direction, {\n selected: $setup.isSelected(message),\n attention: $setup.isAttention(message),\n recalled: message.recalled || message.status === 'recalled'\n }]]),\n \"data-message-key\": $setup.messageIdentity(message),\n onClick: $event => $setup.handleMessageClick(message)\n }, [$props.selectionMode ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"label\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n type: \"checkbox\",\n checked: $setup.isSelected(message),\n onClick: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"])),\n onChange: $event => $setup.emit('toggle-select', message)\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_4)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 1,\n type: \"button\",\n class: \"message-sender-avatar\",\n title: $setup.groupSenderName(message),\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => $setup.openSenderProfile(message), [\"stop\"])\n }, [message.senderPortrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n src: message.senderPortrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.groupSenderAvatarText(message)), 1 /* TEXT */))], 8 /* PROPS */, _hoisted_5)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_8, [$setup.showGroupSender(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 0,\n type: \"button\",\n class: \"message-sender-name\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => $setup.openSenderProfile(message), [\"stop\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)((0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.groupSenderName(message)) + \" \", 1 /* TEXT */), $setup.senderRoleLabel(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderRoleLabel(message)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 8 /* PROPS */, _hoisted_9)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"message-bubble\", $setup.roleBubbleClass(message)]),\n onContextmenu: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => $setup.openMenu($event, message), [\"prevent\"])\n }, [$setup.isImageMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 0,\n type: \"button\",\n class: \"message-image\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => $setup.handleImageClick(message), [\"stop\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"img\", {\n src: $setup.imageDisplayUrl(message.attachment.url),\n alt: message.attachment.name || '图片'\n }, null, 8 /* PROPS */, _hoisted_13)], 8 /* PROPS */, _hoisted_12)) : $setup.isFileMessage(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"a\", {\n key: 1,\n class: \"message-file\",\n href: message.attachment.url,\n target: \"_blank\",\n rel: \"noreferrer\",\n download: \"\"\n }, [_cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"message-file-icon\"\n }, \"▤\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_15, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(message.attachment.name || '文件'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatFileSize(message.attachment.size)), 1 /* TEXT */)])], 8 /* PROPS */, _hoisted_14)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), message.text ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(message.text), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"time\", null, [$setup.isRecallNotice(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(message.recallStatus || '已撤回'), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatTime(message.displayTimestamp || message.timestamp)), 1 /* TEXT */), message.editedAt ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_18, \"【edit \" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatTime(message.editedAt)) + \"】\", 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.isFavorite(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_19, \"★\")) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.deliveryState(message) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", {\n key: 3,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"delivery-mark\", `delivery-mark-${$setup.deliveryState(message)}`]),\n title: $setup.deliveryTitle(message),\n \"aria-label\": $setup.deliveryTitle(message)\n }, [_cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"delivery-check\"\n }, \"✓\", -1 /* HOISTED */)), $setup.deliveryState(message) !== 'sent' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_21, \"✓\")) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 10 /* CLASS, PROPS */, _hoisted_20)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), message.status === 'failed' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_22, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.failureText(message)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)])], 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_11)])], 10 /* CLASS, PROPS */, _hoisted_2);\n }), 128 /* KEYED_FRAGMENT */)), $setup.contextMenu.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"message-context-menu\",\n style: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle)({\n left: `${$setup.contextMenu.x}px`,\n top: `${$setup.contextMenu.y}px`\n }),\n onClick: _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"]))\n }, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.menuItems, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: item.action,\n type: \"button\",\n onClick: $event => $setup.chooseMenuAction(item.action)\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.label), 9 /* TEXT, PROPS */, _hoisted_23);\n }), 128 /* KEYED_FRAGMENT */))], 4 /* STYLE */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Teleport, {\n to: \"body\"\n }, [$setup.imageViewer.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"image-viewer-backdrop\",\n onClick: $setup.closeImageViewer\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"image-viewer-dialog\",\n onClick: _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.imageViewer.name || '图片'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"缩小\",\n \"aria-label\": \"缩小\",\n onClick: _cache[2] || (_cache[2] = $event => $setup.zoomImage(-0.25))\n }, \"−\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"放大\",\n \"aria-label\": \"放大\",\n onClick: _cache[3] || (_cache[3] = $event => $setup.zoomImage(0.25))\n }, \"+\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"还原\",\n \"aria-label\": \"还原\",\n onClick: $setup.resetImageViewer\n }, \"1:1\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"旋转\",\n \"aria-label\": \"旋转\",\n onClick: $setup.rotateImage\n }, \"⟳\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"保存\",\n \"aria-label\": \"保存\",\n onClick: $setup.saveViewerImage\n }, \"⇩\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"关闭\",\n \"aria-label\": \"关闭\",\n onClick: $setup.closeImageViewer\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n ref: \"viewerStage\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"image-viewer-stage\", {\n dragging: $setup.imageViewer.dragging,\n zoomed: $setup.imageViewer.scale > 1\n }]),\n onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleImageWheel, [\"prevent\"]),\n onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.startImageDrag, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"img\", {\n class: \"image-viewer-img\",\n src: $setup.imageViewer.url,\n alt: $setup.imageViewer.name || '图片',\n style: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle)($setup.imageViewerStyle),\n draggable: \"false\"\n }, null, 12 /* STYLE, PROPS */, _hoisted_26)], 34 /* CLASS, NEED_HYDRATION */)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)])), ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Teleport, {\n to: \"body\"\n }, [$setup.senderProfile.visible ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"sender-profile-backdrop\",\n onClick: $setup.closeSenderProfile\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", {\n class: \"sender-profile-dialog\",\n onClick: _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"用户资料\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeSenderProfile\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_27, [$setup.senderProfile.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n class: \"profile-avatar image-avatar\",\n src: $setup.senderProfile.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_28)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_29, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.displayName || $setup.senderProfile.uid), 1 /* TEXT */), $setup.senderProfile.roleLabel ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_30, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.roleLabel), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dl\", _hoisted_31, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"用户ID\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.uid || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.rawName || $setup.senderProfile.displayName || '-'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"手机号\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.mobile || '未知'), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"地区\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.address || '未知'), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", _hoisted_32, [_cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"备注名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[5] || (_cache[5] = $event => $setup.senderProfile.aliasDraft = $event),\n maxlength: \"32\",\n autocomplete: \"off\",\n placeholder: \"可给群员设置备注\",\n disabled: $setup.senderProfile.saving || $setup.senderProfile.adding\n }, null, 8 /* PROPS */, _hoisted_33), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.senderProfile.aliasDraft, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"footer\", _hoisted_34, [$setup.senderProfile.notice ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_35, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.notice), 1 /* TEXT */)) : $setup.senderProfile.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_36, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.error), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), !$setup.senderProfile.isContact ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: 2,\n type: \"button\",\n class: \"ghost-inline-action\",\n disabled: $setup.senderProfile.adding || $setup.senderProfile.saving || !$setup.senderProfile.uid,\n onClick: $setup.addSenderAsContact\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.adding ? '添加中...' : '添加为好友'), 9 /* TEXT, PROPS */, _hoisted_37)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.senderProfile.saving || $setup.senderProfile.adding || !$setup.senderProfile.uid,\n onClick: $setup.saveSenderAlias\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.senderProfile.saving ? '保存中...' : '保存备注'), 9 /* TEXT, PROPS */, _hoisted_38)])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]))], 512 /* NEED_PATCH */);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80":
|
||
/*!***********************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80 ***!
|
||
\***********************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"contact-panel\"\n};\nconst _hoisted_2 = {\n class: \"chat-header\"\n};\nconst _hoisted_3 = {\n class: \"contact-profile\"\n};\nconst _hoisted_4 = [\"src\"];\nconst _hoisted_5 = {\n key: 1,\n class: \"profile-avatar\"\n};\nconst _hoisted_6 = {\n class: \"profile-main\"\n};\nconst _hoisted_7 = {\n class: \"remark-row\"\n};\nconst _hoisted_8 = {\n class: \"profile-fields\"\n};\nconst _hoisted_9 = {\n key: 0,\n class: \"form-error\"\n};\nconst _hoisted_10 = {\n class: \"modal-actions\"\n};\nconst _hoisted_11 = [\"disabled\"];\nconst _hoisted_12 = [\"disabled\"];\nconst _hoisted_13 = {\n key: 1,\n class: \"empty-chat\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"section\", _hoisted_1, [$setup.contact ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 0\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h2\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.remarkName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.username), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [$setup.contact.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n class: \"profile-avatar image-avatar\",\n src: $setup.contact.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_4)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contact.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h3\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.remarkName), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button remark-edit-button\",\n title: \"编辑备注名\",\n onClick: $setup.openAliasEditor\n }, \"✏️\")])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dl\", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"用户名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.username), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"手机号\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.mobile), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dt\", null, \"地区\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"dd\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.address), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-action profile-action\",\n onClick: _cache[0] || (_cache[0] = $event => $setup.contacts.openChat($setup.contact))\n }, \"发消息\")]), $setup.editingAlias ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"modal-backdrop contact-modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeAliasEditor, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"form\", {\n class: \"modal-panel\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submitAlias, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"编辑备注名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeAliasEditor\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"备注名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[1] || (_cache[1] = $event => $setup.aliasDraft = $event),\n maxlength: \"32\",\n autocomplete: \"off\",\n autofocus: \"\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.aliasDraft, void 0, {\n trim: true\n }]])]), $setup.aliasError ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.aliasError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n disabled: $setup.aliasSaving,\n onClick: $setup.closeAliasEditor\n }, \"取消\", 8 /* PROPS */, _hoisted_11), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"submit\",\n class: \"primary-inline-action\",\n disabled: $setup.aliasSaving\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.aliasSaving ? '保存中' : '保存'), 9 /* TEXT, PROPS */, _hoisted_12)])], 32 /* NEED_HYDRATION */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 64 /* STABLE_FRAGMENT */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_13, _cache[7] || (_cache[7] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"选择一个联系人\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"好友列表同步完成后,可以在左侧查看资料\", -1 /* HOISTED */)])))]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/contacts/ContactPanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c":
|
||
/*!************************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c ***!
|
||
\************************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"conversation-list favorite-list\"\n};\nconst _hoisted_2 = {\n class: \"list-header\"\n};\nconst _hoisted_3 = {\n class: \"sidebar-scroll\"\n};\nconst _hoisted_4 = [\"onClick\"];\nconst _hoisted_5 = {\n class: \"favorite-item-main\"\n};\nconst _hoisted_6 = {\n key: 0,\n class: \"empty-list\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"aside\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h2\", null, \"收藏\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.conversations.favoriteMessages.length) + \" 条消息\", 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.conversations.favoriteMessages, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: item.key,\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"favorite-item\", {\n active: $setup.activeKey === item.key\n }]),\n onClick: $event => $setup.conversations.setActiveFavorite(item.key)\n }, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"favorite-item-icon\"\n }, \"★\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favoriteTitle(item)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favoritePreview(item)), 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"time\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatFavoriteTime(item.timestamp)), 1 /* TEXT */)], 10 /* CLASS, PROPS */, _hoisted_4);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.conversations.favoriteMessages.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_6, \" 暂无收藏消息 \")) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)])]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoriteList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0":
|
||
/*!*************************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0 ***!
|
||
\*************************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"favorite-panel\"\n};\nconst _hoisted_2 = {\n class: \"chat-header\"\n};\nconst _hoisted_3 = {\n class: \"favorite-detail\"\n};\nconst _hoisted_4 = {\n class: \"favorite-detail-body\"\n};\nconst _hoisted_5 = {\n key: 0,\n class: \"recall-mark\"\n};\nconst _hoisted_6 = [\"href\"];\nconst _hoisted_7 = [\"src\", \"alt\"];\nconst _hoisted_8 = [\"href\"];\nconst _hoisted_9 = {\n class: \"message-file-main\"\n};\nconst _hoisted_10 = {\n key: 3\n};\nconst _hoisted_11 = {\n class: \"favorite-detail-actions\"\n};\nconst _hoisted_12 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_13 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_14 = {\n key: 1,\n class: \"empty-chat\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"section\", _hoisted_1, [$setup.favorite ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 0\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h2\", null, \"收藏详情\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favoriteTitle($setup.favorite)), 1 /* TEXT */)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"favorite-detail-message\", {\n recalled: $setup.favorite.recalled\n }])\n }, [_cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"favorite-detail-star\"\n }, \"★\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_4, [$setup.favorite.recalled ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favorite.recallStatus || '已撤回'), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.isImageFavorite($setup.favorite) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"a\", {\n key: 1,\n class: \"favorite-detail-image\",\n href: $setup.favorite.attachment.url,\n target: \"_blank\",\n rel: \"noreferrer\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"img\", {\n src: $setup.imageDisplayUrl($setup.favorite.attachment.url),\n alt: $setup.favorite.attachment.name || '图片'\n }, null, 8 /* PROPS */, _hoisted_7)], 8 /* PROPS */, _hoisted_6)) : $setup.isFileFavorite($setup.favorite) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"a\", {\n key: 2,\n class: \"message-file favorite-detail-file\",\n href: $setup.favorite.attachment.url,\n target: \"_blank\",\n rel: \"noreferrer\",\n download: \"\"\n }, [_cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"message-file-icon\"\n }, \"▤\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favorite.attachment.name || '文件'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatFileSize($setup.favorite.attachment.size)), 1 /* TEXT */)])], 8 /* PROPS */, _hoisted_8)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.favoriteText($setup.favorite) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.favoriteText($setup.favorite)), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"time\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatFavoriteTime($setup.favorite.timestamp)), 1 /* TEXT */)], 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_11, [$setup.notice ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.notice), 1 /* TEXT */)) : $setup.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_13, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.error), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.copyFavorite\n }, \"复制\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.openConversation\n }, \"打开原会话\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"danger-inline-action\",\n onClick: $setup.removeFavorite\n }, \"取消收藏\")])])], 64 /* STABLE_FRAGMENT */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_14, _cache[3] || (_cache[3] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"暂无收藏消息\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"右键消息气泡选择“收藏”后,会显示在这里\", -1 /* HOISTED */)])))]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoritePanel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b":
|
||
/*!*********************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b ***!
|
||
\*********************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"conversation-list\"\n};\nconst _hoisted_2 = {\n class: \"list-header\"\n};\nconst _hoisted_3 = {\n class: \"header-actions\"\n};\nconst _hoisted_4 = {\n class: \"search-box\"\n};\nconst _hoisted_5 = {\n class: \"sidebar-scroll\"\n};\nconst _hoisted_6 = [\"onClick\"];\nconst _hoisted_7 = [\"src\"];\nconst _hoisted_8 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_9 = {\n class: \"conversation-copy\"\n};\nconst _hoisted_10 = {\n key: 0,\n class: \"empty-list\"\n};\nconst _hoisted_11 = {\n key: 0,\n class: \"form-error\"\n};\nconst _hoisted_12 = {\n key: 1,\n class: \"form-info\"\n};\nconst _hoisted_13 = {\n class: \"modal-actions\"\n};\nconst _hoisted_14 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"aside\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h2\", null, \"联系人\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.contacts.length) + \" 位好友\", 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"icon-button\",\n title: \"添加联系人\",\n onClick: $setup.openAddContact\n }, \"+\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"icon-button\",\n title: \"刷新\",\n onClick: _cache[0] || (_cache[0] = $event => $setup.contacts.refreshContacts({\n force: true\n }))\n }, \"↻\")])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[1] || (_cache[1] = $event => $setup.keyword = $event),\n placeholder: \"搜索联系人\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.keyword, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.filteredContacts, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: item.id,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"conversation-item\", {\n active: item.id === $setup.contacts.activeId\n }]),\n onClick: $event => $setup.contacts.setActiveContact(item.id)\n }, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: item.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.title), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.subtitle), 1 /* TEXT */)])], 10 /* CLASS, PROPS */, _hoisted_6);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.filteredContacts.length ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.loading ? '正在加载' : '暂无联系人'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.loading ? '请稍候' : '好友同步完成后会显示在这里'), 1 /* TEXT */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), $setup.addingContact ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeAddContact, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"form\", {\n class: \"modal-panel\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submitAddContact, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"添加联系人\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeAddContact\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"用户ID / 手机号 / 用户名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[2] || (_cache[2] = $event => $setup.addKeyword = $event),\n autocomplete: \"off\",\n placeholder: \"请输入要添加的联系人\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.addKeyword, void 0, {\n trim: true\n }]])]), $setup.contacts.actionError ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_11, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.actionError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.contacts.actionInfo ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.actionInfo), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.closeAddContact\n }, \"取消\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-inline-action\",\n disabled: $setup.contacts.loading || !$setup.addKeyword\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.contacts.loading ? '添加中...' : '添加'), 9 /* TEXT, PROPS */, _hoisted_14)])], 32 /* NEED_HYDRATION */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ContactList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78":
|
||
/*!**************************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78 ***!
|
||
\**************************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"conversation-list\"\n};\nconst _hoisted_2 = {\n class: \"list-header\"\n};\nconst _hoisted_3 = {\n class: \"header-actions action-menu-anchor\"\n};\nconst _hoisted_4 = {\n class: \"search-box\"\n};\nconst _hoisted_5 = {\n class: \"sidebar-scroll\"\n};\nconst _hoisted_6 = [\"onClick\"];\nconst _hoisted_7 = [\"src\"];\nconst _hoisted_8 = {\n key: 1,\n class: \"conversation-avatar\"\n};\nconst _hoisted_9 = {\n class: \"conversation-copy\"\n};\nconst _hoisted_10 = [\"aria-label\"];\nconst _hoisted_11 = {\n key: 0,\n class: \"empty-list\"\n};\nconst _hoisted_12 = {\n key: 1,\n class: \"empty-list\"\n};\nconst _hoisted_13 = {\n key: 0\n};\nconst _hoisted_14 = {\n key: 2\n};\nconst _hoisted_15 = {\n key: 5,\n class: \"form-error\"\n};\nconst _hoisted_16 = {\n key: 6,\n class: \"form-info\"\n};\nconst _hoisted_17 = {\n class: \"modal-actions\"\n};\nconst _hoisted_18 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"aside\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h2\", null, \"消息\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.conversations.totalUnread) + \" 条未读\", 1 /* TEXT */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"icon-button\",\n title: \"新建会话\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.toggleActionMenu, [\"stop\"])\n }, \"+\"), $setup.actionMenuOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"quick-action-menu\",\n onClick: _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"stop\"]))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[0] || (_cache[0] = $event => $setup.openAction('addContact'))\n }, \"添加联系人\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[1] || (_cache[1] = $event => $setup.openAction('createGroup'))\n }, \"新建群组\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[2] || (_cache[2] = $event => $setup.openAction('joinGroup'))\n }, \"加入群组\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[3] || (_cache[3] = $event => $setup.openAction('broadcast'))\n }, \"群发助手\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n onClick: _cache[4] || (_cache[4] = $event => $setup.openAction('createChannel'))\n }, \"创建频道/公告群\")])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[6] || (_cache[6] = $event => $setup.searchKeyword = $event),\n placeholder: \"搜索会话、联系人\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.searchKeyword, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_5, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.filteredConversationItems, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"button\", {\n key: item.resultKey,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"conversation-item\", {\n active: $setup.isListItemActive(item)\n }]),\n onClick: $event => $setup.selectListItem(item)\n }, [item.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n class: \"conversation-avatar image-avatar\",\n src: item.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_7)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.avatarText), 1 /* TEXT */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.title), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"small\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.subtitle), 1 /* TEXT */)]), Number(item.unread || 0) > 0 ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", {\n key: 2,\n class: \"unread-badge\",\n \"aria-label\": `${item.unread} 条未读消息`\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatUnread(item.unread)), 9 /* TEXT, PROPS */, _hoisted_10)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 10 /* CLASS, PROPS */, _hoisted_6);\n }), 128 /* KEYED_FRAGMENT */)), !$setup.filteredConversationItems.length && $setup.searchKeyword ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_11, _cache[19] || (_cache[19] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"没有匹配结果\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"换个关键词再试试\", -1 /* HOISTED */)]))) : !$setup.conversations.conversations.length && !$setup.conversations.usingDemoData ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_12, _cache[20] || (_cache[20] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"暂无会话\", -1 /* HOISTED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"收到或发起消息后会出现在这里\", -1 /* HOISTED */)]))) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), $setup.activeAction ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeActionModal, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"form\", {\n class: \"modal-panel conversation-action-panel\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.submitAction, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.actionTitle), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeActionModal\n }, \"×\")]), $setup.activeAction === 'addContact' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"label\", _hoisted_13, [_cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"用户ID / 手机号 / 用户名\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[7] || (_cache[7] = $event => $setup.addKeyword = $event),\n autocomplete: \"off\",\n placeholder: \"请输入要添加的联系人\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.addKeyword, void 0, {\n trim: true\n }]])])) : $setup.activeAction === 'createGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 1\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"群组名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[8] || (_cache[8] = $event => $setup.groupName = $event),\n maxlength: \"64\",\n autocomplete: \"off\",\n placeholder: \"请输入群组名称\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.groupName, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"群说明\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[9] || (_cache[9] = $event => $setup.groupAnnouncement = $event),\n maxlength: \"1000\",\n rows: \"3\",\n placeholder: \"可选\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.groupAnnouncement, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"欢迎词\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[10] || (_cache[10] = $event => $setup.groupWelcomeText = $event),\n maxlength: \"1000\",\n rows: \"3\",\n placeholder: \"群组创建后自动发送\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.groupWelcomeText, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)($setup[\"ContactPicker\"], {\n contacts: $setup.filteredContacts,\n \"selected-ids\": $setup.selectedContactIds,\n keyword: $setup.contactKeyword,\n \"empty-text\": \"暂无可选联系人\",\n \"onUpdate:keyword\": _cache[11] || (_cache[11] = $event => $setup.contactKeyword = $event),\n onToggle: $setup.toggleContact\n }, null, 8 /* PROPS */, [\"contacts\", \"selected-ids\", \"keyword\"])], 64 /* STABLE_FRAGMENT */)) : $setup.activeAction === 'joinGroup' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"label\", _hoisted_14, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"群组ID / 群名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[12] || (_cache[12] = $event => $setup.joinGroupKey = $event),\n autocomplete: \"off\",\n placeholder: \"请输入群组ID或群名称\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.joinGroupKey, void 0, {\n trim: true\n }]])])) : $setup.activeAction === 'broadcast' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 3\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"群发内容\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[13] || (_cache[13] = $event => $setup.broadcastText = $event),\n maxlength: \"2000\",\n rows: \"4\",\n placeholder: \"输入要群发的文字\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.broadcastText, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)($setup[\"ContactPicker\"], {\n contacts: $setup.filteredContacts,\n \"selected-ids\": $setup.selectedContactIds,\n keyword: $setup.contactKeyword,\n \"empty-text\": \"暂无可选联系人\",\n \"onUpdate:keyword\": _cache[14] || (_cache[14] = $event => $setup.contactKeyword = $event),\n onToggle: $setup.toggleContact\n }, null, 8 /* PROPS */, [\"contacts\", \"selected-ids\", \"keyword\"])], 64 /* STABLE_FRAGMENT */)) : $setup.activeAction === 'createChannel' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 4\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"频道/公告群名称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[15] || (_cache[15] = $event => $setup.channelName = $event),\n maxlength: \"64\",\n autocomplete: \"off\",\n placeholder: \"请输入名称\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.channelName, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"公告说明\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n \"onUpdate:modelValue\": _cache[16] || (_cache[16] = $event => $setup.channelAnnouncement = $event),\n maxlength: \"1000\",\n rows: \"3\",\n placeholder: \"可选\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.channelAnnouncement, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)($setup[\"ContactPicker\"], {\n contacts: $setup.filteredContacts,\n \"selected-ids\": $setup.selectedContactIds,\n keyword: $setup.contactKeyword,\n \"empty-text\": \"暂无可选联系人\",\n \"onUpdate:keyword\": _cache[17] || (_cache[17] = $event => $setup.contactKeyword = $event),\n onToggle: $setup.toggleContact\n }, null, 8 /* PROPS */, [\"contacts\", \"selected-ids\", \"keyword\"])], 64 /* STABLE_FRAGMENT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.modalError ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.modalError), 1 /* TEXT */)) : $setup.modalInfo ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"p\", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.modalInfo), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.closeActionModal\n }, \"取消\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-inline-action\",\n disabled: $setup.actionBusy || $setup.submitDisabled\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.actionBusy ? '处理中...' : $setup.submitLabel), 9 /* TEXT, PROPS */, _hoisted_18)])], 32 /* NEED_HYDRATION */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ConversationList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee":
|
||
/*!************************************************************************************************************************************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee ***!
|
||
\************************************************************************************************************************************************************************************************************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n\nconst _hoisted_1 = {\n class: \"navigation-rail\"\n};\nconst _hoisted_2 = [\"src\"];\nconst _hoisted_3 = {\n key: 1\n};\nconst _hoisted_4 = {\n class: \"settings-panel\"\n};\nconst _hoisted_5 = {\n class: \"settings-layout\"\n};\nconst _hoisted_6 = {\n class: \"settings-menu\",\n \"aria-label\": \"设置菜单\"\n};\nconst _hoisted_7 = [\"onClick\"];\nconst _hoisted_8 = {\n key: 0\n};\nconst _hoisted_9 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_10 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_11 = [\"disabled\"];\nconst _hoisted_12 = {\n key: 1,\n class: \"settings-placeholder\"\n};\nconst _hoisted_13 = {\n class: \"profile-avatar-field\"\n};\nconst _hoisted_14 = [\"src\"];\nconst _hoisted_15 = {\n key: 1\n};\nconst _hoisted_16 = [\"value\"];\nconst _hoisted_17 = {\n class: \"modal-actions\"\n};\nconst _hoisted_18 = {\n key: 0,\n class: \"inline-save-status\"\n};\nconst _hoisted_19 = {\n key: 1,\n class: \"inline-save-status error\"\n};\nconst _hoisted_20 = [\"disabled\"];\nconst _hoisted_21 = {\n class: \"avatar-preview-dialog\"\n};\nconst _hoisted_22 = {\n class: \"avatar-preview-actions\"\n};\nconst _hoisted_23 = [\"src\"];\nconst _hoisted_24 = {\n class: \"modal-panel avatar-cropper-panel\"\n};\nconst _hoisted_25 = {\n class: \"avatar-cropper-header-actions\"\n};\nconst _hoisted_26 = [\"disabled\"];\nconst _hoisted_27 = {\n class: \"avatar-cropper-layout\"\n};\nconst _hoisted_28 = {\n ref: \"cropperCanvas\"\n};\nconst _hoisted_29 = {\n key: 0,\n class: \"avatar-cropper-placeholder\"\n};\nconst _hoisted_30 = {\n class: \"avatar-cropper-controls\"\n};\nconst _hoisted_31 = {\n class: \"avatar-cropper-tools\"\n};\nconst _hoisted_32 = {\n class: \"avatar-cropper-preview\"\n};\nconst _hoisted_33 = {\n ref: \"cropperPreviewCanvas\"\n};\nconst _hoisted_34 = {\n key: 0,\n class: \"inline-save-status error\"\n};\nconst _hoisted_35 = [\"disabled\"];\nconst _hoisted_36 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"aside\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"rail-avatar rail-avatar-button\",\n title: \"编辑个人资料\",\n onClick: $setup.openProfileEditor\n }, [$setup.session.portrait ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n src: $setup.session.portrait,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_2)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.initials), 1 /* TEXT */))]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"rail-button\", {\n active: $setup.navigation.section === 'messages'\n }]),\n title: \"消息\",\n onClick: _cache[0] || (_cache[0] = (...args) => $setup.navigation.showMessages && $setup.navigation.showMessages(...args))\n }, \"💬\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"rail-button\", {\n active: $setup.navigation.section === 'contacts'\n }]),\n title: \"联系人\",\n onClick: $setup.showContacts\n }, \"👥\", 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"rail-button\", {\n active: $setup.navigation.section === 'favorites'\n }]),\n title: \"收藏\",\n onClick: _cache[1] || (_cache[1] = (...args) => $setup.navigation.showFavorites && $setup.navigation.showFavorites(...args))\n }, \"☆\", 2 /* CLASS */), _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"rail-spacer\"\n }, null, -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"rail-button\",\n title: \"设置\",\n \"aria-label\": \"设置\",\n onClick: $setup.openSettings\n }, _cache[13] || (_cache[13] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"svg\", {\n viewBox: \"0 0 24 24\",\n \"aria-hidden\": \"true\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"path\", {\n d: \"M12 8.2a3.8 3.8 0 1 1 0 7.6 3.8 3.8 0 0 1 0-7.6Z\"\n }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"path\", {\n 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\"\n })], -1 /* HOISTED */)])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"rail-button rail-logout-button\",\n title: \"退出登录\",\n \"aria-label\": \"退出登录\",\n onClick: $setup.logout\n }, _cache[14] || (_cache[14] = [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)(\"<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)]))]), $setup.settingsOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 0,\n class: \"modal-backdrop settings-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeSettings, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"设置\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeSettings\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"nav\", _hoisted_6, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.settingsItems, item => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n key: item.key,\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n active: $setup.settingsSection === item.key\n }),\n onClick: $event => $setup.selectSettingsSection(item.key)\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.label), 1 /* TEXT */), item.key !== 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"small\", _hoisted_8, \"稍后开放\")) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 10 /* CLASS, PROPS */, _hoisted_7);\n }), 64 /* STABLE_FRAGMENT */))]), $setup.settingsSection === 'password' ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"form\", {\n key: 0,\n class: \"settings-password-form\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.savePassword, [\"prevent\"])\n }, [_cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h3\", null, \"更改密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"当前密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[2] || (_cache[2] = $event => $setup.passwordDraft.oldPassword = $event),\n type: \"password\",\n autocomplete: \"current-password\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.passwordDraft.oldPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"新密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = $event => $setup.passwordDraft.newPassword = $event),\n type: \"password\",\n autocomplete: \"new-password\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.passwordDraft.newPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"确认新密码\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[4] || (_cache[4] = $event => $setup.passwordDraft.confirmPassword = $event),\n type: \"password\",\n autocomplete: \"new-password\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.passwordDraft.confirmPassword]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"footer\", null, [$setup.settingsNotice ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.settingsNotice), 1 /* TEXT */)) : $setup.settingsError ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.settingsError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"submit\",\n class: \"primary-inline-action\",\n disabled: $setup.passwordSaving\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.passwordSaving ? '保存中...' : '保存密码'), 9 /* TEXT, PROPS */, _hoisted_11)])], 32 /* NEED_HYDRATION */)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"section\", _hoisted_12, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"h3\", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.activeSettingsItem?.label || '设置'), 1 /* TEXT */), _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"p\", null, \"该功能稍后开放。\", -1 /* HOISTED */))]))])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.profileOpen ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 1,\n class: \"modal-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeProfileEditor, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"form\", {\n class: \"modal-panel profile-edit-panel\",\n onSubmit: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.saveProfile, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"个人资料\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeProfileEditor\n }, \"×\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_13, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"profile-avatar-preview\", {\n clickable: $setup.currentAvatarUrl\n }]),\n title: \"预览头像\",\n onClick: $setup.openAvatarPreview\n }, [$setup.currentAvatarUrl ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"img\", {\n key: 0,\n src: $setup.currentAvatarUrl,\n alt: \"\"\n }, null, 8 /* PROPS */, _hoisted_14)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.initials), 1 /* TEXT */))], 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action profile-avatar-change-button\",\n onClick: $setup.choosePortraitFile\n }, \"更换头像\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n ref: \"portraitInput\",\n type: \"file\",\n accept: \"image/*\",\n onChange: $setup.selectPortrait\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"昵称\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n \"onUpdate:modelValue\": _cache[5] || (_cache[5] = $event => $setup.profileDraft.displayName = $event),\n maxlength: \"64\",\n autocomplete: \"off\"\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.profileDraft.displayName, void 0, {\n trim: true\n }]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"label\", null, [_cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"用户ID\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n value: $setup.session.userId,\n readonly: \"\"\n }, null, 8 /* PROPS */, _hoisted_16)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_17, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n onClick: $setup.closeProfileEditor\n }, \"取消\"), $setup.profileNotice ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_18, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.profileNotice), 1 /* TEXT */)) : $setup.profileError ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.profileError), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"primary-inline-action\",\n disabled: $setup.profileSaving || !$setup.profileDraft.displayName\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.profileSaving ? '保存中...' : '保存'), 9 /* TEXT, PROPS */, _hoisted_20)])], 32 /* NEED_HYDRATION */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.avatarPreviewViewer.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 2,\n class: \"modal-backdrop avatar-preview-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeAvatarPreview, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", _hoisted_21, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"头像预览\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_22, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"缩小\",\n onClick: _cache[6] || (_cache[6] = $event => $setup.zoomAvatarPreview(1 / 1.16))\n }, \"−\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"放大\",\n onClick: _cache[7] || (_cache[7] = $event => $setup.zoomAvatarPreview(1.16))\n }, \"+\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"还原\",\n onClick: $setup.resetAvatarPreview\n }, \"1:1\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeAvatarPreview\n }, \"×\")])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"avatar-preview-stage\", {\n dragging: $setup.avatarPreviewViewer.dragging\n }]),\n onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleAvatarPreviewWheel, [\"prevent\"]),\n onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.startAvatarPreviewDrag, [\"prevent\"]),\n onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.moveAvatarPreviewDrag, [\"prevent\"]),\n onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.stopAvatarPreviewDrag, [\"prevent\"]),\n onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.stopAvatarPreviewDrag, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"img\", {\n src: $setup.avatarPreviewViewer.url,\n alt: \"头像预览\",\n style: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle)($setup.avatarPreviewStyle),\n draggable: \"false\"\n }, null, 12 /* STYLE, PROPS */, _hoisted_23)], 34 /* CLASS, NEED_HYDRATION */)])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $setup.avatarCropper.open ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", {\n key: 3,\n class: \"modal-backdrop avatar-cropper-backdrop\",\n onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.closeAvatarCropper, [\"self\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", _hoisted_24, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"header\", null, [_cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"strong\", null, \"头像预裁切\", -1 /* HOISTED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_25, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.avatarCropper.busy,\n onClick: $setup.choosePortraitFile\n }, \"上传\", 8 /* PROPS */, _hoisted_26), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"icon-button\",\n title: \"关闭\",\n onClick: $setup.closeAvatarCropper\n }, \"×\")])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_27, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([\"avatar-cropper-stage\", {\n dragging: $setup.avatarCropper.dragging\n }]),\n onWheel: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.handleCropperWheel, [\"prevent\"]),\n onPointerdown: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.startCropperDrag, [\"prevent\"]),\n onPointermove: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.moveCropperDrag, [\"prevent\"]),\n onPointerup: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.stopCropperDrag, [\"prevent\"]),\n onPointerleave: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.stopCropperDrag, [\"prevent\"]),\n onDragover: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, [\"prevent\"])),\n onDrop: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($setup.dropPortrait, [\"prevent\"])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"canvas\", _hoisted_28, null, 512 /* NEED_PATCH */), _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"avatar-cropper-mask\",\n \"aria-hidden\": \"true\"\n }, null, -1 /* HOISTED */)), _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"avatar-cropper-box\",\n \"aria-hidden\": \"true\"\n }, null, -1 /* HOISTED */)), !$setup.avatarCropper.loaded ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_29, \"图片加载中\")) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 34 /* CLASS, NEED_HYDRATION */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"aside\", _hoisted_30, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_31, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"左旋90度\",\n onClick: _cache[9] || (_cache[9] = $event => $setup.rotateCropper(-90))\n }, \"↶90°\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"右旋90度\",\n onClick: _cache[10] || (_cache[10] = $event => $setup.rotateCropper(90))\n }, \"↷90°\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"放大\",\n onClick: _cache[11] || (_cache[11] = $event => $setup.zoomCropper(1.12))\n }, \"+\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"缩小\",\n onClick: _cache[12] || (_cache[12] = $event => $setup.zoomCropper(1 / 1.12))\n }, \"−\"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n title: \"重置\",\n onClick: $setup.resetCropperTransform\n }, \"重置\")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_32, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"canvas\", _hoisted_33, null, 512 /* NEED_PATCH */)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"footer\", null, [$setup.avatarCropper.error ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", _hoisted_34, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.avatarCropper.error), 1 /* TEXT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"ghost-inline-action\",\n disabled: $setup.avatarCropper.busy,\n onClick: $setup.closeAvatarCropper\n }, \"取消\", 8 /* PROPS */, _hoisted_35), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n type: \"button\",\n class: \"primary-inline-action\",\n disabled: $setup.avatarCropper.busy || !$setup.avatarCropper.loaded,\n onClick: $setup.confirmAvatarCrop\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.avatarCropper.busy ? '处理中...' : '确认裁切'), 9 /* TEXT, PROPS */, _hoisted_36)])])])])])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)], 64 /* STABLE_FRAGMENT */);\n}\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/NavigationRail.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/config.js":
|
||
/*!***********************!*\
|
||
!*** ./src/config.js ***!
|
||
\***********************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ appConfig: function() { return /* binding */ appConfig; }\n/* harmony export */ });\nconst currentHost = window.location.hostname || '127.0.0.1';\nconst runtimeConfig = window.JC_WEB_IM_CONFIG || {};\nconst appServerOrigin = `${window.location.protocol}//${currentHost}:8888`;\nconst qrAppServerOrigin = `${window.location.protocol}//${currentHost}:18888`;\nconst adminServerOrigin = `${window.location.protocol}//${currentHost}:8024`;\nconst appConfig = {\n appName: 'Web IM',\n adminServer: runtimeConfig.adminServer || undefined || adminServerOrigin,\n appServer: runtimeConfig.appServer || undefined || appServerOrigin,\n qrAppServer: runtimeConfig.qrAppServer || undefined || qrAppServerOrigin,\n platformConfigApi: runtimeConfig.platformConfigApi || undefined || ( true ? '/local-api/platform_config.php' : 0),\n registerConfigApi: runtimeConfig.registerConfigApi || undefined || `${adminServerOrigin}/api/register-config`,\n registerPhoneExistsApi: runtimeConfig.registerPhoneExistsApi || undefined || `${adminServerOrigin}/api/register-phone-exists`,\n contactsApi: runtimeConfig.contactsApi || undefined || ( true ? '/local-api/contacts.php' : 0),\n updateAliasApi: runtimeConfig.updateAliasApi || undefined || ( true ? '/local-api/update_alias.php' : 0),\n addContactApi: runtimeConfig.addContactApi || undefined || ( true ? '/local-api/add_contact.php' : 0),\n conversationActionsApi: runtimeConfig.conversationActionsApi || undefined || ( true ? '/local-api/conversation_actions.php' : 0),\n sendMessageApi: runtimeConfig.sendMessageApi || undefined || ( true ? '/local-api/send_message.php' : 0),\n messageActionApi: runtimeConfig.messageActionApi || undefined || ( true ? '/local-api/message_action.php' : 0),\n messageDetailApi: runtimeConfig.messageDetailApi || undefined || ( true ? '/local-api/message_detail.php' : 0),\n messagesApi: runtimeConfig.messagesApi || undefined || ( true ? '/local-api/messages.php' : 0),\n profileApi: runtimeConfig.profileApi || undefined || ( true ? '/local-api/profile.php' : 0),\n changePasswordApi: runtimeConfig.changePasswordApi || undefined || `${appServerOrigin}/auth/changePassword`,\n logoutApi: runtimeConfig.logoutApi || undefined || `${appServerOrigin}/auth/logout`,\n imServerHost: runtimeConfig.imServerHost || undefined || currentHost,\n imRoutePort: Number(runtimeConfig.imRoutePort || undefined || 18000),\n useWss: runtimeConfig.useWss ?? undefined === 'true',\n wsPath: runtimeConfig.wsPath || undefined || '/ws',\n wsUrl: runtimeConfig.wsUrl || undefined || '',\n sdkMode: runtimeConfig.sdkMode || undefined || 'http',\n syncIntervalMs: Number(runtimeConfig.syncIntervalMs || undefined || 300),\n sseEnabled: runtimeConfig.sseEnabled ?? undefined === 'true',\n sseTicketApi: runtimeConfig.sseTicketApi || undefined || '/api/sse_ticket.php',\n sseUrl: runtimeConfig.sseUrl || undefined || '/ws-events',\n platform: 5,\n clientIdStorageKey: 'qmt-web-im-client-id',\n authTokenStoragePrefix: 'qmt-web-im-auth-token-'\n};\n\n//# sourceURL=webpack://jc-web-im/./src/config.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/main.js":
|
||
/*!*********************!*\
|
||
!*** ./src/main.js ***!
|
||
\*********************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pinia */ \"./node_modules/pinia/dist/pinia.mjs\");\n/* harmony import */ var _App_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./App.vue */ \"./src/App.vue\");\n/* harmony import */ var _styles_base_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./styles/base.css */ \"./src/styles/base.css\");\n/* harmony import */ var _styles_base_css__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_styles_base_css__WEBPACK_IMPORTED_MODULE_3__);\n\n\n\n\n(0,vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_App_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"]).use((0,pinia__WEBPACK_IMPORTED_MODULE_1__.createPinia)()).mount('#app');\n\n//# sourceURL=webpack://jc-web-im/./src/main.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/appServerClient.js":
|
||
/*!*****************************************!*\
|
||
!*** ./src/services/appServerClient.js ***!
|
||
\*****************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ appServerGet: function() { return /* binding */ appServerGet; },\n/* harmony export */ appServerPost: function() { return /* binding */ appServerPost; },\n/* harmony export */ appServerRequest: function() { return /* binding */ appServerRequest; },\n/* harmony export */ clearStoredAppAuth: function() { return /* binding */ clearStoredAppAuth; },\n/* harmony export */ getStoredAppAuth: function() { return /* binding */ getStoredAppAuth; },\n/* harmony export */ persistAppAuth: function() { return /* binding */ persistAppAuth; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_typed_array_with_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.with.js */ \"./node_modules/core-js/modules/es.typed-array.with.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_uint8_array_set_from_base64_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.uint8-array.set-from-base64.js */ \"./node_modules/core-js/modules/es.uint8-array.set-from-base64.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_uint8_array_set_from_hex_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.uint8-array.set-from-hex.js */ \"./node_modules/core-js/modules/es.uint8-array.set-from-hex.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_uint8_array_to_base64_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.uint8-array.to-base64.js */ \"./node_modules/core-js/modules/es.uint8-array.to-base64.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_uint8_array_to_hex_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.uint8-array.to-hex.js */ \"./node_modules/core-js/modules/es.uint8-array.to-hex.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_web_dom_exception_stack_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/web.dom-exception.stack.js */ \"./node_modules/core-js/modules/web.dom-exception.stack.js\");\n/* 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__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n\n\n\n\n\n\n\n\n\n\nconst AES_KEY = 'xczx2026!@#secKe';\nconst ENCRYPTION_EXCLUDE_PATHS = ['/avatar/', '/f/', '/amr2mp3', '/appVersion/check'];\nconst AUTH_STORAGE_KEY = 'qmt-web-im-app-auth-v1';\nconst AUTH_ERROR_CODE = 13;\nconst REFRESH_ERROR_CODE = 20045;\nlet importedCryptoKeyPromise = null;\nlet refreshPromise = null;\nfunction storageScope() {\n return _config__WEBPACK_IMPORTED_MODULE_9__.appConfig.appServer || '';\n}\nfunction readAuthStore() {\n try {\n return JSON.parse(localStorage.getItem(AUTH_STORAGE_KEY) || '{}');\n } catch (error) {\n return {};\n }\n}\nfunction writeAuthStore(store) {\n localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(store));\n}\nfunction normalizeAuthBundle(bundle = {}) {\n const accessToken = String(bundle.accessToken || '').trim();\n const refreshToken = String(bundle.refreshToken || '').trim();\n if (!accessToken || !refreshToken) {\n return null;\n }\n return {\n accessToken,\n refreshToken,\n tokenType: String(bundle.tokenType || 'Bearer').trim() || 'Bearer',\n accessTokenExpireIn: Number(bundle.accessTokenExpireIn || 0) || 0,\n accessTokenExpireAt: Number(bundle.accessTokenExpireAt || 0) || 0,\n refreshTokenExpireIn: Number(bundle.refreshTokenExpireIn || 0) || 0,\n refreshTokenExpireAt: Number(bundle.refreshTokenExpireAt || 0) || 0\n };\n}\nfunction getStoredAppAuth() {\n const store = readAuthStore();\n return normalizeAuthBundle(store[storageScope()]);\n}\nfunction persistAppAuth(bundle) {\n const normalized = normalizeAuthBundle(bundle);\n const store = readAuthStore();\n if (!normalized) {\n delete store[storageScope()];\n writeAuthStore(store);\n return null;\n }\n store[storageScope()] = normalized;\n writeAuthStore(store);\n return normalized;\n}\nfunction clearStoredAppAuth() {\n persistAppAuth(null);\n}\nfunction hasFormData(value) {\n return typeof FormData !== 'undefined' && value instanceof FormData;\n}\nfunction absoluteUrl(url) {\n return new URL(url, window.location.origin);\n}\nfunction shouldEncrypt(url) {\n const pathname = absoluteUrl(url).pathname;\n return !ENCRYPTION_EXCLUDE_PATHS.some(path => pathname === path || pathname.startsWith(path));\n}\nfunction shouldAttachAuth(config) {\n return !config.skipAuth;\n}\nfunction textEncoder() {\n return new TextEncoder();\n}\nfunction textDecoder() {\n return new TextDecoder();\n}\nfunction bytesToBase64(bytes) {\n let binary = '';\n bytes.forEach(byte => {\n binary += String.fromCharCode(byte);\n });\n return btoa(binary);\n}\nfunction base64ToBytes(base64) {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\nasync function getCryptoKey() {\n if (!importedCryptoKeyPromise) {\n importedCryptoKeyPromise = window.crypto.subtle.importKey('raw', textEncoder().encode(AES_KEY), {\n name: 'AES-CBC'\n }, false, ['encrypt', 'decrypt']);\n }\n return importedCryptoKeyPromise;\n}\nasync function encryptPayload(plainText) {\n const iv = window.crypto.getRandomValues(new Uint8Array(16));\n const key = await getCryptoKey();\n const encrypted = await window.crypto.subtle.encrypt({\n name: 'AES-CBC',\n iv\n }, key, textEncoder().encode(plainText));\n return `${bytesToBase64(iv)}:${bytesToBase64(new Uint8Array(encrypted))}`;\n}\nasync function decryptPayload(cipherText) {\n const [ivBase64, encryptedBase64] = String(cipherText || '').split(':', 2);\n if (!ivBase64 || !encryptedBase64) {\n throw new Error('Encrypted payload format is invalid');\n }\n const key = await getCryptoKey();\n const decrypted = await window.crypto.subtle.decrypt({\n name: 'AES-CBC',\n iv: base64ToBytes(ivBase64)\n }, key, base64ToBytes(encryptedBase64));\n return textDecoder().decode(decrypted);\n}\nfunction normalizeBusinessResponse(payload) {\n if (payload && typeof payload === 'object' && !Array.isArray(payload)) {\n return payload;\n }\n return {\n code: 0,\n message: 'success',\n data: payload\n };\n}\nasync function decodeResponsePayload(response) {\n const encrypted = String(response.headers?.['x-encrypted'] || '').toLowerCase() === 'true';\n if (encrypted && typeof response.data === 'string') {\n const plainText = await decryptPayload(response.data);\n response.data = normalizeBusinessResponse(JSON.parse(plainText));\n return response;\n }\n response.data = normalizeBusinessResponse(response.data);\n return response;\n}\nconst client = axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].create({\n withCredentials: false\n});\nclient.interceptors.request.use(async config => {\n const nextConfig = {\n ...config\n };\n const url = absoluteUrl(nextConfig.url || '').toString();\n if (shouldAttachAuth(nextConfig)) {\n const auth = getStoredAppAuth();\n if (auth?.accessToken) {\n nextConfig.headers = {\n ...(nextConfig.headers || {}),\n Authorization: `${auth.tokenType || 'Bearer'} ${auth.accessToken}`\n };\n }\n }\n if (!hasFormData(nextConfig.data) && nextConfig.method?.toLowerCase() !== 'get' && shouldEncrypt(url)) {\n const plainBody = JSON.stringify(nextConfig.data ?? {});\n nextConfig.data = await encryptPayload(plainBody);\n nextConfig.headers = {\n ...(nextConfig.headers || {}),\n 'Content-Type': 'text/plain;charset=UTF-8',\n 'X-Timestamp': `${Math.floor(Date.now() / 1000)}`\n };\n }\n return nextConfig;\n});\nclient.interceptors.response.use(async response => decodeResponsePayload(response));\nasync function refreshAccessToken() {\n if (refreshPromise) {\n return refreshPromise;\n }\n const auth = getStoredAppAuth();\n if (!auth?.refreshToken) {\n clearStoredAppAuth();\n throw new Error('登录状态已失效,请重新登录');\n }\n refreshPromise = client.post(`${_config__WEBPACK_IMPORTED_MODULE_9__.appConfig.appServer}/auth/refreshToken`, {\n refreshToken: auth.refreshToken\n }, {\n skipAuth: true\n }).then(response => {\n const payload = response.data || {};\n if (Number(payload.code) !== 0 || !payload.data) {\n if (Number(payload.code) === REFRESH_ERROR_CODE) {\n clearStoredAppAuth();\n }\n throw new Error(payload.message || '刷新登录状态失败');\n }\n persistAppAuth(payload.data);\n return payload.data;\n }).finally(() => {\n refreshPromise = null;\n });\n return refreshPromise;\n}\nasync function request(config) {\n const response = await client.request(config);\n const payload = response.data || {};\n if (Number(payload.code) === AUTH_ERROR_CODE && shouldAttachAuth(config) && !config._retriedAfterRefresh) {\n await refreshAccessToken();\n return request({\n ...config,\n _retriedAfterRefresh: true\n });\n }\n return response;\n}\nasync function appServerRequest(config) {\n return request(config);\n}\nasync function appServerGet(url, config = {}) {\n return request({\n ...config,\n method: 'get',\n url\n });\n}\nasync function appServerPost(url, data = {}, config = {}) {\n return request({\n ...config,\n method: 'post',\n url,\n data\n });\n}\n\n//# sourceURL=webpack://jc-web-im/./src/services/appServerClient.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/documentedHttpImClient.js":
|
||
/*!************************************************!*\
|
||
!*** ./src/services/documentedHttpImClient.js ***!
|
||
\************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DocumentedHttpImClient: function() { return /* binding */ DocumentedHttpImClient; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./httpImClient */ \"./src/services/httpImClient.js\");\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _appServerClient__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./appServerClient */ \"./src/services/appServerClient.js\");\n\n\n\n\n\nfunction inferAccountType(account) {\n return String(account || '').includes('@') ? 2 : 1;\n}\nfunction unwrapData(response) {\n return response.data?.data ?? response.data?.result ?? null;\n}\nfunction unwrapMessage(response, fallback) {\n return response.data?.message || response.data?.msg || fallback;\n}\nclass DocumentedHttpImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_2__.HttpImClient {\n unsupported(feature) {\n throw new Error(`当前对接文档未提供“${feature}”接口,已禁用旧本地代理链路`);\n }\n async loginWithPassword(account, password, type = inferAccountType(account)) {\n const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.appServerPost)(`${_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.appServer}/auth/login_pwd`, {\n type,\n number: account,\n password,\n platform: _config__WEBPACK_IMPORTED_MODULE_1__.appConfig.platform,\n clientId: this.getClientId()\n }, {\n skipAuth: true\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '登录失败'));\n }\n (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.persistAppAuth)(unwrapData(response));\n return unwrapData(response);\n }\n async requestAuthCode(email) {\n const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.appServerPost)(`${_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.appServer}/auth/sendEmailCode`, {\n email\n }, {\n skipAuth: true\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '验证码发送失败'));\n }\n return unwrapData(response);\n }\n async loginWithCode(account, code) {\n void account;\n void code;\n throw new Error('接口文档未提供验证码登录接口,请使用密码登录');\n }\n async register({\n type,\n number,\n code = '',\n password,\n invitationCode = ''\n }) {\n const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.appServerPost)(`${_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.appServer}/auth/register`, {\n type,\n number,\n code,\n password,\n clientId: this.getClientId(),\n platform: _config__WEBPACK_IMPORTED_MODULE_1__.appConfig.platform,\n invitationCode\n }, {\n skipAuth: true\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '注册失败'));\n }\n (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.persistAppAuth)(unwrapData(response));\n return unwrapData(response);\n }\n async createPcSession(userId = '') {\n const response = await axios__WEBPACK_IMPORTED_MODULE_3__[\"default\"].post(`${_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.qrAppServer}/pc_session`, {\n flag: 1,\n device_name: 'Web IM',\n userId,\n clientId: this.getClientId(),\n platform: _config__WEBPACK_IMPORTED_MODULE_1__.appConfig.platform\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '二维码登录会话创建失败'));\n }\n return unwrapData(response) || {};\n }\n async loginWithPcSession(token) {\n const url = `${_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.qrAppServer}/session_login/${encodeURIComponent(token)}`;\n let response;\n try {\n response = await axios__WEBPACK_IMPORTED_MODULE_3__[\"default\"].post(url, null, {\n withCredentials: false\n });\n } catch (postError) {\n response = await axios__WEBPACK_IMPORTED_MODULE_3__[\"default\"].get(url, {\n withCredentials: false\n });\n }\n this.persistAppToken(url, response);\n const payload = response.data || {};\n const result = payload.result ?? payload.data ?? null;\n if (Number(payload.code) === 0 && result) {\n (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.persistAppAuth)(result);\n }\n if ([0, 8, 9, 10, 13, 18, 20042].includes(Number(payload.code))) {\n return {\n ...payload,\n data: result\n };\n }\n throw new Error(payload.message || '扫码登录失败');\n }\n async changePassword({\n oldPassword,\n newPassword\n }) {\n const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.appServerPost)(_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.changePasswordApi, {\n oldPassword,\n newPassword\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '密码修改失败'));\n }\n return true;\n }\n async resetPasswordWithCode({\n mobile,\n resetCode,\n newPassword\n }) {\n void mobile;\n void resetCode;\n void newPassword;\n throw new Error('接口文档未提供重置密码接口,请联系服务端确认流程');\n }\n async logout() {\n const auth = (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.getStoredAppAuth)();\n if (!auth?.refreshToken) {\n (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.clearStoredAppAuth)();\n return true;\n }\n try {\n const response = await (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.appServerPost)(_config__WEBPACK_IMPORTED_MODULE_1__.appConfig.logoutApi, {\n refreshToken: auth.refreshToken\n });\n if (response.data?.code !== 0) {\n throw new Error(unwrapMessage(response, '退出登录失败'));\n }\n } finally {\n (0,_appServerClient__WEBPACK_IMPORTED_MODULE_4__.clearStoredAppAuth)();\n }\n return true;\n }\n async fetchRemoteConversations() {\n return [];\n }\n async fetchRemoteMessages() {\n return [];\n }\n async getServerContactList() {\n return [];\n }\n async getProfile() {\n return null;\n }\n async sendTextMessage() {\n this.unsupported('发送消息');\n }\n async sendAttachmentMessage() {\n this.unsupported('发送附件消息');\n }\n async addContact() {\n this.unsupported('添加联系人');\n }\n async updateContactAlias() {\n this.unsupported('联系人备注');\n }\n async createGroup() {\n this.unsupported('创建群组');\n }\n async joinGroup() {\n this.unsupported('加入群组');\n }\n async broadcastMessage() {\n this.unsupported('群发消息');\n }\n async getGroupDetail() {\n this.unsupported('群详情');\n }\n async getGroupMembers() {\n this.unsupported('群成员');\n }\n async updateGroupAlias() {\n this.unsupported('群备注');\n }\n async leaveGroup() {\n this.unsupported('退出群组');\n }\n async dismissGroup() {\n this.unsupported('解散群组');\n }\n async transferGroup() {\n this.unsupported('转让群组');\n }\n async setGroupAdmins() {\n this.unsupported('设置群管理员');\n }\n async updateGroupProfile() {\n this.unsupported('更新群资料');\n }\n async kickGroupMembers() {\n this.unsupported('移除群成员');\n }\n async updateGroupMuteSetting() {\n this.unsupported('群禁言设置');\n }\n async updateProfile() {\n this.unsupported('更新个人资料');\n }\n async recallMessage() {\n this.unsupported('撤回消息');\n }\n async editMessage() {\n this.unsupported('编辑消息');\n }\n async getMessageDetail() {\n this.unsupported('消息详情');\n }\n}\n\n//# sourceURL=webpack://jc-web-im/./src/services/documentedHttpImClient.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/httpImClient.js":
|
||
/*!**************************************!*\
|
||
!*** ./src/services/httpImClient.js ***!
|
||
\**************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ HttpImClient: function() { return /* binding */ HttpImClient; },\n/* harmony export */ imClient: function() { return /* binding */ imClient; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.iterator.some.js */ \"./node_modules/core-js/modules/es.iterator.some.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert.js */ \"./node_modules/core-js/modules/es.map.get-or-insert.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert-computed.js */ \"./node_modules/core-js/modules/es.map.get-or-insert-computed.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/es.set.difference.v2.js */ \"./node_modules/core-js/modules/es.set.difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! core-js/modules/es.set.intersection.v2.js */ \"./node_modules/core-js/modules/es.set.intersection.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! core-js/modules/es.set.is-disjoint-from.v2.js */ \"./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! core-js/modules/es.set.is-subset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-subset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! core-js/modules/es.set.is-superset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-superset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! core-js/modules/es.set.symmetric-difference.v2.js */ \"./node_modules/core-js/modules/es.set.symmetric-difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! core-js/modules/es.set.union.v2.js */ \"./node_modules/core-js/modules/es.set.union.v2.js\");\n/* 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__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _services_appServerClient__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @/services/appServerClient */ \"./src/services/appServerClient.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst LOCAL_MESSAGE_STORAGE_KEY = 'qmt-web-im-local-messages-v2';\nconst LOCAL_HIDDEN_MESSAGE_STORAGE_KEY = 'qmt-web-im-hidden-messages-v1';\nconst LOCAL_RECALLED_MESSAGE_STORAGE_KEY = 'qmt-web-im-recalled-messages-v1';\nfunction scopedStorageKey(baseKey, userId = '') {\n const scope = `${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer || ''}:${userId || 'anonymous'}`;\n return `${baseKey}:${encodeURIComponent(scope)}`;\n}\nfunction randomId() {\n if (window.crypto && window.crypto.randomUUID) {\n return window.crypto.randomUUID().replaceAll('-', '');\n }\n return `${Date.now()}${Math.random().toString(16).slice(2)}`;\n}\nfunction readLocalMessages(userId) {\n try {\n return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId)) || '{}');\n } catch (error) {\n return {};\n }\n}\nfunction readMessageSet(storageKey, userId) {\n try {\n return JSON.parse(localStorage.getItem(scopedStorageKey(storageKey, userId)) || '{}');\n } catch (error) {\n return {};\n }\n}\nfunction writeMessageSet(storageKey, messagesByConversation, userId) {\n localStorage.setItem(scopedStorageKey(storageKey, userId), JSON.stringify(messagesByConversation));\n}\nfunction messageKeys(message) {\n return [message?.id, message?.messageUid].filter(Boolean).map(value => String(value));\n}\nfunction hasStoredMessage(storageKey, conversationId, message, userId) {\n const stored = readMessageSet(storageKey, userId);\n const ids = new Set(stored[conversationId] || []);\n return messageKeys(message).some(id => ids.has(id));\n}\nfunction storeMessageKeys(storageKey, conversationId, messages, userId) {\n const stored = readMessageSet(storageKey, userId);\n const ids = new Set(stored[conversationId] || []);\n messages.forEach(message => {\n messageKeys(message).forEach(id => ids.add(id));\n });\n stored[conversationId] = Array.from(ids);\n writeMessageSet(storageKey, stored, userId);\n}\nfunction withRecalledState(message) {\n return {\n ...message,\n status: 'recalled',\n deliveryStatus: '',\n recalled: true,\n recallStatus: '已撤回'\n };\n}\nfunction applyLocalMessageState(conversationId, messages, userId) {\n return messages.filter(message => !hasStoredMessage(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversationId, message, userId)).map(message => {\n const isRecalled = Boolean(message.recalled) || message.status === 'recalled' || hasStoredMessage(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversationId, message, userId);\n if (!isRecalled) {\n return message;\n }\n return withRecalledState(message);\n });\n}\nfunction writeLocalMessages(messagesByConversation, userId) {\n localStorage.setItem(scopedStorageKey(LOCAL_MESSAGE_STORAGE_KEY, userId), JSON.stringify(messagesByConversation));\n}\nfunction saveLocalMessage(message, userId) {\n const messagesByConversation = readLocalMessages(userId);\n messagesByConversation[message.conversationId] = messagesByConversation[message.conversationId] || [];\n const index = messagesByConversation[message.conversationId].findIndex(item => item.id === message.id);\n if (index >= 0) {\n messagesByConversation[message.conversationId].splice(index, 1, message);\n } else {\n messagesByConversation[message.conversationId].push(message);\n }\n writeLocalMessages(messagesByConversation, userId);\n}\nfunction mergeSyncedMessages(localMessages, remoteMessages, conversationId, userId) {\n const visibleLocalMessages = applyLocalMessageState(conversationId, localMessages, userId);\n const localByKey = new Map();\n visibleLocalMessages.forEach(message => {\n messageKeys(message).forEach(key => {\n if (!localByKey.has(key)) {\n localByKey.set(key, message);\n }\n });\n });\n const visibleRemoteMessages = applyLocalMessageState(conversationId, remoteMessages, userId).map(remoteMessage => {\n if (!remoteMessage.recalled || String(remoteMessage.text || '').trim()) {\n return remoteMessage;\n }\n const localMessage = messageKeys(remoteMessage).map(key => localByKey.get(key)).find(message => message?.text && message.text !== '你撤回了一条消息');\n return localMessage ? {\n ...remoteMessage,\n text: localMessage.text\n } : remoteMessage;\n });\n const remoteKeys = new Set();\n visibleRemoteMessages.forEach(message => {\n messageKeys(message).forEach(key => remoteKeys.add(key));\n });\n const now = Date.now();\n function hasRemoteMatch(localMessage) {\n if (localMessage.messageUid && remoteKeys.has(localMessage.messageUid)) {\n return true;\n }\n return visibleRemoteMessages.some(remoteMessage => {\n return remoteMessage.direction === localMessage.direction && remoteMessage.text === localMessage.text && Math.abs(Number(remoteMessage.timestamp || 0) - Number(localMessage.timestamp || 0)) < 15000;\n });\n }\n const pendingLocalMessages = visibleLocalMessages.filter(message => {\n if (message.status === 'recalled' || message.recalled) {\n return message.direction === 'out' && !hasRemoteMatch(message);\n }\n if (message.direction !== 'out') {\n return false;\n }\n if (message.status === 'sent' && message.messageUid) {\n return !hasRemoteMatch(message);\n }\n if (message.status === 'sent') {\n return !hasRemoteMatch(message) && now - Number(message.timestamp || 0) < 30000;\n }\n return message.status === 'sending' || message.status === 'failed';\n });\n return [...visibleRemoteMessages, ...pendingLocalMessages].sort((a, b) => {\n return Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0);\n });\n}\nfunction getTitle(value, fallback) {\n return value || fallback || '';\n}\nfunction getUniqueEquipment(mobile, fallback) {\n const allowedDevices = {\n '18301902119': '67072d37062c4f31b1165073552933ba',\n '18301902116': '1777479418113eeea8e236edce',\n '18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',\n '18301902117': 'd117f480faa64145b6162107b1b49617'\n };\n return allowedDevices[mobile] || localStorage.getItem('uniqueEquipment') || fallback;\n}\nfunction canUseLocalLoginFallback(response) {\n const message = response.data?.message || '';\n return true && message.includes('允许此设备登录');\n}\nclass HttpImClient {\n constructor() {\n this.listeners = new Map();\n this.connected = false;\n this.currentUser = null;\n }\n getClientId() {\n let clientId = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.clientIdStorageKey);\n if (!clientId) {\n clientId = randomId();\n localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.clientIdStorageKey, clientId);\n }\n return clientId;\n }\n restoreClientId(clientId) {\n if (clientId) {\n localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.clientIdStorageKey, clientId);\n }\n }\n getSdkVersion() {\n return 'HTTP';\n }\n async ensureSdk() {\n return true;\n }\n async loginWithPassword(mobile, password) {\n const url = `${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/login_pwd`;\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(url, {\n mobile,\n password,\n platform: _config__WEBPACK_IMPORTED_MODULE_18__.appConfig.platform,\n clientId: this.getClientId()\n }, {\n withCredentials: false\n });\n this.persistAppToken(url, response);\n if (response.data?.code !== 0) {\n if (canUseLocalLoginFallback(response)) {\n return {\n userId: mobile,\n token: `local-device-pending-${Date.now()}`,\n displayName: mobile,\n localOnly: true\n };\n }\n throw new Error(response.data?.message || '登录失败');\n }\n return response.data.result;\n }\n async requestAuthCode(mobile) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(`${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/send_code`, {\n mobile\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '验证码发送失败');\n }\n return response.data.result;\n }\n async loginWithCode(mobile, code) {\n const url = `${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/login`;\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(url, {\n mobile,\n code,\n platform: _config__WEBPACK_IMPORTED_MODULE_18__.appConfig.platform,\n clientId: this.getClientId()\n }, {\n withCredentials: false\n });\n this.persistAppToken(url, response);\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '登录失败');\n }\n return response.data.result;\n }\n async createPcSession(userId = '') {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(`${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/pc_session`, {\n flag: 1,\n device_name: 'Web IM',\n userId,\n clientId: this.getClientId(),\n platform: _config__WEBPACK_IMPORTED_MODULE_18__.appConfig.platform\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '二维码登录会话创建失败');\n }\n return response.data.result || {};\n }\n async loginWithPcSession(token) {\n const url = `${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/session_login/${encodeURIComponent(token)}`;\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(url, null, {\n withCredentials: false\n });\n this.persistAppToken(url, response);\n const data = response.data || {};\n if ([0, 8, 9, 10, 18].includes(Number(data.code))) {\n return data;\n }\n throw new Error(data.message || '扫码登录失败');\n }\n async registerWithPhone(mobile, code) {\n const url = `${_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer}/register`;\n const deviceId = getUniqueEquipment(mobile, this.getClientId());\n try {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(url, {\n mobile,\n code,\n platform: _config__WEBPACK_IMPORTED_MODULE_18__.appConfig.platform,\n clientId: deviceId,\n uniqueEquipment: deviceId\n }, {\n withCredentials: false\n });\n this.persistAppToken(url, response);\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '注册失败');\n }\n return response.data.result;\n } catch (error) {\n const status = error.response?.status;\n if (status === 404 || status === 405) {\n return this.loginWithCode(mobile, code);\n }\n throw error;\n }\n }\n connect(userId, token) {\n this.currentUser = {\n userId,\n token\n };\n this.connected = true;\n this.emit('connectionStatusChanged', {\n connected: true,\n statusText: '已连接'\n });\n this.refreshConversationList();\n }\n disconnect() {\n this.connected = false;\n this.currentUser = null;\n this.emit('connectionStatusChanged', {\n connected: false,\n statusText: '未连接'\n });\n }\n getConversationList() {\n return [];\n }\n refreshConversationList() {\n const conversations = this.getConversationList();\n if (conversations.length) {\n this.emit('conversationsChanged', conversations);\n }\n if (this.currentUser?.userId) {\n this.fetchRemoteConversations().then(remoteConversations => {\n this.emit('conversationsChanged', remoteConversations);\n }).catch(() => {});\n }\n return conversations;\n }\n async fetchRemoteConversations(limit = 50) {\n if (!this.currentUser?.userId) {\n return [];\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.messagesApi, {\n userId: this.currentUser.userId,\n limit\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '会话同步失败');\n }\n return (response.data?.result?.conversations || []).map(conversation => ({\n ...conversation,\n updatedAt: Number(conversation.updatedAt || Date.now()),\n avatarText: conversation.avatarText || String(conversation.title || conversation.target || '?').slice(0, 1).toUpperCase(),\n raw: conversation.raw || {\n type: 'single',\n target: conversation.target,\n line: 0\n }\n }));\n }\n getMessages(conversation) {\n if (!conversation?.id) {\n return [];\n }\n const userId = this.currentUser?.userId || '';\n return applyLocalMessageState(conversation.id, readLocalMessages(userId)[conversation.id] || [], userId);\n }\n async fetchRemoteMessages(conversation, limit = 50, options = {}) {\n if (!conversation?.id || !this.currentUser?.userId) {\n return [];\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.messagesApi, {\n userId: this.currentUser.userId,\n target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),\n limit,\n conversationType: conversation.type || conversation.raw?.type || 0,\n markRead: Boolean(options.markRead),\n includeConversations: Boolean(options.includeConversations)\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '消息同步失败');\n }\n const messages = (response.data?.result?.messages || []).map(message => ({\n ...message,\n displayTimestamp: message.displayTimestamp || message.timestamp,\n conversationId: conversation.id\n }));\n if (options.includeConversations && Array.isArray(response.data?.result?.conversations)) {\n const remoteConversations = response.data.result.conversations.map(remoteConversation => ({\n ...remoteConversation,\n updatedAt: Number(remoteConversation.updatedAt || Date.now()),\n avatarText: remoteConversation.avatarText || String(remoteConversation.title || remoteConversation.target || '?').slice(0, 1).toUpperCase(),\n raw: remoteConversation.raw || {\n type: 'single',\n target: remoteConversation.target,\n line: 0\n }\n }));\n this.emit('conversationsChanged', remoteConversations);\n }\n const userId = this.currentUser?.userId || '';\n const messagesByConversation = readLocalMessages(userId);\n messagesByConversation[conversation.id] = mergeSyncedMessages(messagesByConversation[conversation.id] || [], messages, conversation.id, userId);\n writeLocalMessages(messagesByConversation, userId);\n return messagesByConversation[conversation.id];\n }\n hideMessages(conversation, messages) {\n const items = Array.isArray(messages) ? messages : [messages];\n if (!conversation?.id || !items.length) {\n return;\n }\n const userId = this.currentUser?.userId || '';\n storeMessageKeys(LOCAL_HIDDEN_MESSAGE_STORAGE_KEY, conversation.id, items, userId);\n const messagesByConversation = readLocalMessages(userId);\n messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);\n writeLocalMessages(messagesByConversation, userId);\n }\n markMessagesRecalled(conversation, messages) {\n const items = Array.isArray(messages) ? messages : [messages];\n if (!conversation?.id || !items.length) {\n return;\n }\n const userId = this.currentUser?.userId || '';\n storeMessageKeys(LOCAL_RECALLED_MESSAGE_STORAGE_KEY, conversation.id, items, userId);\n const messagesByConversation = readLocalMessages(userId);\n messagesByConversation[conversation.id] = applyLocalMessageState(conversation.id, messagesByConversation[conversation.id] || [], userId);\n writeLocalMessages(messagesByConversation, userId);\n }\n async recallMessage(conversation, message) {\n const messageUid = String(message?.messageUid || message?.id || '').trim();\n if (!/^\\d+$/.test(messageUid)) {\n throw new Error('缺少可撤回的消息ID');\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.messageActionApi, {\n action: 'recall',\n userId: this.currentUser?.userId || message.from || '',\n messageUid\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '撤回失败');\n }\n this.markMessagesRecalled(conversation, [message]);\n return response.data.result;\n }\n async editMessage(conversation, message, text) {\n const messageUid = String(message?.messageUid || message?.id || '').trim();\n if (!/^\\d+$/.test(messageUid)) {\n throw new Error('缺少可编辑的消息ID');\n }\n const nextText = String(text || '').trim();\n if (!nextText) {\n throw new Error('编辑内容不能为空');\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.messageActionApi, {\n action: 'edit',\n userId: this.currentUser?.userId || message.from || '',\n messageUid,\n text: nextText\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '编辑失败');\n }\n const result = response.data?.result?.message || {};\n const editedMessage = {\n ...message,\n text: result.text || nextText,\n status: 'delivered',\n deliveryStatus: 'delivered',\n editedAt: Number(result.editedAt || Date.now()),\n activityTimestamp: Number(result.editedAt || Date.now())\n };\n saveLocalMessage(editedMessage, this.currentUser?.userId || '');\n this.emit('messageStatusChanged', editedMessage);\n return editedMessage;\n }\n async getMessageDetail(conversation, message) {\n const messageUid = String(message?.messageUid || message?.id || '').trim();\n if (!messageUid) {\n throw new Error('缺少消息ID');\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.messageDetailApi, {\n userId: this.currentUser?.userId || '',\n target: conversation?.target || conversation?.raw?.target || conversation?.id?.replace(/^single-/, '') || '',\n conversationType: conversation?.type || conversation?.raw?.type || 'single',\n messageUid\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '消息详情加载失败');\n }\n return response.data?.result?.detail || null;\n }\n async sendTextMessage(conversation, text, initialMessage = null) {\n const senderRole = conversation?.role || conversation?.raw?.role || '';\n const message = initialMessage || {\n id: randomId(),\n conversationId: conversation.id,\n from: this.currentUser?.userId || 'me',\n senderRole,\n direction: 'out',\n type: 'text',\n text,\n status: 'sending',\n deliveryStatus: 'sending',\n timestamp: Date.now()\n };\n saveLocalMessage(message, this.currentUser?.userId || '');\n if (!initialMessage) {\n this.emit('messageSent', message);\n }\n try {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.sendMessageApi, {\n sender: this.currentUser?.userId || '',\n target: conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''),\n conversationType: conversation.type || conversation.raw?.type || 0,\n text\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '发送失败');\n }\n const sentMessage = {\n ...message,\n status: 'sent',\n deliveryStatus: 'sent',\n messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',\n senderRole: response.data?.result?.senderRole || message.senderRole || '',\n serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,\n timestamp: message.timestamp,\n displayTimestamp: message.displayTimestamp || message.timestamp\n };\n saveLocalMessage(sentMessage, this.currentUser?.userId || '');\n this.emit('messageStatusChanged', sentMessage);\n return sentMessage;\n } catch (error) {\n const failedMessage = {\n ...message,\n status: 'failed',\n deliveryStatus: '',\n error: error.response?.data?.message || error.message || '发送失败'\n };\n saveLocalMessage(failedMessage, this.currentUser?.userId || '');\n this.emit('messageStatusChanged', failedMessage);\n return failedMessage;\n }\n }\n async sendAttachmentMessage(conversation, {\n type,\n file,\n text = ''\n }, initialMessage = null) {\n const senderRole = conversation?.role || conversation?.raw?.role || '';\n const message = initialMessage || {\n id: randomId(),\n conversationId: conversation.id,\n from: this.currentUser?.userId || 'me',\n senderRole,\n direction: 'out',\n type,\n text,\n attachment: {\n type,\n name: file?.name || (type === 'image' ? '图片' : '文件'),\n mime: file?.type || '',\n size: file?.size || 0,\n url: type === 'image' && file ? URL.createObjectURL(file) : ''\n },\n status: 'sending',\n deliveryStatus: 'sending',\n timestamp: Date.now()\n };\n saveLocalMessage(message, this.currentUser?.userId || '');\n if (!initialMessage) {\n this.emit('messageSent', message);\n }\n try {\n const formData = new FormData();\n formData.append('sender', this.currentUser?.userId || '');\n formData.append('target', conversation.target || conversation.raw?.target || conversation.id.replace(/^single-/, ''));\n formData.append('conversationType', conversation.type || conversation.raw?.type || 0);\n formData.append('messageType', type);\n formData.append('text', text || '');\n formData.append('attachment', file);\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.sendMessageApi, formData, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '发送失败');\n }\n const sentMessage = {\n ...message,\n status: 'sent',\n deliveryStatus: 'sent',\n messageUid: response.data?.result?.messageUid ? String(response.data.result.messageUid) : '',\n senderRole: response.data?.result?.senderRole || message.senderRole || '',\n attachment: response.data?.result?.attachment || message.attachment,\n serverTimestamp: Number(response.data?.result?.timestamp || 0) || null,\n timestamp: message.timestamp,\n displayTimestamp: message.displayTimestamp || message.timestamp\n };\n saveLocalMessage(sentMessage, this.currentUser?.userId || '');\n this.emit('messageStatusChanged', sentMessage);\n return sentMessage;\n } catch (error) {\n const failedMessage = {\n ...message,\n status: 'failed',\n deliveryStatus: '',\n error: error.response?.data?.message || error.message || '发送失败'\n };\n saveLocalMessage(failedMessage, this.currentUser?.userId || '');\n this.emit('messageStatusChanged', failedMessage);\n return failedMessage;\n }\n }\n getContactList() {\n return [];\n }\n async getServerContactList(userId) {\n if (!userId) {\n return [];\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.contactsApi, {\n userId\n }, {\n withCredentials: false,\n headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.contactsApi)\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '联系人加载失败');\n }\n return (response.data?.result?.contacts || []).map(item => {\n return this.mapContact(item.uid, {\n alias: item.alias\n }, {\n uid: item.uid,\n displayName: item.displayName,\n name: item.name,\n mobile: item.mobile,\n portrait: item.portrait,\n address: item.address,\n friendAlias: item.alias\n });\n }).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));\n }\n async addContact(userId, keyword, reason = '') {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.addContactApi, {\n userId,\n keyword,\n reason\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '添加联系人失败');\n }\n const item = response.data?.result?.contact;\n if (!item?.uid) {\n return null;\n }\n return this.mapContact(item.uid, {\n alias: item.alias\n }, {\n uid: item.uid,\n displayName: item.displayName,\n name: item.name,\n mobile: item.mobile,\n portrait: item.portrait,\n address: item.address,\n friendAlias: item.alias\n });\n }\n normalizeConversation(conversation) {\n const title = getTitle(conversation?.title, conversation?.target || '');\n return {\n ...conversation,\n id: conversation?.id || `${conversation?.type === 'single' ? 'single' : 'group'}-${conversation?.target}`,\n target: conversation?.target || conversation?.raw?.target || '',\n title,\n subtitle: conversation?.subtitle || '',\n unread: Number(conversation?.unread || 0),\n portrait: conversation?.portrait || '',\n avatarText: conversation?.avatarText || title.slice(0, 1).toUpperCase(),\n updatedAt: Number(conversation?.updatedAt || Date.now()),\n raw: conversation?.raw || {\n type: conversation?.type === 'single' ? 'single' : 'group',\n target: conversation?.target || '',\n line: 0\n }\n };\n }\n async createGroup(userId, {\n name,\n memberIds = [],\n announcement = '',\n welcomeText = '',\n channel = false\n }) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: channel ? 'create_channel' : 'create_group',\n userId,\n name,\n memberIds,\n announcement,\n welcomeText\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || (channel ? '创建公告群失败' : '创建群组失败'));\n }\n return this.normalizeConversation(response.data?.result?.conversation || {});\n }\n async joinGroup(userId, groupKey) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'join_group',\n userId,\n groupKey\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '加入群组失败');\n }\n return this.normalizeConversation(response.data?.result?.conversation || {});\n }\n async broadcastMessage(userId, targetIds, text) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'broadcast',\n userId,\n targetIds,\n text\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '群发失败');\n }\n return response.data?.result || {};\n }\n async getGroupDetail(userId, groupId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'group_detail',\n userId,\n groupId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '群资料加载失败');\n }\n return response.data?.result?.group || null;\n }\n async getGroupMembers(userId, groupId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'group_members',\n userId,\n groupId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '群员加载失败');\n }\n return response.data?.result?.members || [];\n }\n async updateGroupAlias(userId, groupId, alias) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'update_group_alias',\n userId,\n groupId,\n alias\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '本群昵称保存失败');\n }\n return response.data?.result?.alias || '';\n }\n async leaveGroup(userId, groupId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'leave_group',\n userId,\n groupId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '退出群组失败');\n }\n return response.data?.result || {};\n }\n async dismissGroup(userId, groupId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'dismiss_group',\n userId,\n groupId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '解散群组失败');\n }\n return response.data?.result || {};\n }\n async transferGroup(userId, groupId, targetUserId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'transfer_group',\n userId,\n groupId,\n targetUserId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '转让群组失败');\n }\n return response.data?.result || {};\n }\n async setGroupAdmins(userId, groupId, adminIds) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'set_group_admins',\n userId,\n groupId,\n adminIds\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '管理员设置失败');\n }\n return response.data?.result || {};\n }\n async updateGroupProfile(userId, groupId, {\n name,\n announcement,\n welcomeText\n }) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'update_group_profile',\n userId,\n groupId,\n name,\n announcement,\n welcomeText\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '群资料保存失败');\n }\n return response.data?.result || {};\n }\n async kickGroupMembers(userId, groupId, targetIds) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'kick_group_members',\n userId,\n groupId,\n targetIds\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '踢人失败');\n }\n return response.data?.result || {};\n }\n async updateGroupMuteSetting(userId, groupId, setting) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.conversationActionsApi, {\n action: 'update_mute_setting',\n userId,\n groupId,\n ...setting\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '禁言设置保存失败');\n }\n return response.data?.result?.muteSetting || null;\n }\n async updateContactAlias(userId, targetId, alias) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.updateAliasApi, {\n userId,\n targetId,\n alias\n }, {\n withCredentials: false,\n headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.updateAliasApi)\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '备注名修改失败');\n }\n return response.data?.result?.contact?.alias || '';\n }\n async getProfile(userId) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.profileApi, {\n action: 'get',\n userId\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '用户资料加载失败');\n }\n return response.data?.result?.profile || null;\n }\n async updateProfile(userId, {\n displayName,\n portraitFile\n }) {\n const formData = new FormData();\n formData.append('action', 'update');\n formData.append('userId', userId);\n formData.append('displayName', displayName);\n if (portraitFile) {\n formData.append('portraitFile', portraitFile);\n }\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.profileApi, formData, {\n withCredentials: false,\n headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.appServer)\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || '用户资料保存失败');\n }\n return response.data?.result?.profile || null;\n }\n async changePassword({\n oldPassword,\n newPassword\n }) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.changePasswordApi, {\n oldPassword,\n newPassword\n }, {\n withCredentials: false,\n headers: this.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.changePasswordApi)\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || response.data?.msg || '密码修改失败');\n }\n return true;\n }\n async resetPasswordWithCode({\n mobile,\n resetCode,\n newPassword\n }) {\n const response = await axios__WEBPACK_IMPORTED_MODULE_17__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.resetPasswordApi, {\n mobile,\n resetCode,\n newPassword\n }, {\n withCredentials: false\n });\n if (response.data?.code !== 0) {\n throw new Error(response.data?.message || response.data?.msg || '密码设置失败');\n }\n return true;\n }\n refreshContactList() {\n const contacts = this.getContactList();\n this.emit('contactsChanged', contacts);\n return contacts;\n }\n createSingleConversation(userId, userInfo = null) {\n const title = getTitle(userInfo?.title || userInfo?.displayName || userInfo?.name, userId);\n return {\n id: `single-${userId}`,\n type: 'single',\n target: userId,\n title,\n subtitle: '',\n unread: 0,\n portrait: userInfo?.portrait || '',\n avatarText: title.slice(0, 1).toUpperCase(),\n updatedAt: Date.now(),\n raw: {\n type: 'single',\n target: userId,\n line: 0\n }\n };\n }\n mapContact(userId, friend, userInfo) {\n const title = getTitle(userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name, userId);\n return {\n id: userId,\n uid: userId,\n title,\n subtitle: userInfo?.mobile || userInfo?.name || userId,\n portrait: userInfo?.portrait || '',\n address: userInfo?.address || '',\n avatarText: title.slice(0, 1).toUpperCase(),\n alias: friend?.alias || userInfo?.friendAlias || '',\n rawFriend: friend,\n rawUser: userInfo\n };\n }\n on(eventName, handler) {\n if (!this.listeners.has(eventName)) {\n this.listeners.set(eventName, new Set());\n }\n this.listeners.get(eventName).add(handler);\n return () => this.off(eventName, handler);\n }\n off(eventName, handler) {\n this.listeners.get(eventName)?.delete(handler);\n }\n emit(eventName, payload) {\n this.listeners.get(eventName)?.forEach(handler => handler(payload));\n }\n persistAppToken(url, response) {\n const appToken = response.headers?.authtoken || response.headers?.authToken;\n if (appToken) {\n localStorage.setItem(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.authTokenStoragePrefix + this.getUrlHost(url), appToken);\n }\n }\n getAppAuthHeaders(url) {\n const host = this.getUrlHost(url);\n if (!host) {\n return {};\n }\n const token = localStorage.getItem(_config__WEBPACK_IMPORTED_MODULE_18__.appConfig.authTokenStoragePrefix + host);\n return token ? {\n authToken: token\n } : {};\n }\n getUrlHost(url) {\n try {\n return new URL(url, window.location.origin).host;\n } catch (error) {\n return '';\n }\n }\n}\nconst imClient = new HttpImClient();\n\n//# sourceURL=webpack://jc-web-im/./src/services/httpImClient.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/imClient.js":
|
||
/*!**********************************!*\
|
||
!*** ./src/services/imClient.js ***!
|
||
\**********************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DocumentedHttpImClient: function() { return /* reexport safe */ _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__.DocumentedHttpImClient; },\n/* harmony export */ HttpImClient: function() { return /* reexport safe */ _httpImClient__WEBPACK_IMPORTED_MODULE_1__.HttpImClient; },\n/* harmony export */ LongConnectionImClient: function() { return /* reexport safe */ _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__.LongConnectionImClient; },\n/* harmony export */ WildfireImClient: function() { return /* binding */ UnsupportedWildfireImClient; },\n/* harmony export */ imClient: function() { return /* binding */ imClient; }\n/* harmony export */ });\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./httpImClient */ \"./src/services/httpImClient.js\");\n/* harmony import */ var _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./longConnectionImClient */ \"./src/services/longConnectionImClient.js\");\n/* harmony import */ var _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./documentedHttpImClient */ \"./src/services/documentedHttpImClient.js\");\n\n\n\n\nclass UnsupportedWildfireImClient {\n constructor() {\n throw new Error('当前本地社区版 Web 客户端未启用 WildFire Web SDK');\n }\n}\nconst imClient = _config__WEBPACK_IMPORTED_MODULE_0__.appConfig.sdkMode === 'wildfire' ? new UnsupportedWildfireImClient() : _config__WEBPACK_IMPORTED_MODULE_0__.appConfig.sdkMode === 'custom-ws' || _config__WEBPACK_IMPORTED_MODULE_0__.appConfig.sdkMode === 'long' ? new _longConnectionImClient__WEBPACK_IMPORTED_MODULE_2__.LongConnectionImClient() : _config__WEBPACK_IMPORTED_MODULE_0__.appConfig.sdkMode === 'legacy-http' ? new _httpImClient__WEBPACK_IMPORTED_MODULE_1__.HttpImClient() : new _documentedHttpImClient__WEBPACK_IMPORTED_MODULE_3__.DocumentedHttpImClient();\n\n\n//# sourceURL=webpack://jc-web-im/./src/services/imClient.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/longConnectionImClient.js":
|
||
/*!************************************************!*\
|
||
!*** ./src/services/longConnectionImClient.js ***!
|
||
\************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ LongConnectionImClient: function() { return /* binding */ LongConnectionImClient; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _httpImClient__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./httpImClient */ \"./src/services/httpImClient.js\");\n\n\n\n\n\n\nconst HEARTBEAT_INTERVAL_MS = 25000;\nconst RECONNECT_MIN_MS = 1000;\nconst RECONNECT_MAX_MS = 15000;\nfunction buildWsUrl() {\n if (_config__WEBPACK_IMPORTED_MODULE_4__.appConfig.wsUrl) {\n return _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.wsUrl;\n }\n const protocol = _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.useWss ? 'wss' : 'ws';\n const host = _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.imServerHost || window.location.hostname;\n const port = _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.imRoutePort ? `:${_config__WEBPACK_IMPORTED_MODULE_4__.appConfig.imRoutePort}` : '';\n const path = _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.wsPath?.startsWith('/') ? _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.wsPath : `/${_config__WEBPACK_IMPORTED_MODULE_4__.appConfig.wsPath || 'ws'}`;\n return `${protocol}://${host}${port}${path}`;\n}\nfunction normalizeConversationId(payload) {\n const target = payload.target || payload.to || payload.receiver || payload.conversationTarget || payload.from || payload.sender;\n return payload.conversationId || (target ? `single-${target}` : '');\n}\nfunction normalizeIncomingMessage(payload, currentUserId) {\n const item = payload.message || payload;\n const from = item.from || item.sender || item.fromUser || '';\n const target = item.target || item.to || item.receiver || '';\n const direction = from && String(from) === String(currentUserId) ? 'out' : 'in';\n const conversationId = item.conversationId || normalizeConversationId({\n ...item,\n target: direction === 'out' ? target : from\n });\n if (!conversationId) {\n return null;\n }\n const status = item.status || item.deliveryStatus || 'sent';\n return {\n id: item.id || item.messageId || item.messageUid || `${Date.now()}${Math.random().toString(16).slice(2)}`,\n messageUid: item.messageUid || item.uid || item.messageId || '',\n conversationId,\n from,\n target,\n direction,\n type: item.type || 'text',\n text: item.text || item.content || item.searchableContent || '',\n status,\n deliveryStatus: item.deliveryStatus || (direction === 'out' ? status : ''),\n timestamp: Number(item.timestamp || item.serverTimestamp || Date.now()),\n displayTimestamp: Number(item.displayTimestamp || item.timestamp || item.serverTimestamp || Date.now()),\n raw: item\n };\n}\nclass LongConnectionImClient extends _httpImClient__WEBPACK_IMPORTED_MODULE_5__.HttpImClient {\n constructor() {\n super();\n this.socket = null;\n this.wsUrl = buildWsUrl();\n this.heartbeatTimer = null;\n this.reconnectTimer = null;\n this.reconnectAttempts = 0;\n this.manualClose = false;\n }\n getSdkVersion() {\n return 'JC-LC/0.1';\n }\n shouldUseMessagePolling() {\n return !this.connected;\n }\n async ensureSdk() {\n if (typeof WebSocket === 'undefined') {\n throw new Error('当前浏览器不支持 WebSocket 长连接');\n }\n return true;\n }\n connect(userId, token) {\n this.currentUser = {\n userId,\n token\n };\n this.manualClose = false;\n this.openSocket();\n }\n disconnect() {\n this.manualClose = true;\n this.clearReconnectTimer();\n this.clearHeartbeatTimer();\n if (this.socket) {\n this.socket.close();\n this.socket = null;\n }\n super.disconnect();\n }\n openSocket() {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.sendAuthFrame();\n return;\n }\n if (this.socket?.readyState === WebSocket.CONNECTING) {\n return;\n }\n this.emit('connectionStatusChanged', {\n connected: false,\n statusText: '长连接连接中'\n });\n try {\n this.socket = new WebSocket(this.wsUrl);\n this.socket.binaryType = 'arraybuffer';\n } catch (error) {\n this.emit('connectionStatusChanged', {\n connected: false,\n statusText: '长连接创建失败,使用HTTP补偿'\n });\n this.scheduleReconnect();\n return;\n }\n this.socket.onopen = () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.emit('connectionStatusChanged', {\n connected: true,\n statusText: '长连接已连接'\n });\n this.sendAuthFrame();\n this.startHeartbeat();\n this.refreshConversationList();\n };\n this.socket.onmessage = event => {\n this.handleFrame(event.data);\n };\n this.socket.onerror = () => {\n this.emit('connectionStatusChanged', {\n connected: false,\n statusText: '长连接异常,使用HTTP补偿'\n });\n };\n this.socket.onclose = () => {\n this.connected = false;\n this.clearHeartbeatTimer();\n this.socket = null;\n if (this.manualClose) {\n return;\n }\n this.emit('connectionStatusChanged', {\n connected: false,\n statusText: '长连接重连中'\n });\n this.scheduleReconnect();\n };\n }\n sendAuthFrame() {\n this.sendFrame({\n type: 'auth',\n userId: this.currentUser?.userId || '',\n token: this.currentUser?.token || '',\n clientId: this.getClientId(),\n platform: _config__WEBPACK_IMPORTED_MODULE_4__.appConfig.platform,\n timestamp: Date.now()\n });\n }\n sendFrame(frame) {\n if (this.socket?.readyState !== WebSocket.OPEN) {\n return false;\n }\n this.socket.send(JSON.stringify(frame));\n return true;\n }\n handleFrame(rawData) {\n if (rawData instanceof ArrayBuffer) {\n this.emit('rawFrameReceived', rawData);\n return;\n }\n let payload;\n try {\n payload = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;\n } catch (error) {\n return;\n }\n const type = payload.type || payload.event || payload.cmd || '';\n if (type === 'pong' || type === 'auth_ok' || type === 'connected') {\n return;\n }\n if (type === 'contactsChanged') {\n this.emit('contactsChanged', payload.contacts || []);\n return;\n }\n if (type === 'conversationsChanged') {\n this.emit('conversationsChanged', payload.conversations || []);\n return;\n }\n if (type === 'messages' && Array.isArray(payload.messages)) {\n payload.messages.map(message => normalizeIncomingMessage(message, this.currentUser?.userId)).filter(Boolean).forEach(message => this.emit('messageReceived', message));\n return;\n }\n const message = normalizeIncomingMessage(payload, this.currentUser?.userId);\n if (message) {\n this.emit(message.direction === 'out' ? 'messageStatusChanged' : 'messageReceived', message);\n }\n }\n startHeartbeat() {\n this.clearHeartbeatTimer();\n this.heartbeatTimer = window.setInterval(() => {\n this.sendFrame({\n type: 'ping',\n timestamp: Date.now()\n });\n }, HEARTBEAT_INTERVAL_MS);\n }\n clearHeartbeatTimer() {\n if (this.heartbeatTimer) {\n window.clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n scheduleReconnect() {\n this.clearReconnectTimer();\n const delay = Math.min(RECONNECT_MAX_MS, RECONNECT_MIN_MS * 2 ** this.reconnectAttempts);\n this.reconnectAttempts += 1;\n this.reconnectTimer = window.setTimeout(() => {\n this.openSocket();\n }, delay);\n }\n clearReconnectTimer() {\n if (this.reconnectTimer) {\n window.clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n\n//# sourceURL=webpack://jc-web-im/./src/services/longConnectionImClient.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/mediaProxy.js":
|
||
/*!************************************!*\
|
||
!*** ./src/services/mediaProxy.js ***!
|
||
\************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ imageDisplayUrl: function() { return /* binding */ imageDisplayUrl; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.set.difference.v2.js */ \"./node_modules/core-js/modules/es.set.difference.v2.js\");\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.set.intersection.v2.js */ \"./node_modules/core-js/modules/es.set.intersection.v2.js\");\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.set.is-disjoint-from.v2.js */ \"./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js\");\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.set.is-subset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-subset-of.v2.js\");\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.set.is-superset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-superset-of.v2.js\");\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.set.symmetric-difference.v2.js */ \"./node_modules/core-js/modules/es.set.symmetric-difference.v2.js\");\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.set.union.v2.js */ \"./node_modules/core-js/modules/es.set.union.v2.js\");\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_9__);\n\n\n\n\n\n\n\n\n\n\nfunction configuredProxyHosts() {\n const configured = window.JC_WEB_IM_CONFIG?.mediaProxyHosts;\n const values = Array.isArray(configured) ? configured : String(configured || '').split(/[\\s,]+/);\n return new Set(values.map(value => String(value || '').trim().toLowerCase().replace(/\\.$/, '')).filter(Boolean));\n}\nfunction imageDisplayUrl(value) {\n const source = String(value || '').trim();\n if (!source || source.startsWith('blob:') || source.startsWith('data:')) {\n return source;\n }\n try {\n const url = new URL(source, window.location.origin);\n if (url.protocol !== 'https:' || !configuredProxyHosts().has(url.hostname.toLowerCase())) {\n return source;\n }\n const proxyUrl = new URL('/api/media_proxy.php', window.location.origin);\n proxyUrl.searchParams.set('url', url.toString());\n return proxyUrl.toString();\n } catch (error) {\n return source;\n }\n}\n\n//# sourceURL=webpack://jc-web-im/./src/services/mediaProxy.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/services/realtimeNotifications.js":
|
||
/*!***********************************************!*\
|
||
!*** ./src/services/realtimeNotifications.js ***!
|
||
\***********************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ realtimeNotifications: function() { return /* binding */ realtimeNotifications; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n\n\n\n\nclass RealtimeNotificationClient {\n constructor() {\n this.source = null;\n this.userId = '';\n this.handler = null;\n this.reconnectTimer = null;\n this.reconnectAttempt = 0;\n this.generation = 0;\n }\n isConnected() {\n return this.source?.readyState === WebSocket.OPEN;\n }\n start(userId, handler) {\n this.stop();\n if (!_config__WEBPACK_IMPORTED_MODULE_2__.appConfig.sseEnabled || !userId || typeof window.WebSocket !== 'function') return;\n this.userId = userId;\n this.handler = handler;\n this.generation += 1;\n this.open(this.generation);\n }\n stop() {\n this.generation += 1;\n window.clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n if (this.source) this.source.close();\n this.source = null;\n this.userId = '';\n this.handler = null;\n this.reconnectAttempt = 0;\n }\n async open(generation) {\n try {\n const response = await axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"].post(_config__WEBPACK_IMPORTED_MODULE_2__.appConfig.sseTicketApi, {\n userId: this.userId\n }, {\n withCredentials: false,\n headers: _services_imClient__WEBPACK_IMPORTED_MODULE_3__.imClient.getAppAuthHeaders(_config__WEBPACK_IMPORTED_MODULE_2__.appConfig.appServer)\n });\n if (generation !== this.generation) return;\n if (response.data?.code !== 0) throw new Error(response.data?.message || '实时通知凭证申请失败');\n const ticket = response.data?.result?.ticket || '';\n if (!ticket) throw new Error('实时通知凭证为空');\n const separator = _config__WEBPACK_IMPORTED_MODULE_2__.appConfig.sseUrl.includes('?') ? '&' : '?';\n const endpoint = `${_config__WEBPACK_IMPORTED_MODULE_2__.appConfig.sseUrl}${separator}ticket=${encodeURIComponent(ticket)}`;\n const socketUrl = endpoint.startsWith('ws://') || endpoint.startsWith('wss://') ? endpoint : `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;\n const source = new WebSocket(socketUrl);\n this.source = source;\n source.onopen = () => {\n this.reconnectAttempt = 0;\n };\n source.onmessage = event => {\n if (generation !== this.generation) return;\n let payload = {};\n try {\n payload = JSON.parse(event.data || '{}');\n } catch (error) {\n payload = {};\n }\n if (payload.type !== 'message-notification') return;\n this.handler?.(payload);\n };\n source.onerror = () => {\n if (generation !== this.generation) return;\n source.close();\n if (this.source === source) this.source = null;\n this.scheduleReconnect(generation);\n };\n source.onclose = () => {\n if (generation !== this.generation || this.source !== source) return;\n this.source = null;\n this.scheduleReconnect(generation);\n };\n } catch (error) {\n if (generation === this.generation) this.scheduleReconnect(generation);\n }\n }\n scheduleReconnect(generation) {\n window.clearTimeout(this.reconnectTimer);\n const delay = Math.min(30000, 1000 * 2 ** Math.min(this.reconnectAttempt, 5));\n this.reconnectAttempt += 1;\n this.reconnectTimer = window.setTimeout(() => this.open(generation), delay);\n }\n}\nconst realtimeNotifications = new RealtimeNotificationClient();\n\n//# sourceURL=webpack://jc-web-im/./src/services/realtimeNotifications.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/stores/contacts.js":
|
||
/*!********************************!*\
|
||
!*** ./src/stores/contacts.js ***!
|
||
\********************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useContactStore: function() { return /* binding */ useContactStore; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert.js */ \"./node_modules/core-js/modules/es.map.get-or-insert.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert-computed.js */ \"./node_modules/core-js/modules/es.map.get-or-insert-computed.js\");\n/* 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__);\n/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! pinia */ \"./node_modules/pinia/dist/pinia.mjs\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n/* harmony import */ var _stores_conversations__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/stores/conversations */ \"./src/stores/conversations.js\");\n/* harmony import */ var _stores_navigation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/stores/navigation */ \"./src/stores/navigation.js\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/stores/session */ \"./src/stores/session.js\");\n\n\n\n\n\n\n\n\n\n\n\nconst CONTACT_CACHE_MS = 15000;\nfunction normalizeContacts(contacts) {\n const unique = new Map();\n contacts.forEach(contact => {\n const uid = String(contact.uid || contact.id || '').trim();\n if (!uid) {\n return;\n }\n const normalized = {\n ...contact,\n id: String(contact.id || uid),\n uid\n };\n unique.set(uid, {\n ...(unique.get(uid) || {}),\n ...normalized\n });\n });\n return Array.from(unique.values()).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));\n}\nconst useContactStore = (0,pinia__WEBPACK_IMPORTED_MODULE_6__.defineStore)('contacts', {\n state: () => ({\n contacts: [],\n activeId: '',\n loading: false,\n eventsBound: false,\n refreshSerial: 0,\n refreshPromise: null,\n loadedForUserId: '',\n loadedAt: 0,\n actionError: '',\n actionInfo: ''\n }),\n getters: {\n activeContact(state) {\n return state.contacts.find(item => item.id === state.activeId) || state.contacts[0] || null;\n }\n },\n actions: {\n bindImEvents() {\n if (this.eventsBound) {\n return;\n }\n this.eventsBound = true;\n _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.on('contactsChanged', contacts => {\n if (!contacts.length && this.contacts.length) {\n return;\n }\n this.contacts = normalizeContacts(contacts);\n if (!this.contacts.find(item => item.id === this.activeId)) {\n this.activeId = this.contacts[0]?.id || '';\n }\n });\n },\n async refreshContacts(options = {}) {\n this.bindImEvents();\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__.useSessionStore)();\n const requestUserId = session.userId;\n const force = Boolean(options.force);\n if (!requestUserId) {\n this.clearContacts();\n return [];\n }\n if (!force && this.contacts.length && this.loadedForUserId === requestUserId && Date.now() - this.loadedAt < CONTACT_CACHE_MS) {\n return this.contacts;\n }\n if (this.refreshPromise && !force) {\n return this.refreshPromise;\n }\n const serial = this.refreshSerial + 1;\n this.refreshSerial = serial;\n this.loading = true;\n this.refreshPromise = (async () => {\n this.contacts = normalizeContacts(_services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.refreshContactList());\n if (!this.contacts.find(item => item.id === this.activeId)) {\n this.activeId = this.contacts[0]?.id || '';\n }\n if (!this.contacts.length || force) {\n const serverContacts = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.getServerContactList(requestUserId);\n if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__.useSessionStore)().userId !== requestUserId) {\n return this.contacts;\n }\n this.contacts = normalizeContacts(serverContacts);\n this.loadedForUserId = requestUserId;\n this.loadedAt = Date.now();\n if (!this.contacts.find(item => item.id === this.activeId)) {\n this.activeId = this.contacts[0]?.id || '';\n }\n }\n window.setTimeout(() => {\n if (serial !== this.refreshSerial || (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__.useSessionStore)().userId !== requestUserId) {\n return;\n }\n const latest = _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.getContactList(false);\n if (latest.length || !this.contacts.length) {\n this.contacts = normalizeContacts(latest);\n this.loadedForUserId = requestUserId;\n this.loadedAt = Date.now();\n if (!this.contacts.find(item => item.id === this.activeId)) {\n this.activeId = this.contacts[0]?.id || '';\n }\n }\n }, 1200);\n return this.contacts;\n })();\n try {\n return await this.refreshPromise;\n } finally {\n if (serial === this.refreshSerial) {\n this.loading = false;\n this.refreshPromise = null;\n }\n }\n },\n async addContact(keyword) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__.useSessionStore)();\n const value = String(keyword || '').trim();\n this.actionError = '';\n this.actionInfo = '';\n if (!session.userId) {\n this.actionError = '请先登录';\n return false;\n }\n if (!value) {\n this.actionError = '请输入用户ID、手机号或用户名';\n return false;\n }\n this.loading = true;\n try {\n const contact = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.addContact(session.userId, value, '添加联系人');\n if (contact) {\n this.contacts = normalizeContacts([...this.contacts, contact]);\n this.activeId = contact.id;\n }\n this.actionInfo = '联系人已添加';\n await this.refreshContacts({\n force: true\n });\n return true;\n } catch (error) {\n this.actionError = error.message || '添加联系人失败';\n return false;\n } finally {\n this.loading = false;\n }\n },\n async updateContactAlias(contactId, alias) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_10__.useSessionStore)();\n const targetId = String(contactId || '').trim();\n const nextAlias = String(alias || '').trim();\n this.actionError = '';\n this.actionInfo = '';\n if (!session.userId) {\n this.actionError = '请先登录';\n return false;\n }\n if (!targetId) {\n this.actionError = '缺少联系人ID';\n return false;\n }\n try {\n const savedAlias = await _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.updateContactAlias(session.userId, targetId, nextAlias);\n this.contacts = normalizeContacts(this.contacts.map(item => {\n if (item.uid !== targetId && item.id !== targetId) {\n return item;\n }\n const rawUser = {\n ...(item.rawUser || {}),\n friendAlias: savedAlias\n };\n const rawFriend = {\n ...(item.rawFriend || {}),\n alias: savedAlias\n };\n const title = savedAlias || rawUser.displayName || rawUser.name || item.uid;\n return {\n ...item,\n title,\n avatarText: title.slice(0, 1).toUpperCase(),\n alias: savedAlias,\n rawFriend,\n rawUser\n };\n }));\n this.loadedAt = Date.now();\n this.actionInfo = '备注名已修改';\n return true;\n } catch (error) {\n this.actionError = error.message || '备注名修改失败';\n return false;\n }\n },\n clearContacts() {\n this.refreshSerial += 1;\n this.contacts = [];\n this.activeId = '';\n this.loading = false;\n this.refreshPromise = null;\n this.loadedForUserId = '';\n this.loadedAt = 0;\n this.actionError = '';\n this.actionInfo = '';\n },\n setActiveContact(id) {\n this.activeId = id;\n },\n openChat(contact) {\n if (!contact) {\n return;\n }\n const conversations = (0,_stores_conversations__WEBPACK_IMPORTED_MODULE_8__.useConversationStore)();\n const navigation = (0,_stores_navigation__WEBPACK_IMPORTED_MODULE_9__.useNavigationStore)();\n const conversation = _services_imClient__WEBPACK_IMPORTED_MODULE_7__.imClient.createSingleConversation(contact.uid, contact);\n conversations.upsertConversation(conversation);\n conversations.setActiveConversation(conversation.id);\n navigation.showMessages();\n }\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/stores/contacts.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/stores/conversations.js":
|
||
/*!*************************************!*\
|
||
!*** ./src/stores/conversations.js ***!
|
||
\*************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useConversationStore: function() { return /* binding */ useConversationStore; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.iterator.constructor.js */ \"./node_modules/core-js/modules/es.iterator.constructor.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_filter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.iterator.filter.js */ \"./node_modules/core-js/modules/es.iterator.filter.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_find_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.iterator.find.js */ \"./node_modules/core-js/modules/es.iterator.find.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_flat_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.iterator.flat-map.js */ \"./node_modules/core-js/modules/es.iterator.flat-map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/es.iterator.for-each.js */ \"./node_modules/core-js/modules/es.iterator.for-each.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! core-js/modules/es.iterator.map.js */ \"./node_modules/core-js/modules/es.iterator.map.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_reduce_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.iterator.reduce.js */ \"./node_modules/core-js/modules/es.iterator.reduce.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/es.iterator.some.js */ \"./node_modules/core-js/modules/es.iterator.some.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert.js */ \"./node_modules/core-js/modules/es.map.get-or-insert.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_map_get_or_insert_computed_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! core-js/modules/es.map.get-or-insert-computed.js */ \"./node_modules/core-js/modules/es.map.get-or-insert-computed.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_difference_v2_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! core-js/modules/es.set.difference.v2.js */ \"./node_modules/core-js/modules/es.set.difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_intersection_v2_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! core-js/modules/es.set.intersection.v2.js */ \"./node_modules/core-js/modules/es.set.intersection.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_disjoint_from_v2_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! core-js/modules/es.set.is-disjoint-from.v2.js */ \"./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_subset_of_v2_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! core-js/modules/es.set.is-subset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-subset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_is_superset_of_v2_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! core-js/modules/es.set.is-superset-of.v2.js */ \"./node_modules/core-js/modules/es.set.is-superset-of.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_symmetric_difference_v2_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! core-js/modules/es.set.symmetric-difference.v2.js */ \"./node_modules/core-js/modules/es.set.symmetric-difference.v2.js\");\n/* 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__);\n/* harmony import */ var core_js_modules_es_set_union_v2_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! core-js/modules/es.set.union.v2.js */ \"./node_modules/core-js/modules/es.set.union.v2.js\");\n/* 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__);\n/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! pinia */ \"./node_modules/pinia/dist/pinia.mjs\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n/* harmony import */ var _stores_session__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @/stores/session */ \"./src/stores/session.js\");\n/* harmony import */ var _services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @/services/realtimeNotifications */ \"./src/services/realtimeNotifications.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst LOCAL_CONVERSATION_STORAGE_KEY = 'qmt-web-im-local-conversations-v2';\nconst LOCAL_FAVORITE_MESSAGES_KEY = 'qmt-web-im-favorite-messages-v1';\nfunction scopedStorageKey(baseKey) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n const scope = `${_config__WEBPACK_IMPORTED_MODULE_21__.appConfig.appServer || ''}:${session.userId || 'anonymous'}`;\n return `${baseKey}:${encodeURIComponent(scope)}`;\n}\nfunction readFavoriteMessages() {\n try {\n return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY)) || '[]');\n } catch (error) {\n return [];\n }\n}\nfunction writeFavoriteMessages(messages) {\n localStorage.setItem(scopedStorageKey(LOCAL_FAVORITE_MESSAGES_KEY), JSON.stringify(messages));\n}\nfunction readLocalConversations() {\n try {\n return JSON.parse(localStorage.getItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY)) || '[]');\n } catch (error) {\n return [];\n }\n}\nfunction writeLocalConversations(conversations) {\n localStorage.setItem(scopedStorageKey(LOCAL_CONVERSATION_STORAGE_KEY), JSON.stringify(conversations));\n}\nfunction randomId() {\n if (window.crypto && window.crypto.randomUUID) {\n return window.crypto.randomUUID().replaceAll('-', '');\n }\n return `${Date.now()}${Math.random().toString(16).slice(2)}`;\n}\nfunction messageKey(message) {\n return message.id || message.messageUid;\n}\nfunction messageStableKey(message) {\n return String(message?.messageUid || message?.id || '');\n}\nfunction messageActivityTimestamp(message) {\n return Number(message?.activityTimestamp || message?.editedAt || message?.displayTimestamp || message?.timestamp || 0);\n}\nfunction isRecalledMessage(message) {\n return Boolean(message?.recalled) || message?.status === 'recalled';\n}\nfunction attachmentLabel(message) {\n const attachment = message?.attachment;\n if (!attachment) {\n return '';\n }\n if (attachment.type === 'image') {\n return '[图片]';\n }\n return `[文件] ${attachment.name || '文件'}`;\n}\nfunction messagePreviewText(message) {\n if (isRecalledMessage(message)) {\n return `[${message?.recallStatus || '已撤回'}]`;\n }\n const text = String(message?.text || '').replace(/\\s+/g, ' ').trim();\n return text || attachmentLabel(message);\n}\nfunction quotePrefix(message) {\n const text = messagePreviewText(message);\n return text.length > 48 ? `${text.slice(0, 48)}...` : text;\n}\nasync function writeClipboard(text) {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n const element = document.createElement('textarea');\n element.value = text;\n element.setAttribute('readonly', 'readonly');\n element.style.position = 'fixed';\n element.style.left = '-9999px';\n document.body.appendChild(element);\n element.select();\n document.execCommand('copy');\n document.body.removeChild(element);\n}\nfunction isSameMessage(left, right) {\n if (left.messageUid && right.messageUid && left.messageUid === right.messageUid) {\n return true;\n }\n if (left.id && right.id && left.id === right.id) {\n return true;\n }\n 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;\n}\nfunction hasExactMessage(messages, message) {\n return messages.some(item => {\n if (item.id && message.id && item.id === message.id) {\n return true;\n }\n return item.messageUid && message.messageUid && item.messageUid === message.messageUid;\n });\n}\nfunction shouldUseMessagePolling() {\n return _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.shouldUseMessagePolling ? _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.shouldUseMessagePolling() : true;\n}\nfunction canMarkReadNow(options = {}) {\n if (typeof document === 'undefined') {\n return false;\n }\n if (document.visibilityState !== 'visible') {\n return false;\n }\n if (options.userAction) {\n return true;\n }\n return true;\n}\nfunction normalizeMessageForDisplay(message) {\n if (!message || message.attachment || String(message.text || '').trim()) {\n return message;\n }\n const contentType = Number(message.contentType || 0);\n const labels = {\n 3: '[图片加载失败]',\n 90: '[红包]',\n 105: '[领取了红包]'\n };\n if (!labels[contentType]) {\n return message;\n }\n return {\n ...message,\n type: 'text',\n text: labels[contentType]\n };\n}\nfunction mergeVisibleMessages(currentMessages, syncedMessages) {\n const merged = [...syncedMessages].map(normalizeMessageForDisplay);\n currentMessages.forEach(currentMessage => {\n currentMessage = normalizeMessageForDisplay(currentMessage);\n const exists = merged.some(message => isSameMessage(message, currentMessage));\n const shouldKeepLocal = currentMessage.status === 'sending' || currentMessage.status === 'failed' || currentMessage.direction === 'out' && currentMessage.status === 'sent' && Date.now() - Number(currentMessage.timestamp || 0) < 30000;\n if (!exists && shouldKeepLocal) {\n merged.push(currentMessage);\n }\n });\n return merged.filter((message, index, messages) => {\n const key = messageKey(message);\n return messages.findIndex(item => messageKey(item) === key) === index;\n }).sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0));\n}\nfunction incomingEditedMessages(previousMessages, nextMessages) {\n const previousByKey = new Map();\n (previousMessages || []).forEach(message => {\n const key = messageStableKey(message);\n if (key) {\n previousByKey.set(key, message);\n }\n });\n return (nextMessages || []).filter(message => {\n if (message.direction !== 'in') {\n return false;\n }\n const editedAt = Number(message.editedAt || 0);\n if (editedAt <= 0) {\n return false;\n }\n const previous = previousByKey.get(messageStableKey(message));\n return previous && editedAt > Number(previous.editedAt || 0);\n });\n}\nlet notificationAudioContext = null;\nfunction playNotificationSound() {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (!AudioContext) {\n return;\n }\n notificationAudioContext = notificationAudioContext || new AudioContext();\n if (notificationAudioContext.state === 'suspended') {\n notificationAudioContext.resume().catch(() => {});\n }\n const oscillator = notificationAudioContext.createOscillator();\n const gain = notificationAudioContext.createGain();\n const startAt = notificationAudioContext.currentTime;\n oscillator.type = 'sine';\n oscillator.frequency.setValueAtTime(880, startAt);\n oscillator.frequency.setValueAtTime(660, startAt + 0.1);\n gain.gain.setValueAtTime(0.0001, startAt);\n gain.gain.exponentialRampToValueAtTime(0.12, startAt + 0.02);\n gain.gain.exponentialRampToValueAtTime(0.0001, startAt + 0.22);\n oscillator.connect(gain);\n gain.connect(notificationAudioContext.destination);\n oscillator.start(startAt);\n oscillator.stop(startAt + 0.24);\n } catch (error) {\n // Notification sound is best-effort; browsers may block audio until user interaction.\n }\n}\nconst useConversationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_19__.defineStore)('conversations', {\n state: () => ({\n activeId: '',\n conversations: [],\n messagesByConversation: {},\n visibleMessagesByConversation: {},\n eventsBound: false,\n usingDemoData: false,\n loading: false,\n syncTimer: null,\n conversationSyncTimer: null,\n readPresenceEventsBound: false,\n syncInFlight: false,\n pendingReadReceiptConversationId: '',\n conversationSyncInFlight: false,\n syncAfterSendTimer: null,\n optimisticMessagesByConversation: {},\n quotedMessage: null,\n forwardingMessages: [],\n editingMessage: null,\n editingText: '',\n editingMode: '',\n messageDetailOpen: false,\n messageDetailLoading: false,\n messageDetailError: '',\n messageDetail: null,\n attentionMessageId: '',\n attentionMessageTimer: null,\n selectionMode: false,\n selectedMessageIds: [],\n favoriteMessages: [],\n activeFavoriteKey: '',\n actionNotice: '',\n actionError: '',\n realtimeSyncTimer: null\n }),\n getters: {\n activeConversation(state) {\n return state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;\n },\n activeMessages(state) {\n return state.visibleMessagesByConversation[state.activeId] || [];\n },\n totalUnread(state) {\n return state.conversations.reduce((sum, item) => sum + Number(item.unread || 0), 0);\n },\n canSendActiveConversation(state) {\n const conversation = state.conversations.find(item => item.id === state.activeId) || state.conversations[0] || null;\n if (!conversation) {\n return false;\n }\n if (conversation.type !== 'channel') {\n return true;\n }\n return ['owner', 'admin'].includes(conversation.role || conversation.raw?.role || '');\n },\n favoriteMessageIds(state) {\n return state.favoriteMessages.map(message => message.key);\n },\n activeFavorite(state) {\n return state.favoriteMessages.find(message => message.key === state.activeFavoriteKey) || state.favoriteMessages[0] || null;\n },\n selectedMessages(state) {\n const selectedIds = new Set(state.selectedMessageIds);\n return (state.visibleMessagesByConversation[state.activeId] || []).filter(message => selectedIds.has(messageStableKey(message)));\n }\n },\n actions: {\n bootstrapDemoData() {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n this.bindImEvents();\n this.usingDemoData = false;\n if (!session.userId) {\n this.clearUserState();\n return;\n }\n this.loadScopedLocalState();\n this.startMessageSync();\n _services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__.realtimeNotifications.start(session.userId, payload => this.handleRealtimeNotification(payload));\n },\n loadScopedLocalState() {\n this.conversations = [];\n this.favoriteMessages = readFavoriteMessages();\n this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';\n this.activeId = '';\n this.messagesByConversation = {};\n this.visibleMessagesByConversation = {};\n this.optimisticMessagesByConversation = {};\n this.quotedMessage = null;\n this.forwardingMessages = [];\n this.editingMessage = null;\n this.editingText = '';\n this.editingMode = '';\n this.messageDetailOpen = false;\n this.messageDetailLoading = false;\n this.messageDetailError = '';\n this.messageDetail = null;\n this.selectionMode = false;\n this.selectedMessageIds = [];\n },\n clearUserState() {\n window.clearInterval(this.syncTimer);\n window.clearInterval(this.conversationSyncTimer);\n window.clearTimeout(this.syncAfterSendTimer);\n window.clearTimeout(this.attentionMessageTimer);\n window.clearTimeout(this.realtimeSyncTimer);\n _services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__.realtimeNotifications.stop();\n this.syncTimer = null;\n this.conversationSyncTimer = null;\n this.syncAfterSendTimer = null;\n this.attentionMessageTimer = null;\n this.realtimeSyncTimer = null;\n this.syncInFlight = false;\n this.conversationSyncInFlight = false;\n this.pendingReadReceiptConversationId = '';\n this.activeId = '';\n this.conversations = [];\n this.messagesByConversation = {};\n this.visibleMessagesByConversation = {};\n this.optimisticMessagesByConversation = {};\n this.quotedMessage = null;\n this.forwardingMessages = [];\n this.editingMessage = null;\n this.editingText = '';\n this.editingMode = '';\n this.messageDetailOpen = false;\n this.messageDetailLoading = false;\n this.messageDetailError = '';\n this.messageDetail = null;\n this.attentionMessageId = '';\n this.selectionMode = false;\n this.selectedMessageIds = [];\n this.favoriteMessages = [];\n this.activeFavoriteKey = '';\n this.actionNotice = '';\n this.actionError = '';\n },\n bindImEvents() {\n if (this.eventsBound) {\n return;\n }\n this.eventsBound = true;\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.on('messageSent', message => {\n this.appendMessage(message.conversationId, message);\n });\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.on('messageReceived', message => {\n this.appendMessage(message.conversationId, message);\n if (message.conversationId === this.activeId) {\n this.scheduleActiveMessagesSync({\n allowReadReceipt: true\n }, 500);\n }\n });\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.on('messageStatusChanged', message => {\n this.replaceMessage(message.conversationId, message);\n });\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.on('conversationsChanged', remoteConversations => {\n this.usingDemoData = false;\n this.applyRemoteConversations(remoteConversations);\n });\n },\n setActiveConversation(id) {\n this.activeId = id;\n const conversation = this.conversations.find(item => item.id === id);\n if (conversation) {\n conversation.unread = 0;\n }\n this.loadActiveMessages({\n allowReadReceipt: true,\n userAction: true\n });\n },\n sendText(text) {\n const conversation = this.activeConversation;\n if (!conversation || !text.trim()) {\n return;\n }\n let value = text.trim();\n if (this.quotedMessage) {\n value = `引用:${quotePrefix(this.quotedMessage)}\\n${value}`;\n this.quotedMessage = null;\n }\n const message = {\n id: randomId(),\n conversationId: conversation.id,\n from: 'me',\n direction: 'out',\n type: 'text',\n text: value,\n status: 'sending',\n deliveryStatus: 'sending',\n timestamp: Date.now(),\n displayTimestamp: Date.now()\n };\n this.appendVisibleMessage(conversation.id, message);\n this.appendMessage(conversation.id, message);\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.sendTextMessage(conversation, value, message);\n conversation.subtitle = value;\n conversation.updatedAt = Date.now();\n writeLocalConversations(this.conversations);\n window.clearTimeout(this.syncAfterSendTimer);\n this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 250);\n },\n sendAttachment({\n type,\n file,\n text = ''\n }) {\n const conversation = this.activeConversation;\n if (!conversation || !file || !['image', 'file'].includes(type)) {\n return;\n }\n let value = text.trim();\n if (this.quotedMessage) {\n value = `引用:${quotePrefix(this.quotedMessage)}\\n${value}`.trim();\n this.quotedMessage = null;\n }\n const now = Date.now();\n const message = {\n id: randomId(),\n conversationId: conversation.id,\n from: 'me',\n senderRole: conversation.role || conversation.raw?.role || '',\n direction: 'out',\n type,\n text: value,\n attachment: {\n type,\n name: file.name || (type === 'image' ? '图片' : '文件'),\n mime: file.type || '',\n size: file.size || 0,\n url: type === 'image' ? URL.createObjectURL(file) : ''\n },\n status: 'sending',\n deliveryStatus: 'sending',\n timestamp: now,\n displayTimestamp: now\n };\n this.appendVisibleMessage(conversation.id, message);\n this.appendMessage(conversation.id, message);\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.sendAttachmentMessage(conversation, {\n type,\n file,\n text: value\n }, message);\n conversation.subtitle = messagePreviewText(message);\n conversation.updatedAt = now;\n writeLocalConversations(this.conversations);\n window.clearTimeout(this.syncAfterSendTimer);\n this.syncAfterSendTimer = window.setTimeout(() => this.syncActiveMessages(), 350);\n },\n async sendTextToConversation(conversation, text) {\n if (!conversation || !text.trim()) {\n return null;\n }\n const value = text.trim();\n const message = {\n id: randomId(),\n conversationId: conversation.id,\n from: 'me',\n direction: 'out',\n type: 'text',\n text: value,\n status: 'sending',\n deliveryStatus: 'sending',\n timestamp: Date.now(),\n displayTimestamp: Date.now()\n };\n this.appendMessage(conversation.id, message);\n const sentMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.sendTextMessage(conversation, value, message);\n this.replaceMessage(conversation.id, sentMessage);\n return sentMessage;\n },\n upsertConversation(conversation) {\n const index = this.conversations.findIndex(item => item.id === conversation.id);\n if (index >= 0) {\n this.conversations.splice(index, 1, {\n ...this.conversations[index],\n ...conversation\n });\n } else {\n this.conversations.unshift(conversation);\n }\n this.usingDemoData = false;\n writeLocalConversations(this.conversations);\n },\n removeConversation(conversationId) {\n this.conversations = this.conversations.filter(conversation => conversation.id !== conversationId);\n const {\n [conversationId]: removedMessages,\n ...messagesByConversation\n } = this.messagesByConversation;\n const {\n [conversationId]: removedVisibleMessages,\n ...visibleMessagesByConversation\n } = this.visibleMessagesByConversation;\n const {\n [conversationId]: removedOptimisticMessages,\n ...optimisticMessagesByConversation\n } = this.optimisticMessagesByConversation;\n void removedMessages;\n void removedVisibleMessages;\n void removedOptimisticMessages;\n this.messagesByConversation = messagesByConversation;\n this.visibleMessagesByConversation = visibleMessagesByConversation;\n this.optimisticMessagesByConversation = optimisticMessagesByConversation;\n if (this.activeId === conversationId) {\n this.activeId = this.conversations[0]?.id || '';\n }\n writeLocalConversations(this.conversations);\n if (this.activeId) {\n this.loadActiveMessages();\n }\n },\n applyRemoteConversations(remoteConversations) {\n const remote = Array.isArray(remoteConversations) ? remoteConversations : [];\n if (!remote.length && this.conversations.length) {\n return;\n }\n const merged = new Map();\n this.conversations.forEach(conversation => {\n merged.set(conversation.id, conversation);\n });\n remote.forEach(conversation => {\n const unread = conversation.id === this.activeId && canMarkReadNow() ? 0 : Number(conversation.unread || 0);\n merged.set(conversation.id, {\n ...(merged.get(conversation.id) || {}),\n ...conversation,\n unread\n });\n });\n this.conversations = Array.from(merged.values()).sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0)).slice(0, 100);\n if (!this.conversations.length) {\n this.activeId = '';\n this.messagesByConversation = {};\n this.visibleMessagesByConversation = {};\n this.optimisticMessagesByConversation = {};\n writeLocalConversations(this.conversations);\n return;\n }\n if (!this.conversations.find(item => item.id === this.activeId)) {\n this.activeId = this.conversations[0].id;\n }\n writeLocalConversations(this.conversations);\n this.loadActiveMessages();\n },\n appendMessage(conversationId, message) {\n if (!this.messagesByConversation[conversationId]) {\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: []\n };\n }\n if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent')) {\n this.keepOptimisticMessage(conversationId, message);\n }\n if (!hasExactMessage(this.messagesByConversation[conversationId], message)) {\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: [...this.messagesByConversation[conversationId], message]\n };\n }\n this.updateConversationFromMessage(conversationId, message);\n this.syncVisibleMessages(conversationId);\n writeLocalConversations(this.conversations);\n },\n removeMessages(conversationId, messages) {\n const ids = new Set(messages.flatMap(message => [message.id, message.messageUid].filter(Boolean).map(String)));\n const filterMessages = list => (list || []).filter(message => {\n return ![message.id, message.messageUid].filter(Boolean).some(id => ids.has(String(id)));\n });\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: filterMessages(this.messagesByConversation[conversationId])\n };\n this.visibleMessagesByConversation = {\n ...this.visibleMessagesByConversation,\n [conversationId]: filterMessages(this.visibleMessagesByConversation[conversationId])\n };\n this.optimisticMessagesByConversation = {\n ...this.optimisticMessagesByConversation,\n [conversationId]: filterMessages(this.optimisticMessagesByConversation[conversationId])\n };\n this.selectedMessageIds = this.selectedMessageIds.filter(id => !ids.has(String(id)));\n },\n replaceLocalMessage(conversationId, targetMessage, nextMessage) {\n const keys = new Set([targetMessage.id, targetMessage.messageUid].filter(Boolean).map(String));\n const replaceInList = list => (list || []).map(message => {\n const matched = [message.id, message.messageUid].filter(Boolean).some(id => keys.has(String(id)));\n return matched ? {\n ...message,\n ...nextMessage\n } : message;\n });\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: replaceInList(this.messagesByConversation[conversationId])\n };\n this.visibleMessagesByConversation = {\n ...this.visibleMessagesByConversation,\n [conversationId]: replaceInList(this.visibleMessagesByConversation[conversationId])\n };\n },\n updateConversationFromMessage(conversationId, message) {\n const conversation = this.conversations.find(item => item.id === conversationId);\n if (!conversation) {\n return;\n }\n conversation.subtitle = message.text || conversation.subtitle || '';\n conversation.updatedAt = messageActivityTimestamp(message) || Date.now();\n if (message.direction === 'in') {\n conversation.unread = conversationId === this.activeId ? 0 : Number(conversation.unread || 0) + 1;\n }\n this.conversations = [...this.conversations].sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));\n },\n appendVisibleMessage(conversationId, message) {\n const messages = this.visibleMessagesByConversation[conversationId] || [];\n this.visibleMessagesByConversation = {\n ...this.visibleMessagesByConversation,\n [conversationId]: [...messages.filter(item => item.id !== message.id), message].sort((a, b) => Number(a.displayTimestamp || a.timestamp || 0) - Number(b.displayTimestamp || b.timestamp || 0))\n };\n },\n replaceMessage(conversationId, message) {\n if (!this.messagesByConversation[conversationId]) {\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: []\n };\n }\n if (message.direction === 'out' && (message.status === 'sending' || message.status === 'sent' || message.status === 'failed')) {\n this.keepOptimisticMessage(conversationId, message);\n }\n const index = this.messagesByConversation[conversationId].findIndex(item => item.id === message.id);\n if (index >= 0) {\n const messages = [...this.messagesByConversation[conversationId]];\n messages.splice(index, 1, message);\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: messages\n };\n } else {\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversationId]: [...this.messagesByConversation[conversationId], message]\n };\n }\n this.syncVisibleMessages(conversationId);\n },\n syncVisibleMessages(conversationId) {\n this.visibleMessagesByConversation = {\n ...this.visibleMessagesByConversation,\n [conversationId]: mergeVisibleMessages(this.optimisticMessagesByConversation[conversationId] || [], this.messagesByConversation[conversationId] || [])\n };\n },\n keepOptimisticMessage(conversationId, message) {\n if (!this.optimisticMessagesByConversation[conversationId]) {\n this.optimisticMessagesByConversation = {\n ...this.optimisticMessagesByConversation,\n [conversationId]: []\n };\n }\n const messages = this.optimisticMessagesByConversation[conversationId];\n const index = messages.findIndex(item => item.id === message.id);\n let nextMessages;\n if (index >= 0) {\n nextMessages = [...messages];\n nextMessages.splice(index, 1, message);\n } else {\n nextMessages = [...messages, message];\n }\n this.optimisticMessagesByConversation = {\n ...this.optimisticMessagesByConversation,\n [conversationId]: nextMessages\n };\n },\n pruneOptimisticMessages(conversationId, syncedMessages) {\n const messages = this.optimisticMessagesByConversation[conversationId] || [];\n if (!messages.length) {\n return;\n }\n this.optimisticMessagesByConversation = {\n ...this.optimisticMessagesByConversation,\n [conversationId]: messages.filter(message => {\n const remoteMatched = syncedMessages.some(syncedMessage => {\n return syncedMessage.id !== message.id && isSameMessage(syncedMessage, message);\n });\n if (remoteMatched && message.status !== 'failed') {\n return false;\n }\n return Date.now() - Number(message.displayTimestamp || message.timestamp || 0) < 30000 || message.status === 'failed';\n })\n };\n },\n loadActiveMessages(options = {}) {\n const syncOptions = typeof options === 'boolean' ? {\n allowReadReceipt: options\n } : options;\n const conversation = this.activeConversation;\n if (!conversation) {\n return;\n }\n this.loading = true;\n const messages = _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.getMessages(conversation, 30);\n this.pruneOptimisticMessages(conversation.id, messages);\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [conversation.id]: mergeVisibleMessages(this.messagesByConversation[conversation.id] || [], messages)\n };\n this.syncVisibleMessages(conversation.id);\n this.loading = false;\n this.syncActiveMessages(syncOptions);\n },\n async syncActiveMessages(options = {}) {\n const conversation = this.activeConversation;\n if (!conversation) {\n return;\n }\n const wantsReadReceipt = Boolean(options.allowReadReceipt);\n const explicitReadReceipt = wantsReadReceipt && canMarkReadNow({\n userAction: Boolean(options.userAction)\n });\n const pollingReadReceipt = canMarkReadNow();\n const markRead = explicitReadReceipt || pollingReadReceipt;\n if (this.syncInFlight) {\n if (wantsReadReceipt) {\n this.pendingReadReceiptConversationId = conversation.id;\n }\n return;\n }\n this.syncInFlight = true;\n const syncedConversationId = conversation.id;\n const previousMessages = this.messagesByConversation[syncedConversationId] || [];\n try {\n const messages = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.fetchRemoteMessages(conversation, 50, {\n markRead,\n includeConversations: Boolean(options.includeConversations)\n });\n const editedIncomingMessages = incomingEditedMessages(previousMessages, messages);\n this.pruneOptimisticMessages(syncedConversationId, messages);\n this.messagesByConversation = {\n ...this.messagesByConversation,\n [syncedConversationId]: mergeVisibleMessages(this.messagesByConversation[syncedConversationId] || [], messages)\n };\n this.syncVisibleMessages(syncedConversationId);\n if (editedIncomingMessages.length && syncedConversationId === this.activeId) {\n this.focusMessage(editedIncomingMessages.sort((a, b) => messageActivityTimestamp(b) - messageActivityTimestamp(a))[0]);\n playNotificationSound();\n }\n const latest = messages.reduce((latestMessage, message) => {\n if (!latestMessage || messageActivityTimestamp(message) > messageActivityTimestamp(latestMessage)) {\n return message;\n }\n return latestMessage;\n }, null);\n if (latest) {\n conversation.subtitle = messagePreviewText(latest);\n conversation.updatedAt = messageActivityTimestamp(latest);\n writeLocalConversations(this.conversations);\n }\n } catch (error) {\n // Keep the local view usable if a polling request misses.\n } finally {\n this.syncInFlight = false;\n if (this.pendingReadReceiptConversationId === this.activeId && canMarkReadNow()) {\n this.pendingReadReceiptConversationId = '';\n window.setTimeout(() => this.syncActiveMessages({\n allowReadReceipt: true\n }), 0);\n }\n }\n },\n scheduleActiveMessagesSync(options = {}, delay = 500) {\n if (!this.activeId || typeof document !== 'undefined' && document.visibilityState !== 'visible') {\n return;\n }\n window.clearTimeout(this.syncAfterSendTimer);\n this.syncAfterSendTimer = window.setTimeout(() => {\n this.syncAfterSendTimer = null;\n this.syncActiveMessages(options);\n }, Math.max(0, Number(delay) || 0));\n },\n startMessageSync() {\n this.bindReadPresenceEvents();\n if (!this.syncTimer) {\n this.syncTimer = window.setInterval(() => {\n if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__.realtimeNotifications.isConnected()) {\n this.syncActiveMessages();\n }\n }, Math.max(250, _config__WEBPACK_IMPORTED_MODULE_21__.appConfig.syncIntervalMs));\n }\n if (!this.conversationSyncTimer) {\n this.conversationSyncTimer = window.setInterval(() => {\n if (document.visibilityState === 'visible' && !_services_realtimeNotifications__WEBPACK_IMPORTED_MODULE_23__.realtimeNotifications.isConnected()) {\n this.refreshRemoteConversations();\n }\n }, Math.max(5000, _config__WEBPACK_IMPORTED_MODULE_21__.appConfig.syncIntervalMs * 2));\n this.refreshRemoteConversations();\n }\n },\n handleRealtimeNotification() {\n window.clearTimeout(this.realtimeSyncTimer);\n this.realtimeSyncTimer = window.setTimeout(() => {\n this.refreshRemoteConversations();\n this.scheduleActiveMessagesSync({\n allowReadReceipt: canMarkReadNow(),\n includeConversations: true\n }, 300);\n }, 300);\n },\n bindReadPresenceEvents() {\n if (this.readPresenceEventsBound || typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n this.readPresenceEventsBound = true;\n const syncWhenReadable = () => {\n if (canMarkReadNow()) {\n this.refreshRemoteConversations();\n this.scheduleActiveMessagesSync({\n allowReadReceipt: true\n }, 200);\n }\n };\n window.addEventListener('focus', syncWhenReadable);\n document.addEventListener('visibilitychange', syncWhenReadable);\n },\n async refreshRemoteConversations() {\n this.bindImEvents();\n this.usingDemoData = false;\n if (this.conversationSyncInFlight) {\n return;\n }\n this.conversationSyncInFlight = true;\n try {\n const remoteConversations = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.fetchRemoteConversations(50);\n this.applyRemoteConversations(remoteConversations);\n } catch (error) {\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.refreshConversationList();\n } finally {\n this.conversationSyncInFlight = false;\n }\n },\n setActionNotice(message) {\n this.actionNotice = message;\n this.actionError = '';\n },\n setActionError(message) {\n this.actionError = message;\n this.actionNotice = '';\n },\n focusMessage(message) {\n const key = messageStableKey(message);\n if (!key) {\n return;\n }\n this.attentionMessageId = key;\n window.clearTimeout(this.attentionMessageTimer);\n this.attentionMessageTimer = window.setTimeout(() => {\n if (this.attentionMessageId === key) {\n this.attentionMessageId = '';\n }\n }, 2800);\n },\n async handleMessageAction({\n action,\n message\n }) {\n if (!message) {\n return;\n }\n if (action === 'copy') {\n await this.copyMessages([message]);\n } else if (action === 'edit') {\n this.startEditMessage(message);\n } else if (action === 'delete') {\n this.deleteMessages([message]);\n } else if (action === 'forward') {\n this.startForward([message]);\n } else if (action === 'favorite') {\n this.toggleFavorite(message);\n } else if (action === 'detail') {\n await this.openMessageDetail(message);\n } else if (action === 'quote') {\n this.quoteMessage(message);\n } else if (action === 'select') {\n this.enterSelectionMode(message);\n } else if (action === 'recall') {\n await this.recallMessage(message);\n }\n },\n async openMessageDetail(message) {\n const conversation = this.activeConversation;\n if (!conversation || !message) {\n return;\n }\n const key = messageStableKey(message);\n this.messageDetailOpen = true;\n this.messageDetailLoading = true;\n this.messageDetailError = '';\n this.messageDetail = {\n messageUid: key,\n conversationType: conversation.type || conversation.raw?.type || 'single',\n sentAt: Number(message.displayTimestamp || message.timestamp || 0),\n editedAt: Number(message.editedAt || 0),\n recalled: isRecalledMessage(message),\n localOnly: true,\n sender: {\n uid: message.from || '',\n name: message.senderName || message.from || ''\n }\n };\n try {\n if (!/^\\d+$/.test(key)) {\n this.messageDetailError = '本地临时消息暂无送达/已读详情';\n return;\n }\n const detail = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.getMessageDetail(conversation, message);\n this.messageDetail = detail || this.messageDetail;\n } catch (error) {\n this.messageDetailError = error.message || '消息详情加载失败';\n } finally {\n this.messageDetailLoading = false;\n }\n },\n closeMessageDetail() {\n this.messageDetailOpen = false;\n this.messageDetailLoading = false;\n this.messageDetailError = '';\n this.messageDetail = null;\n },\n async copyMessages(messages) {\n const text = messages.map(message => message.text || '').join('\\n');\n if (!text.trim()) {\n return;\n }\n try {\n await writeClipboard(text);\n this.setActionNotice(messages.length > 1 ? '已复制所选消息' : '已复制');\n } catch (error) {\n this.setActionError('复制失败');\n }\n },\n deleteMessages(messages) {\n const conversation = this.activeConversation;\n if (!conversation || !messages.length) {\n return;\n }\n _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.hideMessages(conversation, messages);\n this.removeMessages(conversation.id, messages);\n if (!this.selectedMessageIds.length) {\n this.selectionMode = false;\n }\n this.setActionNotice(messages.length > 1 ? '已删除所选消息' : '已删除');\n },\n toggleFavorite(message) {\n const key = messageStableKey(message);\n if (!key) {\n return;\n }\n const index = this.favoriteMessages.findIndex(item => item.key === key);\n if (index >= 0) {\n this.favoriteMessages.splice(index, 1);\n if (this.activeFavoriteKey === key) {\n this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';\n }\n this.setActionNotice('已取消收藏');\n } else {\n const conversation = this.conversations.find(item => item.id === message.conversationId) || {};\n this.favoriteMessages.unshift({\n key,\n id: message.id,\n messageUid: message.messageUid,\n conversationId: message.conversationId,\n conversationTitle: conversation.title || message.conversationTitle || '',\n type: message.type || 'text',\n text: message.text || '',\n preview: messagePreviewText(message),\n senderName: message.senderName || message.from || '',\n timestamp: Number(message.displayTimestamp || message.timestamp || Date.now()),\n editedAt: Number(message.editedAt || 0),\n recalled: isRecalledMessage(message),\n recallStatus: message.recallStatus || (isRecalledMessage(message) ? '已撤回' : ''),\n attachment: message.attachment ? {\n ...message.attachment\n } : null\n });\n this.activeFavoriteKey = key;\n this.setActionNotice('已收藏');\n }\n this.favoriteMessages = this.favoriteMessages.slice(0, 200);\n writeFavoriteMessages(this.favoriteMessages);\n },\n setActiveFavorite(key) {\n this.activeFavoriteKey = String(key || '');\n },\n removeFavorite(key) {\n const value = String(key || '');\n if (!value) {\n return;\n }\n this.favoriteMessages = this.favoriteMessages.filter(message => message.key !== value);\n if (this.activeFavoriteKey === value) {\n this.activeFavoriteKey = this.favoriteMessages[0]?.key || '';\n }\n writeFavoriteMessages(this.favoriteMessages);\n },\n quoteMessage(message) {\n this.quotedMessage = {\n ...message,\n quoteText: quotePrefix(message)\n };\n this.setActionNotice('已引用,输入后发送');\n },\n cancelQuote() {\n this.quotedMessage = null;\n },\n enterSelectionMode(message = null) {\n this.selectionMode = true;\n if (message) {\n const key = messageStableKey(message);\n this.selectedMessageIds = key ? [key] : [];\n }\n },\n toggleSelectedMessage(message) {\n const key = messageStableKey(message);\n if (!key) {\n return;\n }\n const selected = new Set(this.selectedMessageIds);\n if (selected.has(key)) {\n selected.delete(key);\n } else {\n selected.add(key);\n }\n this.selectedMessageIds = Array.from(selected);\n this.selectionMode = this.selectedMessageIds.length > 0;\n },\n clearSelection() {\n this.selectionMode = false;\n this.selectedMessageIds = [];\n },\n copySelectedMessages() {\n return this.copyMessages(this.selectedMessages);\n },\n deleteSelectedMessages() {\n this.deleteMessages(this.selectedMessages);\n },\n startForward(messages) {\n this.forwardingMessages = messages.filter(message => message?.text);\n if (!this.forwardingMessages.length) {\n this.setActionError('没有可转发的消息');\n }\n },\n startForwardSelectedMessages() {\n this.startForward(this.selectedMessages);\n },\n cancelForward() {\n this.forwardingMessages = [];\n },\n startEditMessage(message) {\n const isResend = isRecalledMessage(message);\n if (!isResend && !message?.text) {\n this.setActionError('没有可编辑的文字内容');\n return;\n }\n this.editingMessage = message;\n this.editingText = message.text || '';\n this.editingMode = isResend ? 'resend' : 'edit';\n },\n cancelEditMessage() {\n this.editingMessage = null;\n this.editingText = '';\n this.editingMode = '';\n },\n async completeEditMessage() {\n const conversation = this.activeConversation;\n const message = this.editingMessage;\n const text = this.editingText.trim();\n const isResend = this.editingMode === 'resend' || isRecalledMessage(message);\n if (!conversation || !message) {\n this.cancelEditMessage();\n return;\n }\n if (!text) {\n this.setActionError('编辑内容不能为空');\n return;\n }\n if (!isResend && text === String(message.text || '').trim()) {\n this.cancelEditMessage();\n return;\n }\n try {\n if (isResend) {\n await this.sendTextToConversation(conversation, text);\n this.cancelEditMessage();\n this.setActionNotice('已重新发送');\n return;\n }\n const editedMessage = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.editMessage(conversation, message, text);\n this.replaceLocalMessage(conversation.id, message, editedMessage);\n if (messageActivityTimestamp(editedMessage) >= Number(conversation.updatedAt || 0)) {\n conversation.subtitle = editedMessage.text;\n conversation.updatedAt = messageActivityTimestamp(editedMessage);\n writeLocalConversations(this.conversations);\n }\n this.cancelEditMessage();\n this.setActionNotice('已编辑');\n } catch (error) {\n this.setActionError(error.message || '编辑失败');\n }\n },\n async completeForward(targetConversationId) {\n const target = this.conversations.find(conversation => conversation.id === targetConversationId);\n if (!target || !this.forwardingMessages.length) {\n return;\n }\n const text = this.forwardingMessages.map(message => `转发:${message.text || ''}`).join('\\n\\n');\n try {\n await this.sendTextToConversation(target, text);\n this.forwardingMessages = [];\n this.clearSelection();\n this.setActionNotice('已转发');\n } catch (error) {\n this.setActionError(error.message || '转发失败');\n }\n },\n async recallMessage(message) {\n const conversation = this.activeConversation;\n if (!conversation) {\n return;\n }\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.recallMessage(conversation, message);\n if (message.direction !== 'out') {\n this.removeMessages(conversation.id, [message]);\n this.setActionNotice('已撤回');\n this.syncActiveMessages();\n return;\n }\n this.replaceLocalMessage(conversation.id, message, {\n status: 'recalled',\n deliveryStatus: '',\n recalled: true,\n recallStatus: '已撤回'\n });\n this.setActionNotice('已撤回');\n } catch (error) {\n this.setActionError(error.message || '撤回失败');\n }\n },\n async createGroup(options = {}) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n if (!session.userId) {\n this.setActionError('请先登录');\n return false;\n }\n try {\n const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.createGroup(session.userId, options);\n this.upsertConversation(conversation);\n this.setActiveConversation(conversation.id);\n this.setActionNotice(options.channel ? '公告群已创建' : '群组已创建');\n this.refreshRemoteConversations();\n return true;\n } catch (error) {\n this.setActionError(error.message || (options.channel ? '创建公告群失败' : '创建群组失败'));\n return false;\n }\n },\n async joinGroup(groupKey) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n if (!session.userId) {\n this.setActionError('请先登录');\n return false;\n }\n try {\n const conversation = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.joinGroup(session.userId, groupKey);\n this.upsertConversation(conversation);\n this.setActiveConversation(conversation.id);\n this.setActionNotice('已加入群组');\n this.refreshRemoteConversations();\n return true;\n } catch (error) {\n this.setActionError(error.message || '加入群组失败');\n return false;\n }\n },\n async broadcastMessage(targetIds, text) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n if (!session.userId) {\n this.setActionError('请先登录');\n return false;\n }\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.broadcastMessage(session.userId, targetIds, text);\n const successCount = Number(result.successCount || 0);\n const failedCount = Number(result.failedCount || 0);\n this.setActionNotice(failedCount > 0 ? `已群发 ${successCount} 条,失败 ${failedCount} 条` : `已群发 ${successCount} 条`);\n this.refreshRemoteConversations();\n return true;\n } catch (error) {\n this.setActionError(error.message || '群发失败');\n return false;\n }\n },\n async leaveGroup(conversation) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n if (!session.userId || !conversation?.target) {\n this.setActionError('缺少群组信息');\n return false;\n }\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.leaveGroup(session.userId, conversation.target);\n this.removeConversation(conversation.id);\n this.setActionNotice('已退出群组');\n this.refreshRemoteConversations();\n return true;\n } catch (error) {\n this.setActionError(error.message || '退出群组失败');\n return false;\n }\n },\n async dismissGroup(conversation) {\n const session = (0,_stores_session__WEBPACK_IMPORTED_MODULE_22__.useSessionStore)();\n if (!session.userId || !conversation?.target) {\n this.setActionError('缺少群组信息');\n return false;\n }\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_20__.imClient.dismissGroup(session.userId, conversation.target);\n this.removeConversation(conversation.id);\n this.setActionNotice('群组已解散');\n this.refreshRemoteConversations();\n return true;\n } catch (error) {\n this.setActionError(error.message || '解散群组失败');\n return false;\n }\n }\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/stores/conversations.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/stores/navigation.js":
|
||
/*!**********************************!*\
|
||
!*** ./src/stores/navigation.js ***!
|
||
\**********************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useNavigationStore: function() { return /* binding */ useNavigationStore; }\n/* harmony export */ });\n/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pinia */ \"./node_modules/pinia/dist/pinia.mjs\");\n\nconst useNavigationStore = (0,pinia__WEBPACK_IMPORTED_MODULE_0__.defineStore)('navigation', {\n state: () => ({\n section: 'messages'\n }),\n actions: {\n showMessages() {\n this.section = 'messages';\n },\n showContacts() {\n this.section = 'contacts';\n },\n showFavorites() {\n this.section = 'favorites';\n }\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/stores/navigation.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/stores/session.js":
|
||
/*!*******************************!*\
|
||
!*** ./src/stores/session.js ***!
|
||
\*******************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useSessionStore: function() { return /* binding */ useSessionStore; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_includes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.includes.js */ \"./node_modules/core-js/modules/es.array.includes.js\");\n/* 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__);\n/* harmony import */ var pinia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pinia */ \"./node_modules/pinia/dist/pinia.mjs\");\n/* harmony import */ var _services_imClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/services/imClient */ \"./src/services/imClient.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/config */ \"./src/config.js\");\n\n\n\n\nconst STORAGE_KEY = 'qmt-web-im-session';\nfunction normalizeStoredPortrait(portrait) {\n return portrait || '';\n}\nfunction nextProfilePortrait(profilePortrait, currentPortrait) {\n return normalizeStoredPortrait(profilePortrait) || normalizeStoredPortrait(currentPortrait);\n}\nfunction inferAccountType(account) {\n return String(account || '').includes('@') ? 2 : 1;\n}\nconst useSessionStore = (0,pinia__WEBPACK_IMPORTED_MODULE_1__.defineStore)('session', {\n state: () => ({\n isAuthenticated: false,\n connecting: false,\n connected: false,\n connectionStatusText: '未连接',\n userId: '',\n token: '',\n displayName: '',\n portrait: '',\n error: '',\n sdkVersion: '',\n eventsBound: false\n }),\n actions: {\n restore() {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n return;\n }\n try {\n const session = JSON.parse(raw);\n if (session.appServer !== _config__WEBPACK_IMPORTED_MODULE_3__.appConfig.appServer) {\n localStorage.removeItem(STORAGE_KEY);\n return;\n }\n if (session.userId && session.token) {\n if (!session.clientId) {\n localStorage.removeItem(STORAGE_KEY);\n return;\n }\n this.userId = session.userId;\n this.token = session.token;\n this.displayName = session.displayName || session.userId;\n this.portrait = normalizeStoredPortrait(session.portrait);\n this.isAuthenticated = true;\n _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.restoreClientId(session.clientId);\n this.connect();\n this.refreshProfile();\n }\n } catch (error) {\n localStorage.removeItem(STORAGE_KEY);\n }\n },\n async loginWithPassword(account, password, type = inferAccountType(account)) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.loginWithPassword(account, password, type);\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '登录失败';\n } finally {\n this.connecting = false;\n }\n },\n async loginWithCode(account, code) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.loginWithCode(account, code);\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '登录失败';\n } finally {\n this.connecting = false;\n }\n },\n async completePcSessionLogin(result) {\n this.error = '';\n this.connecting = true;\n try {\n this.applyLoginResult(result);\n await this.connect();\n } catch (error) {\n this.error = error.message || '扫码登录失败';\n } finally {\n this.connecting = false;\n }\n },\n async register(payload) {\n this.error = '';\n this.connecting = true;\n try {\n const result = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.register(payload);\n this.applyLoginResult(result);\n await this.connect();\n return result;\n } catch (error) {\n this.error = error.message || '注册失败';\n return null;\n } finally {\n this.connecting = false;\n }\n },\n applyLoginResult(result) {\n this.userId = result.userId || result.uid || result.id || '';\n this.token = result.token || result.imToken || '';\n this.displayName = result.displayName || result.userName || result.name || this.userId;\n this.portrait = normalizeStoredPortrait(result.portrait);\n this.isAuthenticated = Boolean(this.userId && this.token);\n this.persistSession();\n },\n persistSession() {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n userId: this.userId,\n token: this.token,\n displayName: this.displayName,\n portrait: this.portrait,\n clientId: _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.getClientId(),\n appServer: _config__WEBPACK_IMPORTED_MODULE_3__.appConfig.appServer\n }));\n },\n applyProfile(profile) {\n if (!profile) {\n return;\n }\n this.userId = profile.userId || profile.uid || this.userId;\n this.displayName = profile.displayName || profile.name || this.displayName || this.userId;\n this.portrait = nextProfilePortrait(profile.portrait, this.portrait);\n this.persistSession();\n },\n async refreshProfile() {\n if (!this.userId) {\n return null;\n }\n try {\n const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.getProfile(this.userId);\n this.applyProfile(profile);\n return profile;\n } catch (error) {\n return null;\n }\n },\n async saveProfile({\n displayName,\n portraitFile\n }) {\n if (!this.userId) {\n throw new Error('请先登录');\n }\n const profile = await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.updateProfile(this.userId, {\n displayName,\n portraitFile\n });\n this.applyProfile(profile);\n return profile;\n },\n async changePassword({\n oldPassword,\n newPassword\n }) {\n if (!this.userId) {\n throw new Error('请先登录');\n }\n await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.changePassword({\n oldPassword,\n newPassword\n });\n await this.logout();\n return true;\n },\n async resetPasswordWithCode({\n mobile,\n resetCode,\n newPassword\n }) {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.resetPasswordWithCode({\n mobile,\n resetCode,\n newPassword\n });\n return true;\n },\n async connect() {\n if (!this.userId || !this.token) {\n return;\n }\n await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.ensureSdk();\n this.sdkVersion = _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.getSdkVersion();\n this.bindImEvents();\n await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.connect(this.userId, this.token);\n },\n bindImEvents() {\n if (this.eventsBound) {\n return;\n }\n this.eventsBound = true;\n _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.on('connectionStatusChanged', status => {\n this.connected = status.connected;\n this.connectionStatusText = status.statusText || (status.connected ? '已连接' : '未连接');\n });\n },\n async logout() {\n try {\n await _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.logout?.();\n } catch (error) {\n this.error = error.message || '退出登录失败';\n } finally {\n _services_imClient__WEBPACK_IMPORTED_MODULE_2__.imClient.disconnect();\n localStorage.removeItem(STORAGE_KEY);\n this.$reset();\n }\n }\n }\n});\n\n//# sourceURL=webpack://jc-web-im/./src/stores/session.js?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/styles/base.css":
|
||
/*!***************************************************************************************************************************************************************!*\
|
||
!*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/styles/base.css ***!
|
||
\***************************************************************************************************************************************************************/
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root {\\r\\n color-scheme: light;\\r\\n --bg: #f4f6f8;\\r\\n --panel: #ffffff;\\r\\n --panel-soft: #f8fafc;\\r\\n --line: #d9e0e7;\\r\\n --text: #18212f;\\r\\n --muted: #6a7584;\\r\\n --primary: #177d72;\\r\\n --primary-strong: #0f625a;\\r\\n --accent: #d84e3f;\\r\\n --bubble-in: #ffffff;\\r\\n --bubble-out: #dff4ef;\\r\\n --rail: #202a33;\\r\\n}\\r\\n\\r\\n* {\\r\\n box-sizing: border-box;\\r\\n}\\r\\n\\r\\nhtml,\\r\\nbody,\\r\\n#app {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\nbody {\\r\\n margin: 0;\\r\\n min-width: 320px;\\r\\n background: var(--bg);\\r\\n color: var(--text);\\r\\n font-family: -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", sans-serif;\\r\\n}\\r\\n\\r\\nbutton,\\r\\ninput,\\r\\ntextarea {\\r\\n font: inherit;\\r\\n}\\r\\n\\r\\nbutton {\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.login-page {\\r\\n min-height: 100vh;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n padding: 24px;\\r\\n background: linear-gradient(135deg, #eef6f3 0%, #f7f3ee 55%, #eef2f7 100%);\\r\\n}\\r\\n\\r\\n.login-panel {\\r\\n width: min(420px, 100%);\\r\\n padding: 32px;\\r\\n background: var(--panel);\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n box-shadow: 0 18px 48px rgba(30, 40, 50, 0.12);\\r\\n}\\r\\n\\r\\n.brand-lockup {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 14px;\\r\\n margin-bottom: 28px;\\r\\n}\\r\\n\\r\\n.brand-mark,\\r\\n.rail-avatar,\\r\\n.conversation-avatar {\\r\\n display: grid;\\r\\n place-items: center;\\r\\n flex: 0 0 auto;\\r\\n}\\r\\n\\r\\n.image-avatar {\\r\\n -o-object-fit: cover;\\r\\n object-fit: cover;\\r\\n}\\r\\n\\r\\n.brand-mark {\\r\\n width: 48px;\\r\\n height: 48px;\\r\\n border-radius: 8px;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n background: #fff;\\r\\n}\\r\\n\\r\\n.brand-lockup h1,\\r\\n.list-header h2,\\r\\n.chat-header h2 {\\r\\n margin: 0;\\r\\n font-size: 20px;\\r\\n}\\r\\n\\r\\n.brand-lockup p,\\r\\n.list-header p,\\r\\n.chat-header p {\\r\\n margin: 4px 0 0;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.login-form {\\r\\n display: grid;\\r\\n gap: 16px;\\r\\n}\\r\\n\\r\\n.login-tabs,\\r\\n.code-row,\\r\\n.phone-row,\\r\\n.captcha-row {\\r\\n display: grid;\\r\\n grid-template-columns: 1fr 1fr;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.login-tabs button,\\r\\n.code-action {\\r\\n height: 38px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.login-tabs button.active {\\r\\n border-color: var(--primary);\\r\\n background: #e8f4f2;\\r\\n color: var(--primary-strong);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.login-tabs {\\r\\n grid-template-columns: repeat(3, minmax(0, 1fr));\\r\\n}\\r\\n\\r\\n.login-tabs button {\\r\\n min-width: 0;\\r\\n padding: 0 6px;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.code-row {\\r\\n grid-template-columns: minmax(0, 1fr) 112px;\\r\\n}\\r\\n\\r\\n.captcha-row {\\r\\n grid-template-columns: minmax(0, 1fr) 112px;\\r\\n}\\r\\n\\r\\n.phone-row {\\r\\n grid-template-columns: 86px minmax(0, 1fr);\\r\\n}\\r\\n\\r\\n.country-code-field {\\r\\n height: 42px;\\r\\n display: grid;\\r\\n grid-template-columns: 24px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.country-code-field:focus-within {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.country-code-field span {\\r\\n display: grid;\\r\\n place-items: center;\\r\\n color: var(--muted);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.code-action:disabled {\\r\\n cursor: not-allowed;\\r\\n opacity: 0.55;\\r\\n}\\r\\n\\r\\n.login-form label {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.label-row {\\r\\n min-height: 18px;\\r\\n display: grid;\\r\\n grid-template-columns: 86px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.field-error-badge {\\r\\n min-height: 28px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n padding: 4px 10px;\\r\\n border-radius: 2px;\\r\\n background: var(--accent);\\r\\n color: #fff;\\r\\n font-weight: 700;\\r\\n line-height: 1.2;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.login-form input,\\r\\n.login-form select,\\r\\n.modal-panel input,\\r\\n.modal-panel textarea,\\r\\n.search-box input,\\r\\n.message-composer textarea {\\r\\n width: 100%;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.login-form input,\\r\\n.login-form select,\\r\\n.modal-panel input,\\r\\n.search-box input {\\r\\n height: 42px;\\r\\n padding: 0 12px;\\r\\n}\\r\\n\\r\\n.modal-panel textarea {\\r\\n min-height: 92px;\\r\\n resize: vertical;\\r\\n padding: 10px 12px;\\r\\n line-height: 1.5;\\r\\n}\\r\\n\\r\\n.login-form .country-code-field input {\\r\\n height: 40px;\\r\\n padding: 0 10px 0 0;\\r\\n border: 0;\\r\\n border-radius: 0;\\r\\n}\\r\\n\\r\\n.login-form .country-code-field input:focus {\\r\\n border-color: transparent;\\r\\n box-shadow: none;\\r\\n}\\r\\n\\r\\n.login-form input:focus,\\r\\n.login-form select:focus,\\r\\n.modal-panel input:focus,\\r\\n.modal-panel textarea:focus,\\r\\n.search-box input:focus,\\r\\n.message-composer textarea:focus {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.login-form input.captcha-input-valid {\\r\\n border-color: var(--primary);\\r\\n background: var(--primary);\\r\\n color: #fff;\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.login-form input.captcha-input-valid::-moz-placeholder {\\r\\n color: rgba(255, 255, 255, 0.75);\\r\\n}\\r\\n\\r\\n.login-form input.captcha-input-valid::placeholder {\\r\\n color: rgba(255, 255, 255, 0.75);\\r\\n}\\r\\n\\r\\n.login-form input.captcha-input-invalid {\\r\\n border-color: var(--accent);\\r\\n color: var(--accent);\\r\\n box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12);\\r\\n}\\r\\n\\r\\n.login-form input.field-input-error {\\r\\n border-color: var(--accent);\\r\\n color: var(--accent);\\r\\n box-shadow: 0 0 0 3px rgba(216, 78, 63, 0.12);\\r\\n}\\r\\n\\r\\n.login-form input.field-input-error::-moz-placeholder {\\r\\n color: rgba(216, 78, 63, 0.78);\\r\\n}\\r\\n\\r\\n.login-form input.field-input-error::placeholder {\\r\\n color: rgba(216, 78, 63, 0.78);\\r\\n}\\r\\n\\r\\n.captcha-button {\\r\\n width: 112px;\\r\\n height: 42px;\\r\\n padding: 0;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #f7fbfa;\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.captcha-button img {\\r\\n display: block;\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n}\\r\\n\\r\\n.qr-login-card {\\r\\n position: relative;\\r\\n width: min(248px, 100%);\\r\\n aspect-ratio: 1;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n justify-self: center;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: #fff;\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.qr-code-button {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n padding: 18px;\\r\\n border: 0;\\r\\n background: #fff;\\r\\n color: var(--muted);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.qr-code-button:disabled {\\r\\n cursor: default;\\r\\n}\\r\\n\\r\\n.qr-code-button img {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n image-rendering: pixelated;\\r\\n}\\r\\n\\r\\n.qr-login-card.scanned .qr-code-button,\\r\\n.qr-login-card.expired .qr-code-button,\\r\\n.qr-login-card.error .qr-code-button {\\r\\n opacity: 0.22;\\r\\n}\\r\\n\\r\\n.qr-scan-user {\\r\\n position: absolute;\\r\\n inset: 0;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n background: rgba(255, 255, 255, 0.76);\\r\\n}\\r\\n\\r\\n.qr-scan-user img,\\r\\n.qr-scan-user span {\\r\\n width: 70px;\\r\\n height: 70px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border-radius: 8px;\\r\\n background: var(--primary);\\r\\n color: #fff;\\r\\n font-size: 28px;\\r\\n font-weight: 800;\\r\\n -o-object-fit: cover;\\r\\n object-fit: cover;\\r\\n}\\r\\n\\r\\n.qr-login-status {\\r\\n min-height: 48px;\\r\\n display: grid;\\r\\n gap: 4px;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.qr-login-status strong {\\r\\n color: var(--text);\\r\\n font-size: 15px;\\r\\n}\\r\\n\\r\\n.qr-login-status span {\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.primary-action,\\r\\n.primary-inline-action,\\r\\n.send-button {\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: var(--primary);\\r\\n color: #fff;\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.primary-action {\\r\\n height: 44px;\\r\\n}\\r\\n\\r\\n.primary-action:hover,\\r\\n.primary-inline-action:hover,\\r\\n.send-button:hover {\\r\\n background: var(--primary-strong);\\r\\n}\\r\\n\\r\\n.primary-action:disabled,\\r\\n.primary-inline-action:disabled,\\r\\n.send-button:disabled {\\r\\n cursor: not-allowed;\\r\\n opacity: 0.55;\\r\\n}\\r\\n\\r\\n.ghost-action {\\r\\n width: 100%;\\r\\n height: 40px;\\r\\n margin-top: 12px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.ghost-inline-action,\\r\\n.primary-inline-action,\\r\\n.danger-inline-action {\\r\\n height: 38px;\\r\\n display: inline-flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n padding: 0 16px;\\r\\n border-radius: 6px;\\r\\n font-weight: 700;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.ghost-inline-action {\\r\\n border: 1px solid var(--line);\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.ghost-inline-action:hover {\\r\\n background: #edf2f5;\\r\\n}\\r\\n\\r\\n.danger-inline-action {\\r\\n border: 1px solid #ef4444;\\r\\n background: #fff;\\r\\n color: #b91c1c;\\r\\n}\\r\\n\\r\\n.danger-inline-action:hover {\\r\\n background: #fee2e2;\\r\\n}\\r\\n\\r\\n.form-error {\\r\\n margin: 0;\\r\\n color: var(--accent);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.form-info {\\r\\n margin: 0;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.app-shell {\\n height: 100dvh;\\n min-height: 0;\\n display: grid;\\n grid-template-columns: 64px minmax(260px, 340px) minmax(0, 1fr);\\n overflow: hidden;\\n background: var(--panel);\\n}\\n\\n.documented-shell {\\n min-height: 100dvh;\\n display: grid;\\n grid-template-columns: 260px minmax(0, 1fr);\\n background:\\n radial-gradient(circle at top left, rgba(23, 125, 114, 0.08), transparent 28%),\\n linear-gradient(180deg, #f4f8f7 0%, #eef3f7 100%);\\n}\\n\\n.documented-rail {\\n min-height: 0;\\n display: grid;\\n align-content: start;\\n gap: 14px;\\n padding: 24px 20px;\\n border-right: 1px solid var(--line);\\n background: rgba(255, 255, 255, 0.82);\\n backdrop-filter: blur(12px);\\n}\\n\\n.documented-avatar {\\n width: 64px;\\n height: 64px;\\n display: grid;\\n place-items: center;\\n overflow: hidden;\\n border-radius: 16px;\\n background: #dff4ef;\\n color: var(--primary-strong);\\n font-size: 28px;\\n font-weight: 800;\\n}\\n\\n.documented-avatar img {\\n width: 100%;\\n height: 100%;\\n -o-object-fit: cover;\\n object-fit: cover;\\n}\\n\\n.documented-rail-copy {\\n display: grid;\\n gap: 4px;\\n}\\n\\n.documented-rail-copy strong {\\n font-size: 16px;\\n}\\n\\n.documented-rail-copy small {\\n color: var(--muted);\\n overflow-wrap: anywhere;\\n}\\n\\n.documented-rail-button {\\n min-height: 40px;\\n padding: 0 14px;\\n border: 0;\\n border-radius: 10px;\\n background: var(--primary);\\n color: #fff;\\n font-weight: 700;\\n text-align: left;\\n}\\n\\n.documented-rail-button.ghost {\\n border: 1px solid var(--line);\\n background: #fff;\\n color: var(--text);\\n}\\n\\n.documented-main {\\n min-width: 0;\\n min-height: 0;\\n overflow: auto;\\n padding: 28px;\\n display: grid;\\n align-content: start;\\n gap: 18px;\\n}\\n\\n.documented-header {\\n display: flex;\\n align-items: end;\\n justify-content: space-between;\\n gap: 18px;\\n}\\n\\n.documented-header h1 {\\n margin: 0;\\n font-size: 28px;\\n}\\n\\n.documented-header p {\\n margin: 6px 0 0;\\n color: var(--muted);\\n}\\n\\n.documented-status {\\n min-width: 180px;\\n display: grid;\\n gap: 4px;\\n padding: 14px 16px;\\n border: 1px solid var(--line);\\n border-radius: 14px;\\n background: rgba(255, 255, 255, 0.88);\\n}\\n\\n.documented-status span {\\n color: var(--muted);\\n font-size: 12px;\\n}\\n\\n.documented-status strong {\\n font-size: 15px;\\n}\\n\\n.documented-card {\\n display: grid;\\n gap: 12px;\\n padding: 20px;\\n border: 1px solid var(--line);\\n border-radius: 16px;\\n background: rgba(255, 255, 255, 0.88);\\n box-shadow: 0 16px 36px rgba(24, 33, 47, 0.06);\\n}\\n\\n.documented-card h2 {\\n margin: 0;\\n font-size: 18px;\\n}\\n\\n.documented-text {\\n margin: 0;\\n color: var(--muted);\\n line-height: 1.6;\\n}\\n\\n.documented-list {\\n margin: 0;\\n padding-left: 18px;\\n display: grid;\\n gap: 8px;\\n line-height: 1.55;\\n}\\n\\n.documented-list.muted {\\n color: var(--muted);\\n}\\n\\n.documented-meta {\\n margin: 0;\\n display: grid;\\n gap: 10px;\\n}\\n\\n.documented-meta div {\\n display: grid;\\n grid-template-columns: 110px minmax(0, 1fr);\\n gap: 12px;\\n padding-top: 10px;\\n border-top: 1px solid var(--line);\\n}\\n\\n.documented-meta dt {\\n color: var(--muted);\\n}\\n\\n.documented-meta dd {\\n margin: 0;\\n overflow-wrap: anywhere;\\n}\\n\\n.documented-password-panel {\\n width: min(100%, 360px);\\n}\\n\\r\\n.navigation-rail {\\r\\n min-height: 0;\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n align-items: center;\\r\\n gap: 14px;\\r\\n padding: 16px 10px;\\r\\n background: var(--rail);\\r\\n}\\r\\n\\r\\n.rail-avatar {\\r\\n width: 40px;\\r\\n height: 40px;\\r\\n border-radius: 8px;\\r\\n background: #e9f7f4;\\r\\n color: var(--primary-strong);\\r\\n font-weight: 800;\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.rail-avatar-button {\\r\\n position: relative;\\r\\n border: 0;\\r\\n padding: 0;\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.rail-avatar-button::after {\\r\\n content: \\\"+\\\";\\r\\n position: absolute;\\r\\n right: -2px;\\r\\n bottom: -2px;\\r\\n width: 15px;\\r\\n height: 15px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border: 1px solid var(--rail);\\r\\n border-radius: 50%;\\r\\n background: var(--primary);\\r\\n color: #fff;\\r\\n font-size: 11px;\\r\\n font-weight: 800;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.rail-avatar-button:hover,\\r\\n.rail-avatar-button:focus-visible {\\r\\n box-shadow: 0 0 0 3px rgba(47, 196, 178, 0.28);\\r\\n}\\r\\n\\r\\n.rail-avatar img {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n -o-object-fit: cover;\\r\\n object-fit: cover;\\r\\n}\\r\\n\\r\\n.rail-button,\\r\\n.icon-button {\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n}\\r\\n\\r\\n.rail-button {\\r\\n width: 40px;\\r\\n height: 40px;\\r\\n color: #dbe5ea;\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.rail-button svg {\\r\\n width: 22px;\\r\\n height: 22px;\\r\\n fill: none;\\r\\n stroke: currentColor;\\r\\n stroke-width: 1.8;\\r\\n stroke-linecap: round;\\r\\n stroke-linejoin: round;\\r\\n}\\r\\n\\r\\n.rail-button.active,\\r\\n.rail-button:hover {\\r\\n background: rgba(255, 255, 255, 0.12);\\r\\n}\\r\\n\\r\\n.rail-logout-button:hover {\\r\\n background: rgba(239, 68, 68, 0.2);\\r\\n color: #fecaca;\\r\\n}\\r\\n\\r\\n.rail-spacer {\\r\\n flex: 1;\\r\\n}\\r\\n\\r\\n.conversation-list {\\r\\n position: relative;\\r\\n min-height: 0;\\r\\n display: grid;\\r\\n grid-template-rows: 72px auto minmax(0, 1fr);\\r\\n border-right: 1px solid var(--line);\\r\\n background: var(--panel-soft);\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.modal-backdrop {\\r\\n position: absolute;\\r\\n inset: 0;\\r\\n z-index: 5;\\r\\n display: grid;\\r\\n place-items: start center;\\r\\n padding: 88px 16px 16px;\\r\\n background: rgba(24, 33, 47, 0.28);\\r\\n}\\r\\n\\r\\n.modal-panel {\\r\\n width: min(100%, 308px);\\r\\n display: grid;\\r\\n gap: 14px;\\r\\n padding: 16px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.modal-panel header,\\r\\n.modal-actions {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.modal-panel header strong {\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.modal-panel label {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.settings-backdrop {\\r\\n z-index: 24;\\r\\n place-items: center;\\r\\n padding: 24px 16px;\\r\\n}\\r\\n\\r\\n.settings-panel {\\r\\n width: min(620px, calc(100vw - 32px));\\r\\n max-height: calc(100dvh - 48px);\\r\\n display: grid;\\r\\n gap: 14px;\\r\\n overflow: auto;\\r\\n padding: 16px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.settings-panel header,\\r\\n.settings-password-form footer {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.settings-panel header strong {\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.settings-layout {\\r\\n display: grid;\\r\\n grid-template-columns: 170px minmax(0, 1fr);\\r\\n gap: 14px;\\r\\n}\\r\\n\\r\\n.settings-menu {\\r\\n display: grid;\\r\\n align-content: start;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.settings-menu button {\\r\\n min-height: 46px;\\r\\n display: grid;\\r\\n gap: 2px;\\r\\n justify-items: start;\\r\\n padding: 8px 10px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.settings-menu button.active,\\r\\n.settings-menu button:hover {\\r\\n border-color: var(--primary);\\r\\n background: #e8f4f2;\\r\\n color: var(--primary-strong);\\r\\n}\\r\\n\\r\\n.settings-menu button span {\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.settings-menu button small {\\r\\n color: var(--muted);\\r\\n font-size: 11px;\\r\\n}\\r\\n\\r\\n.settings-password-form,\\r\\n.settings-placeholder {\\r\\n min-height: 250px;\\r\\n display: grid;\\r\\n align-content: start;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.settings-password-form h3,\\r\\n.settings-placeholder h3 {\\r\\n margin: 0;\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.settings-password-form label {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.settings-password-form input {\\r\\n width: 100%;\\r\\n height: 42px;\\r\\n padding: 0 12px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.settings-password-form input:focus {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.settings-password-form footer {\\r\\n margin-top: 4px;\\r\\n justify-content: flex-end;\\r\\n flex-wrap: wrap;\\r\\n}\\r\\n\\r\\n.settings-password-form footer .inline-save-status {\\r\\n margin-right: auto;\\r\\n}\\r\\n\\r\\n.settings-placeholder {\\r\\n place-items: center;\\r\\n border: 1px dashed var(--line);\\r\\n border-radius: 8px;\\r\\n color: var(--muted);\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.settings-placeholder p {\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n.profile-edit-panel {\\r\\n width: min(100%, 360px);\\r\\n}\\r\\n\\r\\n.profile-avatar-field {\\r\\n display: grid;\\r\\n justify-items: center;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.profile-avatar-field input[type=\\\"file\\\"] {\\r\\n position: absolute;\\r\\n inline-size: 1px;\\r\\n block-size: 1px;\\r\\n opacity: 0;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.profile-avatar-preview {\\r\\n width: 88px;\\r\\n height: 88px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n overflow: hidden;\\r\\n padding: 0;\\r\\n border: 0;\\r\\n border-radius: 8px;\\r\\n background: #dce8f2;\\r\\n color: #24435c;\\r\\n cursor: default;\\r\\n font-size: 30px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.profile-avatar-preview.clickable {\\r\\n cursor: zoom-in;\\r\\n}\\r\\n\\r\\n.profile-avatar-preview.clickable:hover {\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.16);\\r\\n}\\r\\n\\r\\n.profile-avatar-preview img {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n -o-object-fit: cover;\\r\\n object-fit: cover;\\r\\n}\\r\\n\\r\\n.profile-avatar-change-button {\\r\\n min-width: 96px;\\r\\n}\\r\\n\\r\\n.avatar-preview-backdrop {\\r\\n z-index: 32;\\r\\n place-items: center;\\r\\n padding: 24px 16px;\\r\\n}\\r\\n\\r\\n.avatar-preview-dialog {\\r\\n width: min(520px, calc(100vw - 32px));\\r\\n max-height: calc(100dvh - 48px);\\r\\n display: grid;\\r\\n gap: 12px;\\r\\n padding: 14px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.avatar-preview-dialog header {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.avatar-preview-actions {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n}\\r\\n\\r\\n.avatar-preview-actions button {\\r\\n min-width: 34px;\\r\\n height: 34px;\\r\\n display: inline-flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.avatar-preview-actions .icon-button {\\r\\n border: 0;\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.avatar-preview-stage {\\r\\n height: min(430px, calc(100dvh - 160px));\\r\\n min-height: 260px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n overflow: hidden;\\r\\n border-radius: 8px;\\r\\n background: #101820;\\r\\n cursor: zoom-in;\\r\\n touch-action: none;\\r\\n}\\r\\n\\r\\n.avatar-preview-stage.dragging {\\r\\n cursor: grabbing;\\r\\n}\\r\\n\\r\\n.avatar-preview-stage img {\\r\\n max-width: min(100%, 430px);\\r\\n max-height: 100%;\\r\\n border-radius: 8px;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n transform-origin: center center;\\r\\n transition: transform 0.08s ease-out;\\r\\n -webkit-user-select: none;\\r\\n -moz-user-select: none;\\r\\n user-select: none;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.avatar-preview-stage.dragging img {\\r\\n transition: none;\\r\\n}\\r\\n\\r\\n.avatar-cropper-backdrop {\\r\\n z-index: 30;\\r\\n place-items: center;\\r\\n padding: 24px 16px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-panel {\\r\\n width: min(720px, calc(100vw - 32px));\\r\\n max-height: calc(100dvh - 48px);\\r\\n overflow: auto;\\r\\n}\\r\\n\\r\\n.avatar-cropper-header-actions {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-layout {\\r\\n display: grid;\\r\\n grid-template-columns: minmax(0, 1fr) 190px;\\r\\n gap: 14px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-stage {\\r\\n position: relative;\\r\\n height: 360px;\\r\\n min-height: 360px;\\r\\n overflow: hidden;\\r\\n border: 1px dashed #b8ccd7;\\r\\n border-radius: 8px;\\r\\n background: #0f1b24;\\r\\n touch-action: none;\\r\\n cursor: grab;\\r\\n}\\r\\n\\r\\n.avatar-cropper-stage.dragging {\\r\\n cursor: grabbing;\\r\\n}\\r\\n\\r\\n.avatar-cropper-stage canvas {\\r\\n position: absolute;\\r\\n inset: 0;\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n display: block;\\r\\n}\\r\\n\\r\\n.avatar-cropper-box {\\r\\n position: absolute;\\r\\n left: 50%;\\r\\n top: 50%;\\r\\n width: 74%;\\r\\n aspect-ratio: 1;\\r\\n max-width: calc(100% - 44px);\\r\\n max-height: calc(100% - 44px);\\r\\n transform: translate(-50%, -50%);\\r\\n border: 2px dashed var(--primary);\\r\\n border-radius: 8px;\\r\\n box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.72);\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.avatar-cropper-mask {\\r\\n position: absolute;\\r\\n inset: 0;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.avatar-cropper-placeholder {\\r\\n position: absolute;\\r\\n inset: 0;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n color: #d9e8ee;\\r\\n font-size: 13px;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.avatar-cropper-controls {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n align-content: start;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-tools {\\r\\n display: grid;\\r\\n grid-template-columns: repeat(2, minmax(0, 1fr));\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-tools button {\\r\\n min-height: 34px;\\r\\n padding: 0 10px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.avatar-cropper-tools button:hover {\\r\\n border-color: var(--primary);\\r\\n color: var(--primary-strong);\\r\\n}\\r\\n\\r\\n.avatar-cropper-preview {\\r\\n width: 108px;\\r\\n height: 108px;\\r\\n justify-self: center;\\r\\n overflow: hidden;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: #eef4f7;\\r\\n}\\r\\n\\r\\n.avatar-cropper-preview canvas {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n display: block;\\r\\n}\\r\\n\\r\\n.avatar-cropper-controls footer {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n flex-wrap: wrap;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.avatar-cropper-controls footer .inline-save-status {\\r\\n flex: 1 1 100%;\\r\\n}\\r\\n\\r\\n.modal-actions {\\r\\n justify-content: flex-end;\\r\\n}\\r\\n\\r\\n.list-header,\\r\\n.chat-header {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n min-height: 72px;\\r\\n padding: 16px 18px;\\r\\n border-bottom: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.icon-button {\\r\\n width: 34px;\\r\\n height: 34px;\\r\\n color: var(--muted);\\r\\n font-size: 20px;\\r\\n}\\r\\n\\r\\n.icon-button:hover {\\r\\n background: #edf2f5;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.search-box {\\r\\n padding: 12px 14px;\\r\\n}\\r\\n\\r\\n.sidebar-scroll {\\r\\n min-height: 0;\\r\\n overflow: auto;\\r\\n overscroll-behavior: contain;\\r\\n}\\r\\n\\r\\n.conversation-item {\\r\\n width: 100%;\\r\\n display: grid;\\r\\n grid-template-columns: 42px minmax(0, 1fr) auto;\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n padding: 12px 14px;\\r\\n border: 0;\\r\\n border-top: 1px solid rgba(217, 224, 231, 0.7);\\r\\n background: transparent;\\r\\n color: inherit;\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.conversation-item.active,\\r\\n.conversation-item:hover {\\r\\n background: #eaf3f1;\\r\\n}\\r\\n\\r\\n.favorite-item {\\r\\n width: 100%;\\r\\n display: grid;\\r\\n grid-template-columns: 32px minmax(0, 1fr) auto;\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n padding: 12px 14px;\\r\\n border: 0;\\r\\n border-top: 1px solid rgba(217, 224, 231, 0.7);\\r\\n background: transparent;\\r\\n color: inherit;\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.favorite-item.active,\\r\\n.favorite-item:hover {\\r\\n background: #eaf3f1;\\r\\n}\\r\\n\\r\\n.favorite-item-icon {\\r\\n width: 32px;\\r\\n height: 32px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border-radius: 6px;\\r\\n background: #fff7df;\\r\\n color: #c79520;\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.favorite-item-main {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 4px;\\r\\n}\\r\\n\\r\\n.favorite-item-main strong,\\r\\n.favorite-item-main small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.favorite-item-main strong {\\r\\n font-size: 14px;\\r\\n}\\r\\n\\r\\n.favorite-item-main small,\\r\\n.favorite-item time {\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.favorite-panel {\\r\\n min-width: 0;\\r\\n min-height: 0;\\r\\n display: grid;\\r\\n grid-template-rows: auto minmax(0, 1fr);\\r\\n background: #eef3f6;\\r\\n}\\r\\n\\r\\n.favorite-detail {\\r\\n min-height: 0;\\r\\n display: grid;\\r\\n align-content: start;\\r\\n gap: 16px;\\r\\n padding: 28px;\\r\\n overflow: auto;\\r\\n}\\r\\n\\r\\n.favorite-detail-message {\\r\\n width: min(680px, 100%);\\r\\n display: grid;\\r\\n grid-template-columns: auto minmax(0, 1fr);\\r\\n gap: 10px 12px;\\r\\n padding: 18px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 8px 24px rgba(24, 33, 47, 0.08);\\r\\n}\\r\\n\\r\\n.favorite-detail-message.recalled {\\r\\n border-color: #f1c7c1;\\r\\n background: #fff7f6;\\r\\n}\\r\\n\\r\\n.favorite-detail-star {\\r\\n color: #c79520;\\r\\n font-size: 18px;\\r\\n line-height: 1.4;\\r\\n}\\r\\n\\r\\n.favorite-detail-body {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.favorite-detail-message p {\\r\\n margin: 0;\\r\\n white-space: pre-wrap;\\r\\n overflow-wrap: anywhere;\\r\\n line-height: 1.55;\\r\\n}\\r\\n\\r\\n.favorite-detail-message time {\\r\\n grid-column: 2;\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.favorite-detail-image {\\r\\n width: min(420px, 100%);\\r\\n display: block;\\r\\n overflow: hidden;\\r\\n border: 1px solid #b9ded8;\\r\\n border-radius: 8px;\\r\\n background: #fff;\\r\\n}\\r\\n\\r\\n.favorite-detail-image img {\\r\\n display: block;\\r\\n width: 100%;\\r\\n max-height: 360px;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n background: #f8fbfc;\\r\\n}\\r\\n\\r\\n.favorite-detail-file {\\r\\n width: min(360px, 100%);\\r\\n}\\r\\n\\r\\n.favorite-detail-actions {\\r\\n width: min(680px, 100%);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.favorite-detail-actions .inline-save-status {\\r\\n margin-right: auto;\\r\\n}\\r\\n\\r\\n.empty-list,\\r\\n.empty-chat {\\r\\n display: grid;\\r\\n place-items: center;\\r\\n align-content: center;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.empty-list {\\r\\n min-height: 180px;\\r\\n padding: 24px;\\r\\n}\\r\\n\\r\\n.empty-chat {\\r\\n min-height: 0;\\r\\n padding: 24px;\\r\\n}\\r\\n\\r\\n.empty-list strong,\\r\\n.empty-chat strong {\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.conversation-avatar {\\r\\n width: 42px;\\r\\n height: 42px;\\r\\n border-radius: 8px;\\r\\n background: #dce8f2;\\r\\n color: #24435c;\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.conversation-copy {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 4px;\\r\\n}\\r\\n\\r\\n.conversation-copy strong,\\r\\n.conversation-copy small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.conversation-copy small {\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.unread-badge {\\r\\n justify-self: end;\\r\\n min-width: 20px;\\r\\n height: 20px;\\r\\n padding: 0 6px;\\r\\n border-radius: 999px;\\r\\n background: #ef4444;\\r\\n color: #fff;\\r\\n font-size: 12px;\\r\\n font-weight: 800;\\r\\n line-height: 20px;\\r\\n text-align: center;\\r\\n box-shadow: 0 0 0 2px #f7fafc;\\r\\n}\\r\\n\\r\\n.chat-panel {\\r\\n position: relative;\\r\\n min-width: 0;\\r\\n min-height: 0;\\r\\n height: 100%;\\r\\n display: grid;\\r\\n grid-template-rows: 72px minmax(0, 1fr) auto auto;\\r\\n overflow: hidden;\\r\\n background: #eef2f5;\\r\\n}\\r\\n\\r\\n.contact-panel {\\r\\n min-width: 0;\\r\\n min-height: 0;\\r\\n height: 100%;\\r\\n display: grid;\\r\\n grid-template-rows: 72px minmax(0, 1fr);\\r\\n overflow: auto;\\r\\n background: #eef2f5;\\r\\n}\\r\\n\\r\\n.contact-profile {\\r\\n align-self: start;\\r\\n width: min(520px, calc(100% - 48px));\\r\\n margin: 48px auto;\\r\\n display: grid;\\r\\n justify-items: center;\\r\\n gap: 18px;\\r\\n padding: 32px;\\r\\n background: var(--panel);\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n}\\r\\n\\r\\n.profile-avatar {\\r\\n width: 76px;\\r\\n height: 76px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border-radius: 8px;\\r\\n background: #dce8f2;\\r\\n color: #24435c;\\r\\n font-size: 28px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.profile-main {\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.remark-row {\\r\\n min-width: 0;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.profile-main h3 {\\r\\n margin: 0;\\r\\n font-size: 22px;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.remark-edit-button {\\r\\n width: 32px;\\r\\n height: 32px;\\r\\n flex: 0 0 auto;\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.profile-main p {\\r\\n margin: 6px 0 0;\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.profile-fields {\\r\\n width: 100%;\\r\\n display: grid;\\r\\n gap: 12px;\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n.profile-fields div {\\r\\n display: grid;\\r\\n grid-template-columns: 80px minmax(0, 1fr);\\r\\n gap: 12px;\\r\\n padding: 10px 0;\\r\\n border-top: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.profile-fields dt {\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.profile-fields dd {\\r\\n margin: 0;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.profile-action {\\r\\n width: 160px;\\r\\n}\\r\\n\\r\\n.contact-panel .contact-modal-backdrop {\\r\\n position: fixed;\\r\\n}\\r\\n\\r\\n.header-actions {\\r\\n display: flex;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.chat-header-actions {\\r\\n position: relative;\\r\\n}\\r\\n\\r\\n.chat-title-button {\\r\\n display: grid;\\r\\n grid-template-columns: 38px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n max-width: min(460px, 52vw);\\r\\n padding: 0;\\r\\n border: 0;\\r\\n background: transparent;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.chat-title-avatar {\\r\\n width: 38px;\\r\\n height: 38px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border-radius: 8px;\\r\\n background: #dce8f2;\\r\\n color: #24435c;\\r\\n font-size: 16px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.chat-title-copy {\\r\\n min-width: 0;\\r\\n}\\r\\n\\r\\n.chat-title-button h2 {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.chat-title-button:hover h2 {\\r\\n color: var(--primary-strong);\\r\\n}\\r\\n\\r\\n.chat-more-menu {\\r\\n top: 38px;\\r\\n width: 150px;\\r\\n}\\r\\n\\r\\n.action-menu-anchor {\\r\\n position: relative;\\r\\n}\\r\\n\\r\\n.quick-action-menu {\\r\\n position: absolute;\\r\\n top: 40px;\\r\\n right: 0;\\r\\n z-index: 7;\\r\\n width: 168px;\\r\\n display: grid;\\r\\n padding: 6px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16);\\r\\n}\\r\\n\\r\\n.quick-action-menu button {\\r\\n height: 34px;\\r\\n padding: 0 10px;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.quick-action-menu button:hover {\\r\\n background: #edf2f5;\\r\\n}\\r\\n\\r\\n.quick-action-menu.chat-more-menu {\\r\\n top: 38px;\\r\\n width: 150px;\\r\\n}\\r\\n\\r\\n.conversation-action-panel {\\r\\n width: min(100%, 340px);\\r\\n max-height: calc(100dvh - 116px);\\r\\n overflow: auto;\\r\\n}\\r\\n\\r\\n.contact-picker {\\r\\n display: grid;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.contact-picker > input {\\r\\n width: 100%;\\r\\n height: 38px;\\r\\n padding: 0 10px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n}\\r\\n\\r\\n.contact-picker-list {\\r\\n max-height: 220px;\\r\\n overflow: auto;\\r\\n display: grid;\\r\\n gap: 6px;\\r\\n padding-right: 2px;\\r\\n}\\r\\n\\r\\n.contact-picker-row {\\r\\n width: 100%;\\r\\n min-height: 48px;\\r\\n display: grid;\\r\\n grid-template-columns: 22px 36px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n padding: 6px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.contact-picker-row:hover,\\r\\n.contact-picker-row.selected {\\r\\n border-color: #9fd4cc;\\r\\n background: #edf8f5;\\r\\n}\\r\\n\\r\\n.contact-picker-row .conversation-avatar {\\r\\n width: 36px;\\r\\n height: 36px;\\r\\n border-radius: 6px;\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.contact-check {\\r\\n width: 20px;\\r\\n height: 20px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 4px;\\r\\n color: var(--primary-strong);\\r\\n font-size: 13px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.contact-picker-copy {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 2px;\\r\\n}\\r\\n\\r\\n.contact-picker-copy strong,\\r\\n.contact-picker-copy small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.contact-picker-copy small {\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.contact-picker-empty {\\r\\n min-height: 64px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n color: var(--muted);\\r\\n border: 1px dashed var(--line);\\r\\n border-radius: 6px;\\r\\n}\\r\\n\\r\\n.group-dialog {\\r\\n width: min(420px, calc(100% - 32px));\\r\\n max-height: calc(100dvh - 116px);\\r\\n display: grid;\\r\\n gap: 16px;\\r\\n padding: 18px;\\r\\n overflow: auto;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.group-dialog header,\\r\\n.group-dialog footer {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.group-dialog h3 {\\r\\n margin: 0;\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.single-profile-dialog {\\r\\n width: min(420px, calc(100% - 32px));\\r\\n}\\r\\n\\r\\n.single-profile-summary {\\r\\n display: grid;\\r\\n justify-items: center;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.single-profile-summary strong {\\r\\n max-width: 100%;\\r\\n overflow-wrap: anywhere;\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.single-profile-footer {\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n}\\r\\n\\r\\n.single-profile-footer .inline-save-status {\\r\\n margin-right: auto;\\r\\n}\\r\\n\\r\\n.message-detail-dialog {\\r\\n width: min(560px, calc(100% - 32px));\\r\\n}\\r\\n\\r\\n.message-detail-meta div {\\r\\n grid-template-columns: 88px minmax(0, 1fr);\\r\\n}\\r\\n\\r\\n.message-detail-muted {\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.message-detail-summary {\\r\\n display: flex;\\r\\n flex-wrap: wrap;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.message-detail-summary span {\\r\\n min-height: 30px;\\r\\n display: inline-flex;\\r\\n align-items: center;\\r\\n gap: 4px;\\r\\n padding: 0 10px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #f8fbfb;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.message-detail-summary strong {\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.message-detail-groups {\\r\\n display: grid;\\r\\n gap: 14px;\\r\\n}\\r\\n\\r\\n.message-detail-section {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.message-detail-section header {\\r\\n min-height: 28px;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n border-bottom: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.message-detail-section header strong {\\r\\n font-size: 14px;\\r\\n}\\r\\n\\r\\n.message-detail-section header span {\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.message-detail-member-list {\\r\\n display: grid;\\r\\n overflow: hidden;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n}\\r\\n\\r\\n.message-detail-member-row {\\r\\n display: grid;\\r\\n grid-template-columns: 34px minmax(0, 1fr) auto auto;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n min-height: 48px;\\r\\n padding: 7px 8px;\\r\\n border-top: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.message-detail-member-row:first-child {\\r\\n border-top: 0;\\r\\n}\\r\\n\\r\\n.message-detail-member-row .conversation-avatar {\\r\\n width: 34px;\\r\\n height: 34px;\\r\\n border-radius: 6px;\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.message-detail-member-main {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 2px;\\r\\n}\\r\\n\\r\\n.message-detail-member-main strong,\\r\\n.message-detail-member-main small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.message-detail-member-main strong {\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.message-detail-member-main small,\\r\\n.message-detail-member-time {\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.message-detail-member-time {\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.message-detail-role {\\r\\n min-height: 22px;\\r\\n display: inline-flex;\\r\\n align-items: center;\\r\\n padding: 0 7px;\\r\\n border: 1px solid #c7d9e5;\\r\\n border-radius: 6px;\\r\\n color: #416272;\\r\\n font-size: 12px;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.group-dialog label {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.group-dialog input {\\r\\n width: 100%;\\r\\n height: 42px;\\r\\n padding: 0 12px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n}\\r\\n\\r\\n.group-dialog textarea,\\r\\n.group-dialog select {\\r\\n width: 100%;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.group-dialog textarea {\\r\\n min-height: 86px;\\r\\n resize: vertical;\\r\\n padding: 10px 12px;\\r\\n line-height: 1.5;\\r\\n}\\r\\n\\r\\n.group-dialog select {\\r\\n height: 42px;\\r\\n padding: 0 10px;\\r\\n}\\r\\n\\r\\n.group-dialog input:focus {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.group-dialog textarea:focus,\\r\\n.group-dialog select:focus {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.group-profile {\\r\\n display: grid;\\r\\n gap: 10px;\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n.group-profile div {\\r\\n display: grid;\\r\\n grid-template-columns: 78px minmax(0, 1fr);\\r\\n gap: 12px;\\r\\n padding: 10px 0;\\r\\n border-top: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.group-profile dt {\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.group-profile dd {\\r\\n margin: 0;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.group-loading {\\r\\n min-height: 96px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.group-member-list {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.group-member-row {\\r\\n display: grid;\\r\\n grid-template-columns: 42px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n min-height: 54px;\\r\\n padding: 8px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n}\\r\\n\\r\\n.group-member-row.selectable {\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.group-member-row.with-check {\\r\\n grid-template-columns: 24px 42px minmax(0, 1fr);\\r\\n}\\r\\n\\r\\n.group-member-row.selectable:hover,\\r\\n.group-member-row.selectable.selected {\\r\\n border-color: #9fd4cc;\\r\\n background: #edf8f5;\\r\\n}\\r\\n\\r\\n.group-member-row input[type=\\\"checkbox\\\"] {\\r\\n justify-self: center;\\r\\n width: 16px;\\r\\n height: 16px;\\r\\n}\\r\\n\\r\\n.group-member-row span:last-child {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 3px;\\r\\n}\\r\\n\\r\\n.group-member-row strong,\\r\\n.group-member-row small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.group-member-row small {\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.group-management-dialog {\\r\\n width: min(520px, calc(100% - 32px));\\r\\n}\\r\\n\\r\\n.group-management-tabs {\\r\\n display: flex;\\r\\n flex-wrap: wrap;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.group-management-tabs button {\\r\\n height: 34px;\\r\\n padding: 0 10px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.group-management-tabs button.active,\\r\\n.group-management-tabs button:hover {\\r\\n border-color: var(--primary);\\r\\n background: #e8f4f2;\\r\\n color: var(--primary-strong);\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.group-manage-section {\\r\\n display: grid;\\r\\n gap: 14px;\\r\\n}\\r\\n\\r\\n.group-manage-section footer {\\r\\n justify-content: flex-end;\\r\\n}\\r\\n\\r\\n.mute-save-footer {\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.inline-save-status {\\r\\n color: var(--primary-strong);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.inline-save-status.error {\\r\\n color: var(--accent);\\r\\n}\\r\\n\\r\\n.mute-time-grid {\\r\\n display: grid;\\r\\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.message-list {\\r\\n min-height: 0;\\r\\n overflow: auto;\\r\\n overscroll-behavior: contain;\\r\\n padding: 24px;\\r\\n}\\r\\n\\r\\n.message-row {\\r\\n display: flex;\\r\\n align-items: flex-end;\\r\\n gap: 8px;\\r\\n margin-bottom: 14px;\\r\\n}\\r\\n\\r\\n.message-row.out {\\r\\n justify-content: flex-end;\\r\\n}\\r\\n\\r\\n.message-sender-avatar {\\r\\n width: 34px;\\r\\n height: 34px;\\r\\n flex: 0 0 auto;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n overflow: hidden;\\r\\n padding: 0;\\r\\n border: 0;\\r\\n border-radius: 8px;\\r\\n background: #dce8f2;\\r\\n color: #24435c;\\r\\n font-size: 14px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.message-sender-avatar img {\\r\\n width: 100%;\\r\\n height: 100%;\\r\\n -o-object-fit: cover;\\r\\n object-fit: cover;\\r\\n}\\r\\n\\r\\n.message-stack {\\r\\n max-width: min(68%, 720px);\\r\\n display: grid;\\r\\n justify-items: start;\\r\\n gap: 4px;\\r\\n}\\r\\n\\r\\n.message-row.out .message-stack {\\r\\n justify-items: end;\\r\\n}\\r\\n\\r\\n.message-sender-name {\\r\\n min-height: 18px;\\r\\n max-width: 100%;\\r\\n padding: 0;\\r\\n border: 0;\\r\\n background: transparent;\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n font-weight: 700;\\r\\n text-align: left;\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.message-sender-name:hover {\\r\\n color: var(--primary-strong);\\r\\n}\\r\\n\\r\\n.message-sender-role {\\r\\n margin-left: 4px;\\r\\n color: var(--primary-strong);\\r\\n font-size: 11px;\\r\\n}\\r\\n\\r\\n.message-row.selected .message-bubble {\\r\\n box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.26);\\r\\n}\\r\\n\\r\\n.message-row.attention .message-bubble {\\r\\n animation: message-attention 1.4s ease-in-out 2;\\r\\n box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.3);\\r\\n}\\r\\n\\r\\n@keyframes message-attention {\\r\\n 0%,\\r\\n 100% {\\r\\n box-shadow: 0 0 0 2px rgba(24, 138, 121, 0.16);\\r\\n }\\r\\n\\r\\n 45% {\\r\\n box-shadow: 0 0 0 5px rgba(24, 138, 121, 0.36);\\r\\n }\\r\\n}\\r\\n\\r\\n.message-select {\\r\\n width: 24px;\\r\\n height: 24px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n}\\r\\n\\r\\n.message-select input {\\r\\n width: 16px;\\r\\n height: 16px;\\r\\n}\\r\\n\\r\\n.message-bubble {\\r\\n position: relative;\\r\\n max-width: min(68%, 720px);\\r\\n padding: 10px 12px 8px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--bubble-in);\\r\\n box-shadow: 0 2px 8px rgba(30, 40, 50, 0.05);\\r\\n}\\r\\n\\r\\n.message-stack .message-bubble {\\r\\n max-width: 100%;\\r\\n}\\r\\n\\r\\n.message-row.out .message-bubble {\\r\\n background: var(--bubble-out);\\r\\n border-color: #bfe4dc;\\r\\n}\\r\\n\\r\\n.message-bubble:hover {\\r\\n border-color: #9fd4cc;\\r\\n}\\r\\n\\r\\n.message-bubble.role-bubble-owner,\\r\\n.message-bubble.role-bubble-admin {\\r\\n overflow: hidden;\\r\\n}\\r\\n\\r\\n.message-bubble.role-bubble-owner::after,\\r\\n.message-bubble.role-bubble-admin::after {\\r\\n content: \\\"\\\";\\r\\n position: absolute;\\r\\n top: 0;\\r\\n right: 0;\\r\\n width: 0;\\r\\n height: 0;\\r\\n border-top: 16px solid #d79d22;\\r\\n border-left: 16px solid transparent;\\r\\n}\\r\\n\\r\\n.message-bubble.role-bubble-admin::after {\\r\\n border-top-color: #178a79;\\r\\n}\\r\\n\\r\\n.message-bubble p {\\r\\n margin: 0;\\r\\n line-height: 1.5;\\r\\n white-space: pre-wrap;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.message-image {\\r\\n padding: 0;\\r\\n border: 0;\\r\\n display: block;\\r\\n max-width: min(280px, 62vw);\\r\\n overflow: hidden;\\r\\n border-radius: 6px;\\r\\n background: #edf2f5;\\r\\n cursor: zoom-in;\\r\\n}\\r\\n\\r\\n.message-image + p,\\r\\n.message-file + p {\\r\\n margin-top: 8px;\\r\\n}\\r\\n\\r\\n.message-image img {\\r\\n display: block;\\r\\n max-width: 100%;\\r\\n max-height: 320px;\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n}\\r\\n\\r\\n.image-viewer-backdrop {\\r\\n position: fixed;\\r\\n inset: 0;\\r\\n z-index: 80;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n padding: 24px;\\r\\n background: rgba(12, 18, 26, 0.58);\\r\\n}\\r\\n\\r\\n.image-viewer-dialog {\\r\\n width: min(880px, calc(100vw - 48px));\\r\\n height: min(640px, calc(100vh - 48px));\\r\\n min-width: 360px;\\r\\n min-height: 280px;\\r\\n max-width: calc(100vw - 48px);\\r\\n max-height: calc(100vh - 48px);\\r\\n display: grid;\\r\\n grid-template-rows: 52px minmax(0, 1fr);\\r\\n overflow: hidden;\\r\\n resize: both;\\r\\n border: 1px solid rgba(255, 255, 255, 0.18);\\r\\n border-radius: 8px;\\r\\n background: #101820;\\r\\n box-shadow: 0 24px 70px rgba(0, 0, 0, 0.36);\\r\\n}\\r\\n\\r\\n.image-viewer-toolbar {\\r\\n min-width: 0;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n gap: 8px;\\r\\n padding: 8px 10px;\\r\\n border-bottom: 1px solid rgba(255, 255, 255, 0.12);\\r\\n background: rgba(24, 33, 47, 0.94);\\r\\n}\\r\\n\\r\\n.image-viewer-title {\\r\\n min-width: 0;\\r\\n flex: 1;\\r\\n overflow: hidden;\\r\\n color: #f8fafc;\\r\\n font-size: 13px;\\r\\n font-weight: 700;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.image-viewer-toolbar button {\\r\\n width: 36px;\\r\\n height: 36px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n color: #f8fafc;\\r\\n font-size: 17px;\\r\\n font-weight: 700;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.image-viewer-toolbar button:hover {\\r\\n background: rgba(255, 255, 255, 0.14);\\r\\n}\\r\\n\\r\\n.image-viewer-stage {\\r\\n min-width: 0;\\r\\n min-height: 0;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n overflow: hidden;\\r\\n background: #0c121a;\\r\\n cursor: default;\\r\\n touch-action: none;\\r\\n}\\r\\n\\r\\n.image-viewer-stage.zoomed {\\r\\n cursor: grab;\\r\\n}\\r\\n\\r\\n.image-viewer-stage.dragging {\\r\\n cursor: grabbing;\\r\\n}\\r\\n\\r\\n.image-viewer-img {\\r\\n max-width: calc(100% - 32px);\\r\\n max-height: calc(100% - 32px);\\r\\n -o-object-fit: contain;\\r\\n object-fit: contain;\\r\\n transform-origin: center center;\\r\\n transition: transform 0.08s ease-out;\\r\\n -webkit-user-select: none;\\r\\n -moz-user-select: none;\\r\\n user-select: none;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.image-viewer-stage.dragging .image-viewer-img {\\r\\n transition: none;\\r\\n}\\r\\n\\r\\n.sender-profile-backdrop {\\r\\n position: fixed;\\r\\n inset: 0;\\r\\n z-index: 84;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n padding: 24px;\\r\\n background: rgba(24, 33, 47, 0.32);\\r\\n}\\r\\n\\r\\n.sender-profile-dialog {\\r\\n width: min(380px, calc(100vw - 32px));\\r\\n display: grid;\\r\\n gap: 16px;\\r\\n padding: 18px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.sender-profile-dialog header {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.sender-profile-main {\\r\\n display: grid;\\r\\n justify-items: center;\\r\\n gap: 8px;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n.sender-profile-main strong {\\r\\n max-width: 100%;\\r\\n overflow-wrap: anywhere;\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.sender-profile-main span {\\r\\n color: var(--primary-strong);\\r\\n font-size: 12px;\\r\\n font-weight: 700;\\r\\n}\\r\\n\\r\\n.sender-profile-fields {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n.sender-profile-fields div {\\r\\n display: grid;\\r\\n grid-template-columns: 72px minmax(0, 1fr);\\r\\n gap: 10px;\\r\\n padding-top: 8px;\\r\\n border-top: 1px solid var(--line);\\r\\n}\\r\\n\\r\\n.sender-profile-fields dt {\\r\\n color: var(--muted);\\r\\n}\\r\\n\\r\\n.sender-profile-fields dd {\\r\\n margin: 0;\\r\\n overflow-wrap: anywhere;\\r\\n}\\r\\n\\r\\n.sender-profile-alias {\\r\\n display: grid;\\r\\n gap: 8px;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.sender-profile-alias input {\\r\\n width: 100%;\\r\\n height: 40px;\\r\\n padding: 0 12px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: #fff;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.sender-profile-alias input:focus {\\r\\n border-color: var(--primary);\\r\\n box-shadow: 0 0 0 3px rgba(23, 125, 114, 0.12);\\r\\n}\\r\\n\\r\\n.sender-profile-actions {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.sender-profile-actions .inline-save-status {\\r\\n margin-right: auto;\\r\\n}\\r\\n\\r\\n@media (max-width: 480px) {\\r\\n .image-viewer-backdrop {\\r\\n padding: 12px;\\r\\n }\\r\\n\\r\\n .image-viewer-dialog {\\r\\n width: calc(100vw - 24px);\\r\\n height: min(560px, calc(100vh - 24px));\\r\\n min-width: 280px;\\r\\n min-height: 240px;\\r\\n max-width: calc(100vw - 24px);\\r\\n max-height: calc(100vh - 24px);\\r\\n }\\r\\n\\r\\n .image-viewer-toolbar {\\r\\n gap: 4px;\\r\\n padding: 6px;\\r\\n }\\r\\n\\r\\n .image-viewer-toolbar button {\\r\\n width: 32px;\\r\\n height: 32px;\\r\\n font-size: 15px;\\r\\n }\\r\\n\\r\\n .message-detail-member-row {\\r\\n grid-template-columns: 34px minmax(0, 1fr);\\r\\n }\\r\\n\\r\\n .message-detail-member-time,\\r\\n .message-detail-role {\\r\\n grid-column: 2;\\r\\n justify-self: start;\\r\\n }\\r\\n\\r\\n .avatar-cropper-panel {\\r\\n width: calc(100vw - 24px);\\r\\n max-height: calc(100dvh - 24px);\\r\\n }\\r\\n\\r\\n .avatar-cropper-layout {\\r\\n grid-template-columns: minmax(0, 1fr);\\r\\n }\\r\\n\\r\\n .avatar-cropper-stage {\\r\\n height: 300px;\\r\\n min-height: 300px;\\r\\n }\\r\\n\\r\\n .avatar-cropper-controls {\\r\\n grid-template-columns: minmax(0, 1fr) auto;\\r\\n align-items: center;\\r\\n }\\r\\n\\r\\n .avatar-cropper-tools {\\r\\n grid-template-columns: repeat(3, minmax(0, 1fr));\\r\\n }\\r\\n\\r\\n .avatar-cropper-preview {\\r\\n width: 82px;\\r\\n height: 82px;\\r\\n }\\r\\n\\r\\n .avatar-cropper-controls footer {\\r\\n grid-column: 1 / -1;\\r\\n }\\r\\n\\r\\n .settings-panel {\\r\\n width: calc(100vw - 24px);\\r\\n max-height: calc(100dvh - 24px);\\r\\n }\\r\\n\\r\\n .settings-layout {\\r\\n grid-template-columns: minmax(0, 1fr);\\r\\n }\\r\\n\\r\\n .settings-menu {\\r\\n grid-auto-flow: column;\\r\\n grid-auto-columns: minmax(120px, 1fr);\\r\\n overflow-x: auto;\\r\\n padding-bottom: 2px;\\r\\n }\\r\\n\\r\\n .settings-password-form footer .inline-save-status {\\r\\n flex: 1 1 100%;\\r\\n }\\r\\n}\\r\\n\\r\\n.message-file {\\r\\n width: min(280px, 62vw);\\r\\n display: grid;\\r\\n grid-template-columns: 38px minmax(0, 1fr);\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n padding: 10px;\\r\\n border: 1px solid #d6e2e7;\\r\\n border-radius: 6px;\\r\\n background: #f8fbfc;\\r\\n color: var(--text);\\r\\n text-decoration: none;\\r\\n}\\r\\n\\r\\n.message-file:hover {\\r\\n border-color: #9fd4cc;\\r\\n background: #edf8f5;\\r\\n}\\r\\n\\r\\n.message-file-icon {\\r\\n width: 38px;\\r\\n height: 38px;\\r\\n display: grid;\\r\\n place-items: center;\\r\\n border-radius: 6px;\\r\\n background: #e3eff2;\\r\\n color: var(--primary-strong);\\r\\n font-size: 18px;\\r\\n font-weight: 800;\\r\\n}\\r\\n\\r\\n.message-file-main {\\r\\n min-width: 0;\\r\\n display: grid;\\r\\n gap: 3px;\\r\\n}\\r\\n\\r\\n.message-file-main strong,\\r\\n.message-file-main small {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.message-file-main strong {\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.message-file-main small {\\r\\n color: var(--muted);\\r\\n font-size: 11px;\\r\\n}\\r\\n\\r\\n.message-bubble time {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n flex-wrap: wrap;\\r\\n gap: 4px;\\r\\n margin-top: 4px;\\r\\n color: var(--muted);\\r\\n font-size: 11px;\\r\\n text-align: right;\\r\\n}\\r\\n\\r\\n.recall-mark {\\r\\n margin-right: auto;\\r\\n color: #d93025;\\r\\n font-size: 11px;\\r\\n font-weight: 700;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.edit-mark {\\r\\n color: #7a8792;\\r\\n font-size: 11px;\\r\\n font-weight: 600;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.delivery-mark {\\r\\n display: inline-flex;\\r\\n align-items: center;\\r\\n justify-content: flex-end;\\r\\n min-width: 14px;\\r\\n color: #8f9aa3;\\r\\n font-size: 14px;\\r\\n font-weight: 800;\\r\\n letter-spacing: 0;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.delivery-mark-delivered,\\r\\n.delivery-mark-read {\\r\\n min-width: 19px;\\r\\n}\\r\\n\\r\\n.delivery-mark-read {\\r\\n color: #1aa66a;\\r\\n}\\r\\n\\r\\n.favorite-mark {\\r\\n color: #c79520;\\r\\n font-size: 12px;\\r\\n line-height: 1;\\r\\n}\\r\\n\\r\\n.delivery-check {\\r\\n display: inline-block;\\r\\n}\\r\\n\\r\\n.delivery-check-second {\\r\\n margin-left: -5px;\\r\\n}\\r\\n\\r\\n.delivery-error {\\r\\n color: #c0392b;\\r\\n}\\r\\n\\r\\n.message-context-menu {\\r\\n position: fixed;\\r\\n z-index: 30;\\r\\n width: 136px;\\r\\n padding: 6px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 16px 40px rgba(24, 33, 47, 0.18);\\r\\n}\\r\\n\\r\\n.message-context-menu button {\\r\\n width: 100%;\\r\\n min-height: 32px;\\r\\n padding: 0 10px;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.message-context-menu button:hover {\\r\\n background: #eaf3f1;\\r\\n}\\r\\n\\r\\n.selection-toolbar {\\r\\n min-height: 42px;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n padding: 8px 16px;\\r\\n border-top: 1px solid var(--line);\\r\\n background: #f7fafc;\\r\\n}\\r\\n\\r\\n.selection-toolbar span {\\r\\n flex: 1;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.selection-toolbar button {\\r\\n min-height: 30px;\\r\\n padding: 0 10px;\\r\\n border-radius: 6px;\\r\\n}\\r\\n\\r\\n.forward-dialog,\\r\\n.edit-dialog {\\r\\n width: min(100%, 340px);\\r\\n max-height: min(520px, calc(100vh - 130px));\\r\\n display: grid;\\r\\n gap: 4px;\\r\\n padding: 14px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 18px 40px rgba(24, 33, 47, 0.18);\\r\\n overflow: auto;\\r\\n}\\r\\n\\r\\n.forward-dialog header,\\r\\n.edit-dialog header,\\r\\n.forward-target {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n.forward-dialog header,\\r\\n.edit-dialog header {\\r\\n justify-content: space-between;\\r\\n margin-bottom: 6px;\\r\\n}\\r\\n\\r\\n.forward-dialog h3,\\r\\n.edit-dialog h3 {\\r\\n margin: 0;\\r\\n font-size: 16px;\\r\\n}\\r\\n\\r\\n.edit-dialog {\\r\\n width: min(100%, 420px);\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.edit-dialog textarea {\\r\\n width: 100%;\\r\\n min-height: 132px;\\r\\n resize: vertical;\\r\\n border-radius: 8px;\\r\\n border: 1px solid var(--line);\\r\\n padding: 10px;\\r\\n background: #f9fbfc;\\r\\n color: var(--text);\\r\\n line-height: 1.5;\\r\\n}\\r\\n\\r\\n.edit-dialog textarea:focus {\\r\\n border-color: var(--accent);\\r\\n outline: 0;\\r\\n box-shadow: 0 0 0 3px rgba(24, 138, 121, 0.14);\\r\\n}\\r\\n\\r\\n.edit-dialog footer {\\r\\n display: flex;\\r\\n justify-content: flex-end;\\r\\n gap: 8px;\\r\\n}\\r\\n\\r\\n.edit-dialog footer button {\\r\\n min-height: 34px;\\r\\n padding: 0 14px;\\r\\n border-radius: 8px;\\r\\n}\\r\\n\\r\\n.forward-target {\\r\\n min-height: 52px;\\r\\n padding: 6px;\\r\\n border: 0;\\r\\n border-radius: 8px;\\r\\n background: transparent;\\r\\n color: var(--text);\\r\\n text-align: left;\\r\\n}\\r\\n\\r\\n.forward-target:hover {\\r\\n background: #eaf3f1;\\r\\n}\\r\\n\\r\\n.chat-toast {\\r\\n position: absolute;\\r\\n left: 50%;\\r\\n bottom: 132px;\\r\\n z-index: 20;\\r\\n transform: translateX(-50%);\\r\\n padding: 8px 12px;\\r\\n border-radius: 8px;\\r\\n background: rgba(35, 45, 58, 0.92);\\r\\n color: #fff;\\r\\n font-size: 13px;\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n.chat-toast.error {\\r\\n background: rgba(192, 57, 43, 0.94);\\r\\n}\\r\\n\\r\\n.message-composer {\\r\\n position: relative;\\r\\n min-height: 0;\\r\\n border-top: 1px solid var(--line);\\r\\n background: var(--panel);\\r\\n}\\r\\n\\r\\n.message-composer::after {\\r\\n content: \\\"\\\";\\r\\n position: absolute;\\r\\n inset: 6px;\\r\\n z-index: 4;\\r\\n border: 2px dashed transparent;\\r\\n border-radius: 8px;\\r\\n pointer-events: none;\\r\\n transition: border-color 0.12s ease, background-color 0.12s ease;\\r\\n}\\r\\n\\r\\n.message-composer.drop-active::after {\\r\\n border-color: var(--primary);\\r\\n background: rgba(23, 125, 114, 0.08);\\r\\n}\\r\\n\\r\\n.quote-preview {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n padding: 8px 16px 0;\\r\\n color: var(--muted);\\r\\n font-size: 13px;\\r\\n}\\r\\n\\r\\n.quote-preview span {\\r\\n min-width: 0;\\r\\n flex: 1;\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n border-left: 3px solid var(--accent);\\r\\n padding-left: 8px;\\r\\n}\\r\\n\\r\\n.quote-preview strong {\\r\\n margin-right: 6px;\\r\\n color: var(--text);\\r\\n}\\r\\n\\r\\n.quote-preview button {\\r\\n width: 26px;\\r\\n height: 26px;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n color: var(--muted);\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.quote-preview button:hover {\\r\\n background: #edf2f5;\\r\\n}\\r\\n\\r\\n.composer-tools {\\r\\n position: relative;\\r\\n display: flex;\\r\\n gap: 4px;\\r\\n padding: 8px 16px 0;\\r\\n}\\r\\n\\r\\n.composer-tools input[type=\\\"file\\\"] {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.composer-tools button {\\r\\n width: 32px;\\r\\n height: 32px;\\r\\n border: 0;\\r\\n border-radius: 6px;\\r\\n background: transparent;\\r\\n color: var(--muted);\\r\\n font-size: 18px;\\r\\n}\\r\\n\\r\\n.composer-tools button:hover {\\r\\n background: #edf2f5;\\r\\n}\\r\\n\\r\\n.emoji-picker {\\r\\n position: absolute;\\r\\n left: 16px;\\r\\n bottom: 38px;\\r\\n z-index: 12;\\r\\n width: 256px;\\r\\n display: grid;\\r\\n grid-template-columns: repeat(8, 1fr);\\r\\n gap: 2px;\\r\\n padding: 8px;\\r\\n border: 1px solid var(--line);\\r\\n border-radius: 8px;\\r\\n background: var(--panel);\\r\\n box-shadow: 0 14px 34px rgba(24, 33, 47, 0.16);\\r\\n}\\r\\n\\r\\n.emoji-picker button {\\r\\n width: 28px;\\r\\n height: 28px;\\r\\n border-radius: 6px;\\r\\n font-size: 17px;\\r\\n}\\r\\n\\r\\n.message-composer textarea {\\r\\n display: block;\\r\\n min-height: 86px;\\r\\n max-height: 180px;\\r\\n padding: 12px 16px;\\r\\n border: 0;\\r\\n border-radius: 0;\\r\\n resize: none;\\r\\n box-shadow: none;\\r\\n}\\r\\n\\r\\n.composer-footer {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n padding: 0 16px 14px;\\r\\n color: var(--muted);\\r\\n font-size: 12px;\\r\\n}\\r\\n\\r\\n.send-button {\\r\\n min-width: 72px;\\r\\n height: 34px;\\r\\n}\\r\\n\\r\\n@media (max-width: 760px) {\\r\\n .app-shell {\\r\\n grid-template-columns: 56px minmax(0, 1fr);\\r\\n }\\r\\n\\r\\n .conversation-list {\\r\\n display: none;\\r\\n }\\r\\n\\r\\n .message-bubble {\\r\\n max-width: 86%;\\r\\n }\\r\\n}\\r\\n\", \"\"]);\n// Exports\n/* harmony default export */ __webpack_exports__[\"default\"] = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://jc-web-im/./src/styles/base.css?./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use%5B1%5D!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use%5B2%5D\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/App.vue":
|
||
/*!*********************!*\
|
||
!*** ./src/App.vue ***!
|
||
\*********************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _App_vue_vue_type_template_id_7ba5bd90__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./App.vue?vue&type=template&id=7ba5bd90 */ \"./src/App.vue?vue&type=template&id=7ba5bd90\");\n/* harmony import */ var _App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./App.vue?vue&type=script&setup=true&lang=js */ \"./src/App.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_App_vue_vue_type_template_id_7ba5bd90__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/App.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/App.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/ChatShell.vue":
|
||
/*!**************************************!*\
|
||
!*** ./src/components/ChatShell.vue ***!
|
||
\**************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ChatShell_vue_vue_type_template_id_2fe58db8__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ChatShell.vue?vue&type=template&id=2fe58db8 */ \"./src/components/ChatShell.vue?vue&type=template&id=2fe58db8\");\n/* harmony import */ var _ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ChatShell.vue?vue&type=script&setup=true&lang=js */ \"./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ChatShell_vue_vue_type_template_id_2fe58db8__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ChatShell.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/ChatShell.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/LoginView.vue":
|
||
/*!**************************************!*\
|
||
!*** ./src/components/LoginView.vue ***!
|
||
\**************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _LoginView_vue_vue_type_template_id_37959aa4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./LoginView.vue?vue&type=template&id=37959aa4 */ \"./src/components/LoginView.vue?vue&type=template&id=37959aa4\");\n/* harmony import */ var _LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LoginView.vue?vue&type=script&setup=true&lang=js */ \"./src/components/LoginView.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_LoginView_vue_vue_type_template_id_37959aa4__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/LoginView.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/LoginView.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/ChatPanel.vue":
|
||
/*!*******************************************!*\
|
||
!*** ./src/components/chat/ChatPanel.vue ***!
|
||
\*******************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ChatPanel_vue_vue_type_template_id_358a1705__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ChatPanel.vue?vue&type=template&id=358a1705 */ \"./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705\");\n/* harmony import */ var _ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ChatPanel.vue?vue&type=script&setup=true&lang=js */ \"./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ChatPanel_vue_vue_type_template_id_358a1705__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/chat/ChatPanel.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/ChatPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageComposer.vue":
|
||
/*!*************************************************!*\
|
||
!*** ./src/components/chat/MessageComposer.vue ***!
|
||
\*************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _MessageComposer_vue_vue_type_template_id_08eca580__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageComposer.vue?vue&type=template&id=08eca580 */ \"./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580\");\n/* harmony import */ var _MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MessageComposer.vue?vue&type=script&setup=true&lang=js */ \"./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_MessageComposer_vue_vue_type_template_id_08eca580__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/chat/MessageComposer.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageComposer.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageList.vue":
|
||
/*!*********************************************!*\
|
||
!*** ./src/components/chat/MessageList.vue ***!
|
||
\*********************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _MessageList_vue_vue_type_template_id_a39e6c04__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageList.vue?vue&type=template&id=a39e6c04 */ \"./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04\");\n/* harmony import */ var _MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MessageList.vue?vue&type=script&setup=true&lang=js */ \"./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_MessageList_vue_vue_type_template_id_a39e6c04__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/chat/MessageList.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/contacts/ContactPanel.vue":
|
||
/*!**************************************************!*\
|
||
!*** ./src/components/contacts/ContactPanel.vue ***!
|
||
\**************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ContactPanel_vue_vue_type_template_id_63d88b80__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ContactPanel.vue?vue&type=template&id=63d88b80 */ \"./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80\");\n/* harmony import */ var _ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ContactPanel.vue?vue&type=script&setup=true&lang=js */ \"./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ContactPanel_vue_vue_type_template_id_63d88b80__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/contacts/ContactPanel.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/contacts/ContactPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoriteList.vue":
|
||
/*!***************************************************!*\
|
||
!*** ./src/components/favorites/FavoriteList.vue ***!
|
||
\***************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _FavoriteList_vue_vue_type_template_id_0086db7c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FavoriteList.vue?vue&type=template&id=0086db7c */ \"./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c\");\n/* harmony import */ var _FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FavoriteList.vue?vue&type=script&setup=true&lang=js */ \"./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_FavoriteList_vue_vue_type_template_id_0086db7c__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/favorites/FavoriteList.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoriteList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoritePanel.vue":
|
||
/*!****************************************************!*\
|
||
!*** ./src/components/favorites/FavoritePanel.vue ***!
|
||
\****************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _FavoritePanel_vue_vue_type_template_id_29e1a3e0__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FavoritePanel.vue?vue&type=template&id=29e1a3e0 */ \"./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0\");\n/* harmony import */ var _FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FavoritePanel.vue?vue&type=script&setup=true&lang=js */ \"./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_FavoritePanel_vue_vue_type_template_id_29e1a3e0__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/favorites/FavoritePanel.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoritePanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ContactList.vue":
|
||
/*!************************************************!*\
|
||
!*** ./src/components/sidebar/ContactList.vue ***!
|
||
\************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ContactList_vue_vue_type_template_id_7aaf5f2b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ContactList.vue?vue&type=template&id=7aaf5f2b */ \"./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b\");\n/* harmony import */ var _ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ContactList.vue?vue&type=script&setup=true&lang=js */ \"./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ContactList_vue_vue_type_template_id_7aaf5f2b__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/sidebar/ContactList.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ContactList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ConversationList.vue":
|
||
/*!*****************************************************!*\
|
||
!*** ./src/components/sidebar/ConversationList.vue ***!
|
||
\*****************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ConversationList_vue_vue_type_template_id_7a656f78__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ConversationList.vue?vue&type=template&id=7a656f78 */ \"./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78\");\n/* harmony import */ var _ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ConversationList.vue?vue&type=script&setup=true&lang=js */ \"./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ConversationList_vue_vue_type_template_id_7a656f78__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/sidebar/ConversationList.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ConversationList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/NavigationRail.vue":
|
||
/*!***************************************************!*\
|
||
!*** ./src/components/sidebar/NavigationRail.vue ***!
|
||
\***************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _NavigationRail_vue_vue_type_template_id_021016ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./NavigationRail.vue?vue&type=template&id=021016ee */ \"./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee\");\n/* harmony import */ var _NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NavigationRail.vue?vue&type=script&setup=true&lang=js */ \"./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js\");\n/* harmony import */ var _node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_NavigationRail_vue_vue_type_template_id_021016ee__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/sidebar/NavigationRail.vue\"]])\n/* hot reload */\nif (false) // removed by dead control flow\n{}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/NavigationRail.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/App.vue?vue&type=script&setup=true&lang=js":
|
||
/*!********************************************************!*\
|
||
!*** ./src/App.vue?vue&type=script&setup=true&lang=js ***!
|
||
\********************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./App.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/App.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*************************************************************************!*\
|
||
!*** ./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ChatShell.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/ChatShell.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/LoginView.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*************************************************************************!*\
|
||
!*** ./src/components/LoginView.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./LoginView.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/LoginView.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!******************************************************************************!*\
|
||
!*** ./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\******************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ChatPanel.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/ChatPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js":
|
||
/*!************************************************************************************!*\
|
||
!*** ./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js ***!
|
||
\************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./MessageComposer.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageComposer.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!********************************************************************************!*\
|
||
!*** ./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./MessageList.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!*************************************************************************************!*\
|
||
!*** ./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\*************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ContactPanel.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/contacts/ContactPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!**************************************************************************************!*\
|
||
!*** ./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\**************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./FavoriteList.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoriteList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js":
|
||
/*!***************************************************************************************!*\
|
||
!*** ./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js ***!
|
||
\***************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./FavoritePanel.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoritePanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!***********************************************************************************!*\
|
||
!*** ./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\***********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ContactList.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ContactList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js":
|
||
/*!****************************************************************************************!*\
|
||
!*** ./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js ***!
|
||
\****************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ConversationList.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ConversationList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js":
|
||
/*!**************************************************************************************!*\
|
||
!*** ./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js ***!
|
||
\**************************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_script_setup_true_lang_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_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__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./NavigationRail.vue?vue&type=script&setup=true&lang=js */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=script&setup=true&lang=js\");\n \n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/NavigationRail.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/App.vue?vue&type=template&id=7ba5bd90":
|
||
/*!***************************************************!*\
|
||
!*** ./src/App.vue?vue&type=template&id=7ba5bd90 ***!
|
||
\***************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_template_id_7ba5bd90__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_template_id_7ba5bd90__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./App.vue?vue&type=template&id=7ba5bd90 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/App.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/ChatShell.vue?vue&type=template&id=2fe58db8":
|
||
/*!********************************************************************!*\
|
||
!*** ./src/components/ChatShell.vue?vue&type=template&id=2fe58db8 ***!
|
||
\********************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_template_id_2fe58db8__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatShell_vue_vue_type_template_id_2fe58db8__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ChatShell.vue?vue&type=template&id=2fe58db8 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/ChatShell.vue?vue&type=template&id=2fe58db8\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/ChatShell.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/LoginView.vue?vue&type=template&id=37959aa4":
|
||
/*!********************************************************************!*\
|
||
!*** ./src/components/LoginView.vue?vue&type=template&id=37959aa4 ***!
|
||
\********************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_template_id_37959aa4__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_LoginView_vue_vue_type_template_id_37959aa4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./LoginView.vue?vue&type=template&id=37959aa4 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/LoginView.vue?vue&type=template&id=37959aa4\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/LoginView.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705":
|
||
/*!*************************************************************************!*\
|
||
!*** ./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705 ***!
|
||
\*************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_template_id_358a1705__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ChatPanel_vue_vue_type_template_id_358a1705__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ChatPanel.vue?vue&type=template&id=358a1705 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/ChatPanel.vue?vue&type=template&id=358a1705\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/ChatPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580":
|
||
/*!*******************************************************************************!*\
|
||
!*** ./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580 ***!
|
||
\*******************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_template_id_08eca580__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageComposer_vue_vue_type_template_id_08eca580__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./MessageComposer.vue?vue&type=template&id=08eca580 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageComposer.vue?vue&type=template&id=08eca580\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageComposer.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04":
|
||
/*!***************************************************************************!*\
|
||
!*** ./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04 ***!
|
||
\***************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_template_id_a39e6c04__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_MessageList_vue_vue_type_template_id_a39e6c04__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./MessageList.vue?vue&type=template&id=a39e6c04 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/chat/MessageList.vue?vue&type=template&id=a39e6c04\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/chat/MessageList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80":
|
||
/*!********************************************************************************!*\
|
||
!*** ./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80 ***!
|
||
\********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_template_id_63d88b80__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactPanel_vue_vue_type_template_id_63d88b80__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ContactPanel.vue?vue&type=template&id=63d88b80 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/contacts/ContactPanel.vue?vue&type=template&id=63d88b80\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/contacts/ContactPanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c":
|
||
/*!*********************************************************************************!*\
|
||
!*** ./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c ***!
|
||
\*********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_template_id_0086db7c__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoriteList_vue_vue_type_template_id_0086db7c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./FavoriteList.vue?vue&type=template&id=0086db7c */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoriteList.vue?vue&type=template&id=0086db7c\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoriteList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0":
|
||
/*!**********************************************************************************!*\
|
||
!*** ./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0 ***!
|
||
\**********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_template_id_29e1a3e0__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_FavoritePanel_vue_vue_type_template_id_29e1a3e0__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./FavoritePanel.vue?vue&type=template&id=29e1a3e0 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/favorites/FavoritePanel.vue?vue&type=template&id=29e1a3e0\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/favorites/FavoritePanel.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b":
|
||
/*!******************************************************************************!*\
|
||
!*** ./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b ***!
|
||
\******************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_template_id_7aaf5f2b__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ContactList_vue_vue_type_template_id_7aaf5f2b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ContactList.vue?vue&type=template&id=7aaf5f2b */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ContactList.vue?vue&type=template&id=7aaf5f2b\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ContactList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78":
|
||
/*!***********************************************************************************!*\
|
||
!*** ./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78 ***!
|
||
\***********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_template_id_7a656f78__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_ConversationList_vue_vue_type_template_id_7a656f78__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./ConversationList.vue?vue&type=template&id=7a656f78 */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/ConversationList.vue?vue&type=template&id=7a656f78\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/ConversationList.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee":
|
||
/*!*********************************************************************************!*\
|
||
!*** ./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee ***!
|
||
\*********************************************************************************/
|
||
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_template_id_021016ee__WEBPACK_IMPORTED_MODULE_0__.render; }\n/* harmony export */ });\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_40_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_NavigationRail_vue_vue_type_template_id_021016ee__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./NavigationRail.vue?vue&type=template&id=021016ee */ \"./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/sidebar/NavigationRail.vue?vue&type=template&id=021016ee\");\n\n\n//# sourceURL=webpack://jc-web-im/./src/components/sidebar/NavigationRail.vue?\n}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/styles/base.css":
|
||
/*!*****************************!*\
|
||
!*** ./src/styles/base.css ***!
|
||
\*****************************/
|
||
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
||
|
||
eval("{// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(/*! !!../../node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!../../node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./base.css */ \"./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/styles/base.css\");\nif(content.__esModule) content = content.default;\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar add = (__webpack_require__(/*! !../../node_modules/vue-style-loader/lib/addStylesClient.js */ \"./node_modules/vue-style-loader/lib/addStylesClient.js\")[\"default\"])\nvar update = add(\"1a9917ba\", content, false, {\"sourceMap\":false,\"shadowMode\":false});\n// Hot Module Replacement\nif(false) // removed by dead control flow\n{}\n\n//# sourceURL=webpack://jc-web-im/./src/styles/base.css?\n}");
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
/************************************************************************/
|
||
/******/ // 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] = {
|
||
/******/ id: moduleId,
|
||
/******/ // no module.loaded needed
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ if (!(moduleId in __webpack_modules__)) {
|
||
/******/ delete __webpack_module_cache__[moduleId];
|
||
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
||
/******/ e.code = 'MODULE_NOT_FOUND';
|
||
/******/ throw e;
|
||
/******/ }
|
||
/******/ __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 = {
|
||
/******/ "app": 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, ["chunk-vendors"], function() { return __webpack_require__("./src/main.js"); })
|
||
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
||
/******/
|
||
/******/ })()
|
||
; |