vue-chat-kit 0.1.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
- import { ref as m, computed as oe, nextTick as Ke, watch as mt, resolveComponent as ie, createBlock as H, openBlock as i, withCtx as b, createElementVNode as t, createElementBlock as f, createCommentVNode as F, createVNode as h, createTextVNode as se, onMounted as vt, onUnmounted as gt, unref as u, Fragment as he, renderList as pe, normalizeClass as j, resolveDynamicComponent as yt, toDisplayString as w, isRef as we, withModifiers as Oe, withDirectives as xt, withKeys as bt, vModelText as _t, normalizeStyle as wt } from "vue";
2
- import { ChatDotRound as Me, UserFilled as Xe, Bell as kt, Setting as Ct, Search as Ee, Plus as Ut, MoreFilled as At, Document as St, Download as Vt, Folder as Ye, Picture as Ft, ChatLineRound as Rt, Camera as It } from "@element-plus/icons-vue";
3
- import $e from "dayjs";
4
- import { ElMessage as X } from "element-plus";
5
- class Lt {
6
- constructor(e, a = {}) {
7
- this.userId = e, this.wsUrl = a.wsUrl || "", this.socket = null, this.reconnectAttempts = 0, this.maxReconnectAttempts = a.maxReconnectAttempts || 5, this.reconnectDelay = a.reconnectDelay || 3e3, this.handlers = {
1
+ import { ref as h, computed as ye, nextTick as Qe, watch as Dt, resolveComponent as ie, openBlock as n, createBlock as B, withCtx as b, createElementVNode as e, createElementBlock as v, createCommentVNode as U, createVNode as p, createTextVNode as J, onMounted as gt, onUnmounted as _t, unref as c, Fragment as se, renderList as ae, normalizeClass as K, resolveDynamicComponent as yt, toDisplayString as _, isRef as Ce, withModifiers as Ye, withDirectives as bt, withKeys as kt, vModelText as wt, normalizeStyle as Ct } from "vue";
2
+ import { ChatDotRound as Re, UserFilled as Ge, Bell as Ut, Setting as $t, Search as Le, Plus as xt, MoreFilled as At, Document as Vt, Download as St, Folder as Je, Picture as Ft, ChatLineRound as It, Camera as zt } from "@element-plus/icons-vue";
3
+ import mt from "dayjs";
4
+ import { ElMessage as P } from "element-plus";
5
+ class Et {
6
+ constructor(t, a = {}) {
7
+ this.userId = t, this.wsUrl = a.wsUrl || "", this.socket = null, this.reconnectAttempts = 0, this.maxReconnectAttempts = a.maxReconnectAttempts || 5, this.reconnectDelay = a.reconnectDelay || 3e3, this.handlers = {
8
8
  message: [],
9
9
  open: [],
10
10
  close: [],
@@ -20,60 +20,60 @@ class Lt {
20
20
  try {
21
21
  this.socket = new WebSocket(this.wsUrl), this.socket.onopen = () => {
22
22
  console.log("[VueChatKit] WebSocket 连接成功"), this.isConnecting = !1, this.reconnectAttempts = 0, this.emit("open");
23
- }, this.socket.onmessage = (e) => {
23
+ }, this.socket.onmessage = (t) => {
24
24
  try {
25
- const a = e.data;
25
+ const a = t.data;
26
26
  this.emit("message", a);
27
27
  } catch (a) {
28
28
  console.error("[VueChatKit] WebSocket 消息解析失败", a);
29
29
  }
30
- }, this.socket.onclose = (e) => {
31
- console.log("[VueChatKit] WebSocket 连接关闭", e.code), this.isConnecting = !1, this.emit("close", e), !this.manualClose && e.code !== 1e3 && this.reconnect();
32
- }, this.socket.onerror = (e) => {
33
- console.error("[VueChatKit] WebSocket 连接错误", e), this.isConnecting = !1, this.emit("error", e);
30
+ }, this.socket.onclose = (t) => {
31
+ console.log("[VueChatKit] WebSocket 连接关闭", t.code), this.isConnecting = !1, this.emit("close", t), !this.manualClose && t.code !== 1e3 && this.reconnect();
32
+ }, this.socket.onerror = (t) => {
33
+ console.error("[VueChatKit] WebSocket 连接错误", t), this.isConnecting = !1, this.emit("error", t);
34
34
  };
35
- } catch (e) {
36
- console.error("[VueChatKit] WebSocket 创建连接失败", e), this.isConnecting = !1;
35
+ } catch (t) {
36
+ console.error("[VueChatKit] WebSocket 创建连接失败", t), this.isConnecting = !1;
37
37
  }
38
38
  }
39
39
  }
40
40
  /**
41
41
  * 发送消息
42
42
  */
43
- send(e, a, o = "text", R = "", L = "", z = 0) {
43
+ send(t, a, m = "text", C = "", N = "", I = 0) {
44
44
  if (this.isConnected()) {
45
- const k = JSON.stringify({
46
- to: e,
45
+ const T = JSON.stringify({
46
+ to: t,
47
47
  msg: a,
48
- type: o,
49
- fileUrl: R,
50
- fileName: L,
51
- fileSize: z
48
+ type: m,
49
+ fileUrl: C,
50
+ fileName: N,
51
+ fileSize: I
52
52
  });
53
- return this.socket.send(k), !0;
53
+ return this.socket.send(T), !0;
54
54
  }
55
55
  return console.warn("[VueChatKit] WebSocket 连接未建立,无法发送消息"), !1;
56
56
  }
57
57
  /**
58
58
  * 注册事件监听
59
59
  */
60
- on(e, a) {
61
- this.handlers[e] && this.handlers[e].push(a);
60
+ on(t, a) {
61
+ this.handlers[t] && this.handlers[t].push(a);
62
62
  }
63
63
  /**
64
64
  * 移除事件监听
65
65
  */
66
- off(e, a) {
67
- if (this.handlers[e]) {
68
- const o = this.handlers[e].indexOf(a);
69
- o > -1 && this.handlers[e].splice(o, 1);
66
+ off(t, a) {
67
+ if (this.handlers[t]) {
68
+ const m = this.handlers[t].indexOf(a);
69
+ m > -1 && this.handlers[t].splice(m, 1);
70
70
  }
71
71
  }
72
72
  /**
73
73
  * 触发事件
74
74
  */
75
- emit(e, ...a) {
76
- this.handlers[e] && this.handlers[e].forEach((o) => o(...a));
75
+ emit(t, ...a) {
76
+ this.handlers[t] && this.handlers[t].forEach((m) => m(...a));
77
77
  }
78
78
  /**
79
79
  * 重连
@@ -99,729 +99,758 @@ class Lt {
99
99
  return this.socket && this.socket.readyState === WebSocket.OPEN;
100
100
  }
101
101
  }
102
- class ke extends Error {
103
- constructor(e, a, o, R) {
104
- super(e), this.name = "RequestError", this.status = a || 0, this.code = o || 0, this.data = R;
102
+ class Xe extends Error {
103
+ constructor(t, a, m, C) {
104
+ super(t), this.name = "RequestError", this.status = a || 0, this.code = m || 0, this.data = C;
105
105
  }
106
106
  }
107
- class Tt {
108
- constructor(e = {}) {
109
- this.baseUrl = e.baseUrl || "", this.timeout = e.timeout || 1e4, this.headers = e.headers || {}, this.requestInterceptors = [], this.responseInterceptors = [], this.addRequestInterceptor((a) => (a.body instanceof FormData || (a.headers = {
107
+ class qt {
108
+ constructor(t = {}) {
109
+ this.baseUrl = t.baseUrl || "", this.timeout = t.timeout || 1e4, this.headers = t.headers || {}, this.requestInterceptors = [], this.responseInterceptors = [], t.requestInterceptors && Array.isArray(t.requestInterceptors) && t.requestInterceptors.forEach((a) => {
110
+ this.requestInterceptors.push(a);
111
+ }), this.addRequestInterceptor((a) => (a.body instanceof FormData || (a.headers = {
110
112
  "Content-Type": "application/json",
111
113
  ...a.headers
112
- }), a));
114
+ }), a)), t.responseInterceptors && Array.isArray(t.responseInterceptors) && t.responseInterceptors.forEach((a) => {
115
+ this.responseInterceptors.push(a);
116
+ });
113
117
  }
114
118
  /**
115
119
  * 添加请求拦截器
116
120
  */
117
- addRequestInterceptor(e) {
118
- this.requestInterceptors.push(e);
121
+ addRequestInterceptor(t) {
122
+ this.requestInterceptors.push(t);
119
123
  }
120
124
  /**
121
125
  * 添加响应拦截器
122
126
  */
123
- addResponseInterceptor(e) {
124
- this.responseInterceptors.push(e);
127
+ addResponseInterceptor(t) {
128
+ this.responseInterceptors.push(t);
125
129
  }
126
130
  /**
127
131
  * 超时控制
128
132
  */
129
- timeoutPromise(e) {
130
- return new Promise((a, o) => {
133
+ timeoutPromise(t) {
134
+ return new Promise((a, m) => {
131
135
  setTimeout(() => {
132
- o(new ke("请求超时", 408, 408));
133
- }, e);
136
+ m(new Xe("请求超时", 408, 408));
137
+ }, t);
134
138
  });
135
139
  }
136
140
  /**
137
141
  * 核心请求方法
138
142
  */
139
- async request(e, a = {}) {
140
- const { method: o = "GET", headers: R = {}, body: L, params: z } = a;
141
- let k = e.startsWith("http") ? e : `${this.baseUrl}${e}`, C = {
142
- method: o,
143
- headers: { ...this.headers, ...R },
144
- body: L,
145
- params: z
143
+ async request(t, a = {}) {
144
+ const { method: m = "GET", headers: C = {}, body: N, params: I } = a;
145
+ let T = t.startsWith("http") ? t : `${this.baseUrl}${t}`, L = {
146
+ method: m,
147
+ headers: { ...this.headers, ...C },
148
+ body: N,
149
+ params: I
146
150
  };
147
- this.requestInterceptors.forEach((v) => {
148
- C = v(C);
151
+ this.requestInterceptors.forEach((x) => {
152
+ L = x(L);
149
153
  });
150
- const V = {
151
- method: C.method,
152
- headers: C.headers,
154
+ const H = {
155
+ method: L.method,
156
+ headers: L.headers,
153
157
  credentials: "include"
154
158
  };
155
- if (C.body && o !== "GET" && (C.body instanceof FormData ? V.body = C.body : typeof C.body == "object" ? V.body = JSON.stringify(C.body) : V.body = C.body), C.params) {
156
- const v = new URLSearchParams();
157
- for (const _ in C.params)
158
- C.params[_] !== void 0 && C.params[_] !== null && C.params[_] !== "" && v.append(_, C.params[_]);
159
- const x = v.toString();
160
- x && (k += (k.includes("?") ? "&" : "?") + x);
159
+ if (L.body && m !== "GET" && (L.body instanceof FormData ? H.body = L.body : typeof L.body == "object" ? H.body = JSON.stringify(L.body) : H.body = L.body), L.params) {
160
+ const x = new URLSearchParams();
161
+ for (const S in L.params)
162
+ L.params[S] !== void 0 && L.params[S] !== null && L.params[S] !== "" && x.append(S, L.params[S]);
163
+ const k = x.toString();
164
+ k && (T += (T.includes("?") ? "&" : "?") + k);
161
165
  }
162
166
  try {
163
- let x = await Promise.race([
164
- fetch(k, V),
167
+ let k = await Promise.race([
168
+ fetch(T, H),
165
169
  this.timeoutPromise(this.timeout)
166
170
  ]);
167
- if (this.responseInterceptors.forEach((B) => {
168
- x = B(x);
169
- }), !x.ok)
170
- throw new ke(
171
- `HTTP ${x.status}: ${x.statusText}`,
172
- x.status,
173
- x.status
171
+ if (this.responseInterceptors.forEach((G) => {
172
+ k = G(k);
173
+ }), !k.ok)
174
+ throw new Xe(
175
+ `HTTP ${k.status}: ${k.statusText}`,
176
+ k.status,
177
+ k.status
174
178
  );
175
- const _ = x.headers.get("content-type");
176
- let I;
177
- return _ && _.includes("application/json") ? I = await x.json() : I = await x.text(), I;
178
- } catch (v) {
179
- throw v instanceof ke ? v : new ke(
180
- v instanceof Error ? v.message : "网络错误",
179
+ const S = k.headers.get("content-type");
180
+ let z;
181
+ return S && S.includes("application/json") ? z = await k.json() : z = await k.text(), z;
182
+ } catch (x) {
183
+ throw x instanceof Xe ? x : new Xe(
184
+ x instanceof Error ? x.message : "网络错误",
181
185
  0,
182
186
  0
183
187
  );
184
188
  }
185
189
  }
186
190
  // 便捷方法
187
- get(e, a, o) {
188
- return this.request(e, { ...o, method: "GET", params: a });
191
+ get(t, a, m) {
192
+ return this.request(t, { ...m, method: "GET", params: a });
189
193
  }
190
- post(e, a, o) {
191
- return this.request(e, { ...o, method: "POST", body: a });
194
+ post(t, a, m) {
195
+ return this.request(t, { ...m, method: "POST", body: a });
192
196
  }
193
- put(e, a, o) {
194
- return this.request(e, { ...o, method: "PUT", body: a });
197
+ put(t, a, m) {
198
+ return this.request(t, { ...m, method: "PUT", body: a });
195
199
  }
196
- delete(e, a) {
197
- return this.request(e, { ...a, method: "DELETE" });
200
+ delete(t, a) {
201
+ return this.request(t, { ...a, method: "DELETE" });
198
202
  }
199
203
  }
200
- class zt {
201
- constructor(e, a = null) {
202
- this.config = e, this.endpoints = e.api.endpoints, this.customAdapter = e.api.adapter, a ? this.http = a : this.http = new Tt({
203
- baseUrl: e.api.baseUrl,
204
- headers: e.headers
204
+ class ft {
205
+ constructor(t, a = null) {
206
+ this.config = t, this.endpoints = t.api.endpoints, this.customAdapter = t.api.adapter, a ? this.http = a : this.http = new qt({
207
+ baseUrl: t.api.baseUrl,
208
+ headers: t.headers,
209
+ requestInterceptors: t.requestInterceptors,
210
+ responseInterceptors: t.responseInterceptors
205
211
  });
206
212
  }
207
213
  /**
208
214
  * 使用自定义适配器或默认实现
209
215
  */
210
- async _call(e, ...a) {
211
- return this.customAdapter && typeof this.customAdapter[e] == "function" ? this.customAdapter[e](...a) : this[`_${e}`](...a);
216
+ async _call(t, ...a) {
217
+ return this.customAdapter && typeof this.customAdapter[t] == "function" ? this.customAdapter[t](...a) : this[`_${t}`](...a);
212
218
  }
213
219
  // ========== 好友相关 ==========
214
220
  /**
215
221
  * 获取好友列表
216
222
  */
217
- async getFriends(e) {
218
- return this._call("getFriends", e);
223
+ async getFriends(t) {
224
+ return this._call("getFriends", t);
219
225
  }
220
- async _getFriends(e) {
221
- return this.http.get(this.endpoints.getFriends, { currentUser: e });
226
+ async _getFriends(t) {
227
+ return this.http.get(this.endpoints.getFriends, { currentUser: t });
222
228
  }
223
229
  /**
224
230
  * 获取可添加的用户列表
225
231
  */
226
- async getAvailableUsers(e) {
227
- return this._call("getAvailableUsers", e);
232
+ async getAvailableUsers(t) {
233
+ return this._call("getAvailableUsers", t);
228
234
  }
229
- async _getAvailableUsers(e) {
230
- return this.http.get(this.endpoints.getAvailableUsers, { currentUser: e });
235
+ async _getAvailableUsers(t) {
236
+ return this.http.get(this.endpoints.getAvailableUsers, { currentUser: t });
231
237
  }
232
238
  /**
233
239
  * 添加好友
234
240
  */
235
- async addFriend(e, a) {
236
- return this._call("addFriend", e, a);
241
+ async addFriend(t, a) {
242
+ return this._call("addFriend", t, a);
237
243
  }
238
- async _addFriend(e, a) {
239
- return this.http.post(this.endpoints.addFriend, { currentUser: e, friendUser: a });
244
+ async _addFriend(t, a) {
245
+ return this.http.post(this.endpoints.addFriend, { currentUser: t, friendUser: a });
240
246
  }
241
247
  /**
242
248
  * 获取好友申请列表
243
249
  */
244
- async getApplyList(e) {
245
- return this._call("getApplyList", e);
250
+ async getApplyList(t) {
251
+ return this._call("getApplyList", t);
246
252
  }
247
- async _getApplyList(e) {
248
- return this.http.get(this.endpoints.getApplyList, { currentUser: e });
253
+ async _getApplyList(t) {
254
+ return this.http.get(this.endpoints.getApplyList, { currentUser: t });
249
255
  }
250
256
  /**
251
257
  * 同意好友申请
252
258
  */
253
- async agreeFriend(e, a) {
254
- return this._call("agreeFriend", e, a);
259
+ async agreeFriend(t, a) {
260
+ return this._call("agreeFriend", t, a);
255
261
  }
256
- async _agreeFriend(e, a) {
257
- return this.http.post(this.endpoints.agreeFriend, { applyUser: e, friendUser: a });
262
+ async _agreeFriend(t, a) {
263
+ return this.http.post(this.endpoints.agreeFriend, { applyUser: t, friendUser: a });
258
264
  }
259
265
  /**
260
266
  * 设置好友聊天状态
261
267
  */
262
- async setChatStatus(e, a, o = 1) {
263
- return this._call("setChatStatus", e, a, o);
268
+ async setChatStatus(t, a, m = 1) {
269
+ return this._call("setChatStatus", t, a, m);
264
270
  }
265
- async _setChatStatus(e, a, o) {
266
- return this.http.post(this.endpoints.setChatStatus, null, { params: { currentUser: e, friendUser: a, status: o } });
271
+ async _setChatStatus(t, a, m) {
272
+ return this.http.post(this.endpoints.setChatStatus, null, { params: { currentUser: t, friendUser: a, status: m } });
267
273
  }
268
274
  // ========== 消息相关 ==========
269
275
  /**
270
276
  * 获取聊天历史
271
277
  */
272
- async getHistory(e, a) {
273
- return this._call("getHistory", e, a);
278
+ async getHistory(t, a) {
279
+ return this._call("getHistory", t, a);
274
280
  }
275
- async _getHistory(e, a) {
276
- return this.http.get(this.endpoints.getHistory, { fromUser: e, toUser: a });
281
+ async _getHistory(t, a) {
282
+ return this.http.get(this.endpoints.getHistory, { fromUser: t, toUser: a });
277
283
  }
278
284
  /**
279
285
  * 标记消息已读
280
286
  */
281
- async setRead(e, a) {
282
- return this._call("setRead", e, a);
287
+ async setRead(t, a) {
288
+ return this._call("setRead", t, a);
283
289
  }
284
- async _setRead(e, a) {
285
- return this.http.post(this.endpoints.setRead, { currentUser: e, friendUser: a });
290
+ async _setRead(t, a) {
291
+ return this.http.post(this.endpoints.setRead, { currentUser: t, friendUser: a });
286
292
  }
287
293
  // ========== 文件相关 ==========
288
294
  /**
289
295
  * 上传文件
290
296
  */
291
- async uploadFile(e) {
292
- return this._call("uploadFile", e);
297
+ async uploadFile(t) {
298
+ return this._call("uploadFile", t);
293
299
  }
294
- async _uploadFile(e) {
300
+ async _uploadFile(t) {
295
301
  const a = new FormData();
296
- return a.append("file", e), this.http.post(this.endpoints.uploadFile, a);
302
+ return a.append("file", t), this.http.post(this.endpoints.uploadFile, a);
297
303
  }
298
304
  // ========== 用户相关 ==========
299
305
  /**
300
306
  * 获取用户信息
301
307
  */
302
- async getUserInfo(e) {
303
- return this._call("getUserInfo", e);
308
+ async getUserInfo(t) {
309
+ return this._call("getUserInfo", t);
304
310
  }
305
- async _getUserInfo(e) {
306
- return this.http.get(this.endpoints.getUserInfo, { username: e });
311
+ async _getUserInfo(t) {
312
+ return this.http.get(this.endpoints.getUserInfo, { username: t });
307
313
  }
308
314
  /**
309
315
  * 更新用户信息
310
316
  */
311
- async updateUserInfo(e, a) {
312
- return this._call("updateUserInfo", e, a);
317
+ async updateUserInfo(t, a) {
318
+ return this._call("updateUserInfo", t, a);
313
319
  }
314
- async _updateUserInfo(e, a) {
315
- return this.http.put(this.endpoints.updateUserInfo, { username: e, ...a });
320
+ async _updateUserInfo(t, a) {
321
+ return this.http.put(this.endpoints.updateUserInfo, { username: t, ...a });
316
322
  }
317
323
  /**
318
324
  * 获取用户头像
319
325
  */
320
- async getUserAvatar(e) {
321
- return this._call("getUserAvatar", e);
326
+ async getUserAvatar(t) {
327
+ return this._call("getUserAvatar", t);
322
328
  }
323
- async _getUserAvatar(e) {
324
- return this.http.get(this.endpoints.getUserAvatar, { username: e });
329
+ async _getUserAvatar(t) {
330
+ return this.http.get(this.endpoints.getUserAvatar, { username: t });
325
331
  }
326
332
  /**
327
333
  * 上传头像
328
334
  */
329
- async uploadAvatar(e, a) {
330
- return this._call("uploadAvatar", e, a);
335
+ async uploadAvatar(t, a) {
336
+ return this._call("uploadAvatar", t, a);
331
337
  }
332
- async _uploadAvatar(e, a) {
333
- const o = new FormData();
334
- return o.append("file", e), o.append("username", a), this.http.post(this.endpoints.uploadAvatar, o);
338
+ async _uploadAvatar(t, a) {
339
+ const m = new FormData();
340
+ return m.append("file", t), m.append("username", a), this.http.post(this.endpoints.uploadAvatar, m);
335
341
  }
336
342
  }
337
- function jt(y) {
338
- const e = new zt(y);
339
- let a = null;
340
- const o = y.user.username, R = m(y.user.avatar || `https://api.dicebear.com/7.x/avataaars/svg?seed=${o}`), L = m({
341
- username: o,
342
- nickname: y.user.nickname || "",
343
- email: y.user.email || "",
344
- phone: y.user.phone || "",
345
- bio: y.user.bio || ""
346
- }), z = m(!1), k = m([]), C = m([]), V = m([]), v = m(""), x = m(""), _ = m(""), I = m(null), B = m(!1), Y = m(""), G = m([]), J = m(!1), ae = m([]), ee = m(!1), g = oe(() => {
347
- let n = C.value;
348
- if (x.value) {
349
- const r = x.value.toLowerCase();
350
- n = n.filter(
351
- (c) => c.username?.toLowerCase().includes(r)
343
+ const Rt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
344
+ __proto__: null,
345
+ ChatApi: ft,
346
+ default: ft
347
+ }, Symbol.toStringTag, { value: "Module" }));
348
+ function Lt(w, t) {
349
+ const a = new ft(w);
350
+ let m = null;
351
+ const C = w.user.username, N = h(w.user.avatar || `https://api.dicebear.com/7.x/avataaars/svg?seed=${C}`), I = h({
352
+ username: C,
353
+ nickname: w.user.nickname || "",
354
+ email: w.user.email || "",
355
+ phone: w.user.phone || "",
356
+ bio: w.user.bio || ""
357
+ }), T = h(!1), L = h([]), H = h([]), x = h([]), k = h(""), S = h(""), z = h(""), G = h(null), fe = h(!1), oe = h(""), Q = h([]), ne = h(!1), _e = h([]), $ = h(!1), R = ye(() => {
358
+ let l = H.value;
359
+ if (S.value) {
360
+ const d = S.value.toLowerCase();
361
+ l = l.filter(
362
+ (g) => {
363
+ var A;
364
+ return (A = g.username) == null ? void 0 : A.toLowerCase().includes(d);
365
+ }
352
366
  );
353
367
  }
354
- return n.map((r) => ({
355
- id: r.username,
356
- name: r.username,
357
- avatar: r.avatar || R.value,
358
- online: r.online,
359
- lastMsg: r.lastMsg || "暂无消息",
360
- lastTime: r.lastTime,
361
- unread: r.unReadNum || 0
368
+ return l.map((d) => ({
369
+ id: d.username,
370
+ name: d.username,
371
+ avatar: d.avatar || N.value,
372
+ online: d.online,
373
+ lastMsg: d.lastMsg || "暂无消息",
374
+ lastTime: d.lastTime,
375
+ unread: d.unReadNum || 0
362
376
  }));
363
- }), U = oe(() => {
364
- let n = k.value;
365
- if (x.value) {
366
- const r = x.value.toLowerCase();
367
- n = n.filter(
368
- (c) => c.username?.toLowerCase().includes(r)
377
+ }), M = ye(() => {
378
+ let l = L.value;
379
+ if (S.value) {
380
+ const d = S.value.toLowerCase();
381
+ l = l.filter(
382
+ (g) => {
383
+ var A;
384
+ return (A = g.username) == null ? void 0 : A.toLowerCase().includes(d);
385
+ }
369
386
  );
370
387
  }
371
- return n.map((r) => ({
372
- id: r.username,
373
- name: r.username,
374
- avatar: r.avatar || R.value,
375
- online: r.online,
376
- isChatting: r.isChatting
388
+ return l.map((d) => ({
389
+ id: d.username,
390
+ name: d.username,
391
+ avatar: d.avatar || N.value,
392
+ online: d.online,
393
+ isChatting: d.isChatting
377
394
  }));
378
- }), A = oe(() => Y.value ? G.value.filter(
379
- (n) => n.username?.toLowerCase().includes(Y.value.toLowerCase())
380
- ) : G.value), E = oe(() => g.value.find((n) => n.id === v.value) || null), ne = oe(() => V.value.map((n) => {
381
- const r = n.type === "file" || n.fileUrl || n.fileName, c = n.fileName || n.msgContent;
395
+ }), Z = ye(() => oe.value ? Q.value.filter(
396
+ (l) => {
397
+ var d;
398
+ return (d = l.username) == null ? void 0 : d.toLowerCase().includes(oe.value.toLowerCase());
399
+ }
400
+ ) : Q.value), he = ye(() => R.value.find((l) => l.id === k.value) || null), re = ye(() => x.value.map((l) => {
401
+ const d = l.type === "file" || l.fileUrl || l.fileName, g = l.fileName || l.msgContent;
382
402
  return {
383
- text: n.msgContent,
384
- isSelf: n.sendUsername === o,
385
- time: n.createTime,
386
- sendUsername: n.sendUsername,
387
- type: r ? "file" : "text",
388
- fileType: ve(c) ? "image" : ye(c),
389
- fileUrl: n.fileUrl || "",
390
- fileName: c,
391
- fileSize: n.fileSize || 0
403
+ text: l.msgContent,
404
+ isSelf: l.sendUsername === C,
405
+ time: l.createTime,
406
+ sendUsername: l.sendUsername,
407
+ type: d ? "file" : "text",
408
+ fileType: $e(g) ? "image" : ke(g),
409
+ fileUrl: l.fileUrl || "",
410
+ fileName: g,
411
+ fileSize: l.fileSize || 0
392
412
  };
393
- })), P = (n) => $e(n).format("HH:mm"), me = (n) => {
394
- if (!n) return "";
395
- const r = $e(), c = $e(n);
396
- return r.isSame(c, "day") ? c.format("HH:mm") : r.diff(c, "day") === 1 ? "昨天" : r.diff(c, "day") < 7 ? ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][c.day()] : c.format("MM/DD");
397
- }, ve = (n) => {
398
- if (!n) return !1;
399
- const r = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"], c = n.split(".").pop().toLowerCase();
400
- return r.includes(c);
401
- }, ye = (n) => {
402
- if (!n) return "default";
403
- const r = n.split(".").pop().toLowerCase();
404
- return ["xls", "xlsx"].includes(r) ? "excel" : ["pdf"].includes(r) ? "pdf" : ["doc", "docx"].includes(r) ? "docx" : "default";
405
- }, q = () => {
406
- Ke(() => {
407
- I.value && (I.value.scrollTop = I.value.scrollHeight);
413
+ })), be = (l) => mt(l).format("HH:mm"), Ue = (l) => {
414
+ if (!l) return "";
415
+ const d = mt(), g = mt(l);
416
+ return d.isSame(g, "day") ? g.format("HH:mm") : d.diff(g, "day") === 1 ? "昨天" : d.diff(g, "day") < 7 ? ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][g.day()] : g.format("MM/DD");
417
+ }, $e = (l) => {
418
+ if (!l) return !1;
419
+ const d = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"], g = l.split(".").pop().toLowerCase();
420
+ return d.includes(g);
421
+ }, ke = (l) => {
422
+ if (!l) return "default";
423
+ const d = l.split(".").pop().toLowerCase();
424
+ return ["xls", "xlsx"].includes(d) ? "excel" : ["pdf"].includes(d) ? "pdf" : ["doc", "docx"].includes(d) ? "docx" : "default";
425
+ }, ce = () => {
426
+ Qe(() => {
427
+ G.value && (G.value.scrollTop = G.value.scrollHeight);
408
428
  });
409
- }, $ = async () => {
429
+ }, de = async () => {
410
430
  try {
411
- const r = (await e.getFriends(o)).data || [];
412
- k.value = r, C.value = r.filter((c) => c.isChatting === 1);
413
- for (const c of C.value)
431
+ const d = (await a.getFriends(C)).data || [];
432
+ L.value = d, H.value = d.filter((g) => g.isChatting === 1);
433
+ for (const g of H.value)
414
434
  try {
415
- const te = (await e.getHistory(o, c.username)).data || [];
416
- c.unReadNum = te.filter(
417
- (Z) => Z.isRead === 0 && Z.sendUsername === c.username
435
+ const le = (await a.getHistory(C, g.username)).data || [];
436
+ g.unReadNum = le.filter(
437
+ (E) => E.isRead === 0 && E.sendUsername === g.username
418
438
  ).length;
419
439
  } catch {
420
- c.unReadNum = 0;
440
+ g.unReadNum = 0;
421
441
  }
422
- } catch (n) {
423
- console.error("[VueChatKit] 获取好友列表失败", n);
442
+ } catch (l) {
443
+ console.error("[VueChatKit] 获取好友列表失败", l);
424
444
  }
425
- }, le = async (n) => {
445
+ }, we = async (l) => {
426
446
  try {
427
- const r = await e.getHistory(o, n);
428
- V.value = r.data || [], q();
429
- } catch (r) {
430
- console.error("[VueChatKit] 获取聊天历史失败", r);
447
+ const d = await a.getHistory(C, l);
448
+ x.value = d.data || [], ce();
449
+ } catch (d) {
450
+ console.error("[VueChatKit] 获取聊天历史失败", d);
431
451
  }
432
- }, We = async (n) => {
452
+ }, Te = async (l) => {
433
453
  try {
434
- await e.setRead(o, n), $();
435
- } catch (r) {
436
- console.error("[VueChatKit] 标记已读失败", r);
454
+ await a.setRead(C, l), de();
455
+ } catch (d) {
456
+ console.error("[VueChatKit] 标记已读失败", d);
437
457
  }
438
- }, Ce = async (n) => {
439
- v.value = n.id, await le(n.id), await We(n.id), q();
440
- }, Ue = async (n, r = 1) => {
458
+ }, Me = async (l) => {
459
+ k.value = l.id, await we(l.id), await Te(l.id), ce();
460
+ }, Fe = async (l, d = 1) => {
441
461
  try {
442
- return await e.setChatStatus(o, n, r), await $(), !0;
443
- } catch (c) {
444
- return console.error("[VueChatKit] 设置聊天状态失败", c), !1;
462
+ return await a.setChatStatus(C, l, d), await de(), !0;
463
+ } catch (g) {
464
+ return console.error("[VueChatKit] 设置聊天状态失败", g), !1;
445
465
  }
446
- }, xe = () => {
447
- if (!_.value.trim() || !v.value || !a) return;
448
- if (a.send(v.value, _.value.trim(), "text")) {
449
- const r = {
450
- msgContent: _.value.trim(),
451
- sendUsername: o,
452
- receiveUsername: v.value,
466
+ }, Ie = () => {
467
+ if (!z.value.trim() || !k.value || !m) return;
468
+ if (m.send(k.value, z.value.trim(), "text")) {
469
+ const d = {
470
+ msgContent: z.value.trim(),
471
+ sendUsername: C,
472
+ receiveUsername: k.value,
453
473
  createTime: /* @__PURE__ */ new Date(),
454
474
  isRead: 0,
455
475
  type: "text"
456
476
  };
457
- V.value.push(r), _.value = "", q(), setTimeout(() => {
458
- le(v.value), $();
477
+ x.value.push(d), z.value = "", ce(), setTimeout(() => {
478
+ we(k.value), de();
459
479
  }, 300);
460
480
  }
461
- }, be = async (n) => {
462
- if (!v.value || !a) return !1;
481
+ }, xe = async (l) => {
482
+ if (!k.value || !m) return !1;
463
483
  try {
464
- const r = await e.uploadFile(n);
465
- if (r.code === 200 && r.data) {
466
- const { fileUrl: c, fileName: T } = r.data;
467
- if (a.send(
468
- v.value,
469
- T,
484
+ const d = await a.uploadFile(l);
485
+ if (d.code === 200 && d.data) {
486
+ const { fileUrl: g, fileName: A } = d.data;
487
+ if (m.send(
488
+ k.value,
489
+ A,
470
490
  "file",
471
- c,
472
- T,
473
- n.size
491
+ g,
492
+ A,
493
+ l.size
474
494
  )) {
475
- const Z = {
476
- msgContent: T,
477
- sendUsername: o,
478
- receiveUsername: v.value,
495
+ const E = {
496
+ msgContent: A,
497
+ sendUsername: C,
498
+ receiveUsername: k.value,
479
499
  createTime: /* @__PURE__ */ new Date(),
480
500
  isRead: 0,
481
501
  type: "file",
482
- fileUrl: c,
483
- fileName: T,
484
- fileSize: n.size
502
+ fileUrl: g,
503
+ fileName: A,
504
+ fileSize: l.size
485
505
  };
486
- return V.value.push(Z), q(), !0;
506
+ return x.value.push(E), ce(), !0;
487
507
  }
488
508
  }
489
509
  return !1;
490
- } catch (r) {
491
- return console.error("[VueChatKit] 发送文件失败", r), !1;
510
+ } catch (d) {
511
+ return console.error("[VueChatKit] 发送文件失败", d), !1;
492
512
  }
493
- }, _e = async (n, r) => {
494
- if (!(!v.value || !a)) {
495
- if (r && r.trim() && a.send(v.value, r.trim(), "text")) {
496
- const T = {
497
- msgContent: r.trim(),
498
- sendUsername: o,
499
- receiveUsername: v.value,
513
+ }, De = async (l, d) => {
514
+ if (!(!k.value || !m)) {
515
+ if (d && d.trim() && m.send(k.value, d.trim(), "text")) {
516
+ const A = {
517
+ msgContent: d.trim(),
518
+ sendUsername: C,
519
+ receiveUsername: k.value,
500
520
  createTime: /* @__PURE__ */ new Date(),
501
521
  isRead: 0,
502
522
  type: "text"
503
523
  };
504
- V.value.push(T);
524
+ x.value.push(A);
505
525
  }
506
- for (const c of n) {
507
- const T = c.file || c;
508
- await be(T);
526
+ for (const g of l) {
527
+ const A = g.file || g;
528
+ await xe(A);
509
529
  }
510
530
  setTimeout(() => {
511
- le(v.value), $();
531
+ we(k.value), de();
512
532
  }, 300);
513
533
  }
514
- }, Ae = (n) => {
534
+ }, Ee = (l) => {
515
535
  try {
516
536
  try {
517
- const c = JSON.parse(n);
518
- if (c.to || c.msg)
537
+ const g = JSON.parse(l);
538
+ if (g.to || g.msg)
519
539
  return {
520
- to: c.to,
521
- content: c.msg,
522
- type: c.type || "text",
523
- fileUrl: c.fileUrl || "",
524
- fileName: c.fileName || "",
525
- fileSize: c.fileSize || 0
540
+ to: g.to,
541
+ content: g.msg,
542
+ type: g.type || "text",
543
+ fileUrl: g.fileUrl || "",
544
+ fileName: g.fileName || "",
545
+ fileSize: g.fileSize || 0
526
546
  };
527
547
  } catch {
528
548
  }
529
- const r = n.match(/^\[(.+?)\]:(.+)$/);
530
- if (r)
549
+ const d = l.match(/^\[(.+?)\]:(.+)$/);
550
+ if (d)
531
551
  return {
532
- username: r[1],
533
- content: r[2],
552
+ username: d[1],
553
+ content: d[2],
534
554
  type: "text"
535
555
  };
536
- } catch (r) {
537
- console.error("[VueChatKit] 解析消息失败", r);
556
+ } catch (d) {
557
+ console.error("[VueChatKit] 解析消息失败", d);
538
558
  }
539
559
  return null;
540
- }, Se = (n) => {
541
- if (n.includes("【状态变更】")) {
542
- const c = /【状态变更】(.+?) 已(上线|下线)/, T = n.match(c);
543
- if (T) {
544
- const te = T[1], Z = T[2] === "上线", ue = k.value.find((W) => W.username === te);
545
- ue && (ue.online = Z);
560
+ }, qe = (l) => {
561
+ if (l.includes("【状态变更】")) {
562
+ const g = /【状态变更】(.+?) 已(上线|下线)/, A = l.match(g);
563
+ if (A) {
564
+ const le = A[1], E = A[2] === "上线", q = L.value.find((pe) => pe.username === le);
565
+ q && (q.online = E);
546
566
  }
547
567
  return;
548
568
  }
549
- const r = Ae(n);
550
- if (r) {
551
- if (v.value) {
569
+ const d = Ee(l);
570
+ if (d) {
571
+ const g = {
572
+ content: d.content,
573
+ username: d.username || k.value,
574
+ type: d.type || "text",
575
+ fileUrl: d.fileUrl || "",
576
+ fileName: d.fileName || "",
577
+ fileSize: d.fileSize || 0,
578
+ timestamp: /* @__PURE__ */ new Date()
579
+ };
580
+ if (k.value) {
552
581
  try {
553
- let c = {
554
- msgContent: r.content,
555
- sendUsername: r.username || v.value,
556
- receiveUsername: o,
582
+ let A = {
583
+ msgContent: d.content,
584
+ sendUsername: g.username,
585
+ receiveUsername: C,
557
586
  createTime: /* @__PURE__ */ new Date(),
558
587
  isRead: 0,
559
- type: r.type || "text",
560
- fileUrl: r.fileUrl || "",
561
- fileName: r.fileName || "",
562
- fileSize: r.fileSize || 0
588
+ type: d.type || "text",
589
+ fileUrl: d.fileUrl || "",
590
+ fileName: d.fileName || "",
591
+ fileSize: d.fileSize || 0
563
592
  };
564
- V.value.push(c), q();
565
- } catch (c) {
566
- console.error("[VueChatKit] 添加临时消息失败", c);
593
+ x.value.push(A), ce();
594
+ } catch (A) {
595
+ console.error("[VueChatKit] 添加临时消息失败", A);
567
596
  }
568
- le(v.value);
597
+ we(k.value);
569
598
  }
570
- $();
599
+ de(), t && typeof t == "function" && t(g);
571
600
  }
572
- }, Ve = () => {
573
- const n = `${y.api.websocketUrl}?userId=${o}`;
574
- a = new Lt(o, {
575
- wsUrl: n,
576
- maxReconnectAttempts: y.websocket.maxReconnectAttempts,
577
- reconnectDelay: y.websocket.reconnectDelay
578
- }), a.on("message", Se), a.connect();
579
- }, Fe = () => {
580
- a && (a.close(), a = null);
581
- }, Re = async () => {
582
- B.value = !0, Y.value = "", await Ie();
583
- }, Ie = async () => {
584
- J.value = !0;
601
+ }, We = () => {
602
+ const l = `${w.api.websocketUrl}?userId=${C}`;
603
+ m = new Et(C, {
604
+ wsUrl: l,
605
+ maxReconnectAttempts: w.websocket.maxReconnectAttempts,
606
+ reconnectDelay: w.websocket.reconnectDelay
607
+ }), m.on("message", qe), m.connect();
608
+ }, Be = () => {
609
+ m && (m.close(), m = null);
610
+ }, Ke = async () => {
611
+ fe.value = !0, oe.value = "", await ve();
612
+ }, ve = async () => {
613
+ ne.value = !0;
585
614
  try {
586
- const n = await e.getAvailableUsers(o);
587
- G.value = n?.data || [];
588
- } catch (n) {
589
- console.error("[VueChatKit] 获取可用用户失败", n);
615
+ const l = await a.getAvailableUsers(C);
616
+ Q.value = (l == null ? void 0 : l.data) || [];
617
+ } catch (l) {
618
+ console.error("[VueChatKit] 获取可用用户失败", l);
590
619
  } finally {
591
- J.value = !1;
620
+ ne.value = !1;
592
621
  }
593
- }, Le = async (n) => {
622
+ }, ee = async (l) => {
594
623
  try {
595
- await e.addFriend(o, n.username), await $(), B.value = !1;
596
- } catch (r) {
597
- console.error("[VueChatKit] 添加好友失败", r);
624
+ await a.addFriend(C, l.username), await de(), fe.value = !1;
625
+ } catch (d) {
626
+ console.error("[VueChatKit] 添加好友失败", d);
598
627
  }
599
- }, Q = async () => {
600
- ee.value = !0;
628
+ }, W = async () => {
629
+ $.value = !0;
601
630
  try {
602
- const n = await e.getApplyList(o);
603
- ae.value = n.data || [];
604
- } catch (n) {
605
- console.error("[VueChatKit] 获取好友申请列表失败", n);
631
+ const l = await a.getApplyList(C);
632
+ _e.value = l.data || [];
633
+ } catch (l) {
634
+ console.error("[VueChatKit] 获取好友申请列表失败", l);
606
635
  } finally {
607
- ee.value = !1;
636
+ $.value = !1;
608
637
  }
609
- }, ce = async (n) => {
638
+ }, F = async (l) => {
610
639
  try {
611
- await e.agreeFriend(n, o), await Q(), await $();
612
- } catch (r) {
613
- console.error("[VueChatKit] 同意好友申请失败", r);
640
+ await a.agreeFriend(l, C), await W(), await de();
641
+ } catch (d) {
642
+ console.error("[VueChatKit] 同意好友申请失败", d);
614
643
  }
615
- }, D = async () => {
644
+ }, O = async () => {
616
645
  try {
617
- const n = await e.getUserAvatar(o);
618
- n.code === 200 && n.data && (R.value = n.data);
619
- } catch (n) {
620
- console.warn("[VueChatKit] 加载头像失败", n);
646
+ const l = await a.getUserAvatar(C);
647
+ l.code === 200 && l.data && (N.value = l.data);
648
+ } catch (l) {
649
+ console.warn("[VueChatKit] 加载头像失败", l);
621
650
  }
622
- }, M = (n) => {
623
- R.value = n;
624
- }, de = async () => {
625
- z.value = !0;
651
+ }, j = (l) => {
652
+ N.value = l;
653
+ }, D = async () => {
654
+ T.value = !0;
626
655
  try {
627
- const n = await e.getUserInfo(o);
628
- n.code === 200 && n.data && (L.value = {
629
- ...L.value,
630
- ...n.data
656
+ const l = await a.getUserInfo(C);
657
+ l.code === 200 && l.data && (I.value = {
658
+ ...I.value,
659
+ ...l.data
631
660
  });
632
- } catch (n) {
633
- console.error("[VueChatKit] 获取用户信息失败", n);
661
+ } catch (l) {
662
+ console.error("[VueChatKit] 获取用户信息失败", l);
634
663
  } finally {
635
- z.value = !1;
664
+ T.value = !1;
636
665
  }
637
- }, N = async (n) => {
666
+ }, X = async (l) => {
638
667
  try {
639
- return (await e.updateUserInfo(o, n)).code === 200 ? (L.value = {
640
- ...L.value,
641
- ...n
668
+ return (await a.updateUserInfo(C, l)).code === 200 ? (I.value = {
669
+ ...I.value,
670
+ ...l
642
671
  }, !0) : !1;
643
- } catch (r) {
644
- return console.error("[VueChatKit] 更新用户信息失败", r), !1;
672
+ } catch (d) {
673
+ return console.error("[VueChatKit] 更新用户信息失败", d), !1;
645
674
  }
646
- }, K = () => {
647
- v.value = "", V.value = [], _.value = "", x.value = "";
675
+ }, ge = () => {
676
+ k.value = "", x.value = [], z.value = "", S.value = "";
648
677
  };
649
- return D(), {
678
+ return O(), {
650
679
  // 状态
651
- myUsername: o,
652
- myAvatar: R,
653
- userInfo: L,
654
- loadingUserInfo: z,
655
- friendList: k,
656
- chatList: C,
657
- filteredFriendList: U,
658
- chatMsgList: V,
659
- currentSelectName: v,
660
- searchText: x,
661
- inputText: _,
662
- messagesContainer: I,
663
- filteredUsers: g,
664
- filteredAvailableUsers: A,
665
- currentUser: E,
666
- currentMessages: ne,
667
- addFriendDialogVisible: B,
668
- addFriendSearchText: Y,
669
- availableUsers: G,
670
- loadingAvailableUsers: J,
671
- friendApplyList: ae,
672
- loadingFriendApply: ee,
680
+ myUsername: C,
681
+ myAvatar: N,
682
+ userInfo: I,
683
+ loadingUserInfo: T,
684
+ friendList: L,
685
+ chatList: H,
686
+ filteredFriendList: M,
687
+ chatMsgList: x,
688
+ currentSelectName: k,
689
+ searchText: S,
690
+ inputText: z,
691
+ messagesContainer: G,
692
+ filteredUsers: R,
693
+ filteredAvailableUsers: Z,
694
+ currentUser: he,
695
+ currentMessages: re,
696
+ addFriendDialogVisible: fe,
697
+ addFriendSearchText: oe,
698
+ availableUsers: Q,
699
+ loadingAvailableUsers: ne,
700
+ friendApplyList: _e,
701
+ loadingFriendApply: $,
673
702
  // 方法
674
- formatTime: P,
675
- formatLastTime: me,
676
- scrollToBottom: q,
677
- getFriendList: $,
678
- getChatHistory: le,
679
- setFriendToChatStatus: Ue,
680
- selectUser: Ce,
681
- sendMessage: xe,
682
- sendFile: be,
683
- sendFilesAndText: _e,
684
- initWebSocket: Ve,
685
- closeWebSocket: Fe,
686
- reset: K,
687
- openAddFriendDialog: Re,
688
- addFriend: Le,
689
- loadFriendApplyList: Q,
690
- agreeFriend: ce,
691
- updateMyAvatar: M,
692
- getUserInfo: de,
693
- updateUserInfo: N
703
+ formatTime: be,
704
+ formatLastTime: Ue,
705
+ scrollToBottom: ce,
706
+ getFriendList: de,
707
+ getChatHistory: we,
708
+ setFriendToChatStatus: Fe,
709
+ selectUser: Me,
710
+ sendMessage: Ie,
711
+ sendFile: xe,
712
+ sendFilesAndText: De,
713
+ initWebSocket: We,
714
+ closeWebSocket: Be,
715
+ reset: ge,
716
+ openAddFriendDialog: Ke,
717
+ addFriend: ee,
718
+ loadFriendApplyList: W,
719
+ agreeFriend: F,
720
+ updateMyAvatar: j,
721
+ getUserInfo: D,
722
+ updateUserInfo: X
694
723
  };
695
724
  }
696
- const Ge = (y, e) => {
697
- const a = y.__vccOpts || y;
698
- for (const [o, R] of e)
699
- a[o] = R;
725
+ const ht = (w, t) => {
726
+ const a = w.__vccOpts || w;
727
+ for (const [m, C] of t)
728
+ a[m] = C;
700
729
  return a;
701
- }, Dt = { class: "avatar-crop-container" }, Mt = ["src"], Et = { class: "crop-overlay" }, $t = { class: "crop-box" }, Kt = {
730
+ }, Wt = { class: "avatar-crop-container" }, Bt = ["src"], Kt = { class: "crop-overlay" }, Pt = { class: "crop-box" }, Nt = {
702
731
  key: 0,
703
732
  class: "crop-mask"
704
- }, Wt = { class: "zoom-controls" }, Bt = {
733
+ }, Ht = { class: "zoom-controls" }, Ot = {
705
734
  __name: "AvatarCrop",
706
735
  props: {
707
736
  modelValue: { type: Boolean, default: !1 },
708
737
  src: { type: String, default: "" }
709
738
  },
710
739
  emits: ["update:modelValue", "confirm"],
711
- setup(y, { emit: e }) {
712
- const a = y, o = e, R = oe({
740
+ setup(w, { emit: t }) {
741
+ const a = w, m = t, C = ye({
713
742
  get: () => a.modelValue,
714
- set: (g) => o("update:modelValue", g)
715
- }), L = m(""), z = m(null), k = m(null), C = m(null), V = m(1), v = m({ x: 0, y: 0 }), x = m(!1), _ = m({ x: 0, y: 0 }), I = m({ width: 0, height: 0 });
716
- mt(() => a.src, (g) => {
717
- g && (L.value = g, V.value = 1, v.value = { x: 0, y: 0 });
743
+ set: ($) => m("update:modelValue", $)
744
+ }), N = h(""), I = h(null), T = h(null), L = h(null), H = h(1), x = h({ x: 0, y: 0 }), k = h(!1), S = h({ x: 0, y: 0 }), z = h({ width: 0, height: 0 });
745
+ Dt(() => a.src, ($) => {
746
+ $ && (N.value = $, H.value = 1, x.value = { x: 0, y: 0 });
718
747
  });
719
- const B = () => {
720
- Ke(() => {
721
- if (z.value && k.value) {
722
- const g = z.value, U = k.value, A = Math.min(U.clientWidth, U.clientHeight);
723
- g.naturalWidth > g.naturalHeight ? (I.value.height = A, I.value.width = g.naturalWidth / g.naturalHeight * A) : (I.value.width = A, I.value.height = g.naturalHeight / g.naturalWidth * A), v.value = {
724
- x: (A - I.value.width) / 2,
725
- y: (A - I.value.height) / 2
748
+ const G = () => {
749
+ Qe(() => {
750
+ if (I.value && T.value) {
751
+ const $ = I.value, R = T.value, M = Math.min(R.clientWidth, R.clientHeight);
752
+ $.naturalWidth > $.naturalHeight ? (z.value.height = M, z.value.width = $.naturalWidth / $.naturalHeight * M) : (z.value.width = M, z.value.height = $.naturalHeight / $.naturalWidth * M), x.value = {
753
+ x: (M - z.value.width) / 2,
754
+ y: (M - z.value.height) / 2
726
755
  };
727
756
  }
728
757
  });
729
- }, Y = (g) => {
730
- x.value = !0;
731
- const U = g.touches ? g.touches[0].clientX : g.clientX, A = g.touches ? g.touches[0].clientY : g.clientY;
732
- _.value = { x: U - v.value.x, y: A - v.value.y }, document.addEventListener("mousemove", G), document.addEventListener("mouseup", J), document.addEventListener("touchmove", G), document.addEventListener("touchend", J);
733
- }, G = (g) => {
734
- if (!x.value) return;
735
- const U = g.touches ? g.touches[0].clientX : g.clientX, A = g.touches ? g.touches[0].clientY : g.clientY;
736
- v.value = {
737
- x: U - _.value.x,
738
- y: A - _.value.y
758
+ }, fe = ($) => {
759
+ k.value = !0;
760
+ const R = $.touches ? $.touches[0].clientX : $.clientX, M = $.touches ? $.touches[0].clientY : $.clientY;
761
+ S.value = { x: R - x.value.x, y: M - x.value.y }, document.addEventListener("mousemove", oe), document.addEventListener("mouseup", Q), document.addEventListener("touchmove", oe), document.addEventListener("touchend", Q);
762
+ }, oe = ($) => {
763
+ if (!k.value) return;
764
+ const R = $.touches ? $.touches[0].clientX : $.clientX, M = $.touches ? $.touches[0].clientY : $.clientY;
765
+ x.value = {
766
+ x: R - S.value.x,
767
+ y: M - S.value.y
739
768
  };
740
- }, J = () => {
741
- x.value = !1, document.removeEventListener("mousemove", G), document.removeEventListener("mouseup", J), document.removeEventListener("touchmove", G), document.removeEventListener("touchend", J);
742
- }, ae = () => {
743
- const g = document.createElement("canvas"), U = g.getContext("2d"), A = 200;
744
- g.width = A, g.height = A;
745
- const E = z.value, ne = C.value, P = k.value;
746
- if (E && ne && P) {
747
- const me = ne.getBoundingClientRect(), ve = P.getBoundingClientRect(), ye = (me.left - ve.left - v.value.x) / V.value, q = (me.top - ve.top - v.value.y) / V.value, $ = me.width / V.value;
748
- U.drawImage(
749
- E,
750
- ye * (E.naturalWidth / I.value.width),
751
- q * (E.naturalHeight / I.value.height),
752
- $ * (E.naturalWidth / I.value.width),
753
- $ * (E.naturalHeight / I.value.height),
769
+ }, Q = () => {
770
+ k.value = !1, document.removeEventListener("mousemove", oe), document.removeEventListener("mouseup", Q), document.removeEventListener("touchmove", oe), document.removeEventListener("touchend", Q);
771
+ }, ne = () => {
772
+ const $ = document.createElement("canvas"), R = $.getContext("2d"), M = 200;
773
+ $.width = M, $.height = M;
774
+ const Z = I.value, he = L.value, re = T.value;
775
+ if (Z && he && re) {
776
+ const be = he.getBoundingClientRect(), Ue = re.getBoundingClientRect(), $e = (be.left - Ue.left - x.value.x) / H.value, ke = (be.top - Ue.top - x.value.y) / H.value, ce = be.width / H.value;
777
+ R.drawImage(
778
+ Z,
779
+ $e * (Z.naturalWidth / z.value.width),
780
+ ke * (Z.naturalHeight / z.value.height),
781
+ ce * (Z.naturalWidth / z.value.width),
782
+ ce * (Z.naturalHeight / z.value.height),
754
783
  0,
755
784
  0,
756
- A,
757
- A
758
- ), g.toBlob((le) => {
759
- o("confirm", { file: le, url: g.toDataURL("image/png") }), R.value = !1;
785
+ M,
786
+ M
787
+ ), $.toBlob((de) => {
788
+ m("confirm", { file: de, url: $.toDataURL("image/png") }), C.value = !1;
760
789
  }, "image/png");
761
790
  }
762
- }, ee = () => {
763
- L.value = "", V.value = 1, v.value = { x: 0, y: 0 };
791
+ }, _e = () => {
792
+ N.value = "", H.value = 1, x.value = { x: 0, y: 0 };
764
793
  };
765
- return (g, U) => {
766
- const A = ie("el-slider"), E = ie("el-button"), ne = ie("el-dialog");
767
- return i(), H(ne, {
768
- modelValue: R.value,
769
- "onUpdate:modelValue": U[2] || (U[2] = (P) => R.value = P),
794
+ return ($, R) => {
795
+ const M = ie("el-slider"), Z = ie("el-button"), he = ie("el-dialog");
796
+ return n(), B(he, {
797
+ modelValue: C.value,
798
+ "onUpdate:modelValue": R[2] || (R[2] = (re) => C.value = re),
770
799
  title: "裁剪头像",
771
800
  width: "500px",
772
801
  "close-on-click-modal": !1,
773
- onClosed: ee
802
+ onClosed: _e
774
803
  }, {
775
804
  footer: b(() => [
776
- h(E, {
777
- onClick: U[1] || (U[1] = (P) => R.value = !1)
805
+ p(Z, {
806
+ onClick: R[1] || (R[1] = (re) => C.value = !1)
778
807
  }, {
779
- default: b(() => [...U[3] || (U[3] = [
780
- se("取消", -1)
808
+ default: b(() => [...R[3] || (R[3] = [
809
+ J("取消", -1)
781
810
  ])]),
782
811
  _: 1
783
812
  }),
784
- h(E, {
813
+ p(Z, {
785
814
  type: "primary",
786
- onClick: ae
815
+ onClick: ne
787
816
  }, {
788
- default: b(() => [...U[4] || (U[4] = [
789
- se("确定", -1)
817
+ default: b(() => [...R[4] || (R[4] = [
818
+ J("确定", -1)
790
819
  ])]),
791
820
  _: 1
792
821
  })
793
822
  ]),
794
823
  default: b(() => [
795
- t("div", Dt, [
796
- t("div", {
824
+ e("div", Wt, [
825
+ e("div", {
797
826
  class: "crop-area",
798
827
  ref_key: "cropAreaRef",
799
- ref: k
828
+ ref: T
800
829
  }, [
801
- t("img", {
802
- src: L.value,
830
+ e("img", {
831
+ src: N.value,
803
832
  ref_key: "imageRef",
804
- ref: z,
833
+ ref: I,
805
834
  class: "crop-image",
806
- onLoad: B,
807
- onMousedown: Y,
808
- onTouchstart: Y
809
- }, null, 40, Mt),
810
- t("div", Et, [
811
- t("div", $t, [
812
- t("div", {
835
+ onLoad: G,
836
+ onMousedown: fe,
837
+ onTouchstart: fe
838
+ }, null, 40, Bt),
839
+ e("div", Kt, [
840
+ e("div", Pt, [
841
+ e("div", {
813
842
  class: "crop-border",
814
843
  ref_key: "cropBoxRef",
815
- ref: C
844
+ ref: L
816
845
  }, null, 512)
817
846
  ])
818
847
  ]),
819
- x.value ? (i(), f("div", Kt)) : F("", !0)
848
+ k.value ? (n(), v("div", Nt)) : U("", !0)
820
849
  ], 512),
821
- t("div", Wt, [
822
- h(A, {
823
- modelValue: V.value,
824
- "onUpdate:modelValue": U[0] || (U[0] = (P) => V.value = P),
850
+ e("div", Ht, [
851
+ p(M, {
852
+ modelValue: H.value,
853
+ "onUpdate:modelValue": R[0] || (R[0] = (re) => H.value = re),
825
854
  min: 0.5,
826
855
  max: 3,
827
856
  step: 0.1,
@@ -834,966 +863,1844 @@ const Ge = (y, e) => {
834
863
  }, 8, ["modelValue"]);
835
864
  };
836
865
  }
837
- }, Nt = /* @__PURE__ */ Ge(Bt, [["__scopeId", "data-v-4e4a992b"]]), Ht = { class: "chat-container flex h-[680px] bg-white overflow-hidden" }, Pt = { class: "w-16 theme-white flex flex-col items-center gap-2 bg-gray-50 border-r" }, qt = ["src"], Ot = ["onClick"], Xt = {
866
+ }, Tt = /* @__PURE__ */ ht(Ot, [["__scopeId", "data-v-4e4a992b"]]), jt = { class: "chat-panel" }, Xt = { class: "chat-sidebar" }, Yt = ["src"], Gt = ["onClick"], Jt = {
838
867
  key: 0,
839
- class: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 rounded-full text-xs text-white flex items-center justify-center"
840
- }, Yt = { class: "w-72 bg-[#f5f5f5] border-r border-gray-200 flex flex-col" }, Gt = { class: "p-3" }, Jt = { class: "flex-1 overflow-y-auto min-h-0" }, Qt = { key: 0 }, Zt = ["onClick", "onContextmenu"], es = { class: "relative flex-shrink-0" }, ts = ["src", "alt"], ss = {
868
+ class: "sidebar-nav-badge"
869
+ }, Qt = { class: "chat-content-panel" }, Zt = { class: "chat-search-bar" }, es = { class: "chat-content-scroll" }, ts = { key: 0 }, ss = ["onClick", "onContextmenu"], as = { class: "chat-list-avatar-wrapper" }, ns = ["src", "alt"], ls = {
841
870
  key: 0,
842
- class: "absolute bottom-0 right-0 w-3 h-3 bg-green-500 rounded-full border-2 border-white"
843
- }, as = { class: "ml-3 flex-1 overflow-hidden" }, ns = { class: "flex justify-between items-center" }, ls = { class: "font-medium text-gray-800 text-sm" }, rs = { class: "text-xs text-gray-400" }, os = { class: "flex justify-between items-center mt-1" }, is = { class: "text-xs text-gray-500 truncate pr-2" }, cs = {
871
+ class: "chat-list-online-indicator"
872
+ }, is = { class: "chat-list-info" }, os = { class: "chat-list-header" }, rs = { class: "chat-list-name" }, cs = { class: "chat-list-time" }, ds = { class: "chat-list-preview" }, us = { class: "chat-list-last-msg" }, vs = {
844
873
  key: 0,
845
- class: "bg-red-500 text-white text-xs rounded-full px-1.5 py-0.5 min-w-[18px] text-center"
846
- }, ds = { key: 1 }, us = { class: "p-3" }, fs = { class: "w-11 h-11 bg-green-500 rounded-lg flex items-center justify-center" }, hs = ["onClick"], ps = { class: "relative flex-shrink-0" }, ms = ["src", "alt"], vs = { class: "ml-3" }, gs = { class: "font-medium text-gray-800 text-sm" }, ys = { key: 2 }, xs = { class: "flex items-center" }, bs = ["src", "alt"], _s = { class: "ml-3" }, ws = { class: "font-medium text-gray-800 text-sm" }, ks = { class: "flex-1 flex flex-col min-w-0 bg-white" }, Cs = {
874
+ class: "chat-list-unread"
875
+ }, ps = { key: 1 }, ms = { class: "add-friend-section" }, fs = { class: "add-friend-icon" }, hs = ["onClick"], gs = { class: "chat-list-avatar-wrapper" }, _s = ["src", "alt"], ys = { class: "chat-list-info" }, bs = { class: "chat-list-name" }, ks = { key: 2 }, ws = { class: "friend-request-info" }, Cs = ["src", "alt"], Us = { class: "friend-request-details" }, $s = { class: "friend-request-username" }, xs = { class: "chat-main-area" }, As = {
847
876
  key: 0,
848
- class: "flex-1 flex flex-col min-h-0"
849
- }, Us = { class: "flex-1 flex flex-col items-center justify-center p-8 bg-[#f5f5f5]" }, As = ["src", "alt"], Ss = { class: "text-xl font-medium text-gray-800 mb-2" }, Vs = { class: "flex items-center gap-2 mb-8" }, Fs = { class: "text-sm text-gray-500" }, Rs = {
877
+ class: "friend-profile-area"
878
+ }, Vs = ["src", "alt"], Ss = { class: "profile-name" }, Fs = { class: "profile-status" }, Is = {
850
879
  key: 1,
851
- class: "flex-1 flex flex-col min-h-0"
852
- }, Is = { class: "h-14 border-b border-gray-200 flex items-center justify-between px-4 bg-white" }, Ls = { class: "flex items-center gap-3" }, Ts = { class: "font-medium text-gray-800" }, zs = { class: "flex items-center gap-3 text-gray-500" }, js = { class: "flex-shrink-0" }, Ds = ["src"], Ms = {
880
+ class: "chat-window-area"
881
+ }, zs = { class: "chat-window-header" }, Rs = { class: "chat-window-title" }, Ls = { class: "chat-window-name" }, Ts = { class: "chat-window-actions" }, Ms = { class: "message-avatar" }, Ds = ["src"], Es = {
853
882
  key: 0,
854
- class: "text-xs text-gray-500 mb-1 ml-1"
855
- }, Es = { class: "relative group" }, $s = ["onClick"], Ks = ["src", "alt"], Ws = {
883
+ class: "message-sender-name"
884
+ }, qs = { class: "message-bubble-wrapper" }, Ws = ["onClick"], Bs = ["src", "alt"], Ks = {
856
885
  key: 0,
857
- class: "absolute left-1 bottom-0 text-white"
858
- }, Bs = ["onClick"], Ns = { class: "w-10 h-10 flex items-center justify-center rounded-lg flex-shrink-0" }, Hs = { class: "flex-1 min-w-0" }, Ps = { key: 0 }, qs = { class: "bg-white border-t border-gray-200" }, Os = {
886
+ class: "message-image-size"
887
+ }, Ps = ["onClick"], Ns = { class: "message-file-content" }, Hs = { class: "message-file-icon" }, Os = { class: "message-file-info" }, js = { class: "message-file-name" }, Xs = { class: "message-file-meta" }, Ys = { key: 0 }, Gs = { class: "chat-input-area" }, Js = {
859
888
  key: 0,
860
- class: "px-3 py-2 border-b border-gray-100 flex flex-wrap gap-2"
861
- }, Xs = {
889
+ class: "pending-files-area"
890
+ }, Qs = {
862
891
  key: 0,
863
- class: "relative w-20 h-20 rounded-lg overflow-hidden border border-gray-200"
864
- }, Ys = ["src", "alt"], Gs = ["onClick"], Js = {
892
+ class: "pending-image-wrapper"
893
+ }, Zs = ["src", "alt"], ea = ["onClick"], ta = {
865
894
  key: 1,
866
- class: "relative w-24 h-20 rounded-lg border border-gray-200 bg-gray-50 flex flex-col items-center justify-center p-1"
867
- }, Qs = { class: "text-xs text-gray-500 truncate w-full text-center px-1" }, Zs = ["onClick"], ea = {
895
+ class: "pending-file-wrapper"
896
+ }, sa = { class: "pending-file-name" }, aa = ["onClick"], na = {
868
897
  key: 1,
869
- class: "flex items-center p-3 gap-2"
870
- }, ta = { class: "px-3 pb-3" }, sa = ["onKeydown"], aa = { class: "flex justify-end px-3 pb-3" }, na = {
898
+ class: "input-toolbar"
899
+ }, la = { class: "input-textarea-wrapper" }, ia = ["onKeydown"], oa = { class: "input-send-wrapper" }, ra = {
871
900
  key: 2,
872
- class: "flex-1 flex items-center justify-center flex-col bg-[#f5f5f5]"
873
- }, la = { class: "text-gray-400" }, ra = {
901
+ class: "chat-empty-state"
902
+ }, ca = { class: "empty-state-text" }, da = {
874
903
  key: 0,
875
- class: "w-64 bg-[#f5f5f5] border-l border-gray-200 flex flex-col"
876
- }, oa = { class: "flex-1 p-4" }, ia = { class: "flex flex-col items-center" }, ca = ["src", "alt"], da = { class: "mt-3 font-medium text-gray-800 text-lg" }, ua = { class: "mb-4" }, fa = { class: "relative" }, ha = { class: "max-h-[400px] overflow-y-auto" }, pa = { class: "flex items-center" }, ma = ["src", "alt"], va = { class: "ml-3" }, ga = { class: "font-medium text-gray-800" }, ya = { class: "flex flex-col" }, xa = { class: "flex flex-col items-center mb-8 pb-6 border-b border-gray-100" }, ba = { class: "relative mb-4" }, _a = ["src"], wa = { class: "text-center" }, ka = { class: "font-semibold text-gray-800 text-xl" }, Ca = { class: "text-sm text-gray-500 mt-1" }, Ua = { class: "space-y-5" }, Aa = { class: "flex items-center justify-between mb-2" }, Sa = { class: "text-gray-700 font-semibold flex items-center gap-2" }, Va = { class: "bg-gray-50 rounded-xl p-6 space-y-5" }, Fa = {
904
+ class: "chat-detail-panel"
905
+ }, ua = { class: "chat-detail-content" }, va = { class: "chat-detail-profile" }, pa = ["src", "alt"], ma = { class: "chat-detail-name" }, fa = { class: "add-friend-search-wrapper" }, ha = { class: "add-friend-users-list" }, ga = { class: "add-friend-user-info" }, _a = ["src", "alt"], ya = { class: "add-friend-user-name" }, ba = { class: "chat-settings-container" }, ka = { class: "chat-settings-avatar-section" }, wa = { class: "chat-settings-avatar-wrapper" }, Ca = ["src"], Ua = { class: "chat-settings-user-display" }, $a = { class: "chat-settings-nickname" }, xa = { class: "chat-settings-username" }, Aa = { class: "chat-settings-form-section" }, Va = { class: "chat-settings-form-header" }, Sa = { class: "chat-settings-form-title" }, Fa = { class: "chat-settings-form" }, Ia = { class: "chat-settings-form-item" }, za = {
877
906
  key: 1,
878
- class: "text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"
879
- }, Ra = {
907
+ class: "chat-settings-form-value"
908
+ }, Ra = { class: "chat-settings-form-item" }, La = {
880
909
  key: 1,
881
- class: "text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"
882
- }, Ia = {
910
+ class: "chat-settings-form-value"
911
+ }, Ta = { class: "chat-settings-form-item" }, Ma = {
883
912
  key: 1,
884
- class: "text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"
885
- }, La = {
913
+ class: "chat-settings-form-value"
914
+ }, Da = { class: "chat-settings-form-item" }, Ea = {
886
915
  key: 1,
887
- class: "text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200 min-h-[80px]"
888
- }, Ta = {
916
+ class: "chat-settings-form-value bio-value"
917
+ }, qa = {
889
918
  key: 0,
890
- class: "flex gap-3 justify-end pt-2"
891
- }, za = {
892
- __name: "ChatWindow",
919
+ class: "chat-settings-form-actions"
920
+ }, Wa = {
921
+ __name: "ChatPanel",
893
922
  props: {
894
- modelValue: { type: Boolean, default: !1 },
895
- config: { type: Object, required: !0 },
896
- width: { type: [String, Number], default: "1100px" }
923
+ config: { type: Object, required: !0 }
897
924
  },
898
- emits: ["update:modelValue", "open", "close", "message", "send", "error"],
899
- setup(y, { emit: e }) {
900
- const a = y, o = e, R = oe({
901
- get: () => a.modelValue,
902
- set: (d) => o("update:modelValue", d)
903
- }), {
904
- myUsername: L,
905
- myAvatar: z,
906
- userInfo: k,
907
- loadingUserInfo: C,
908
- friendList: V,
909
- filteredFriendList: v,
925
+ emits: ["message", "send", "error", "init"],
926
+ setup(w, { emit: t }) {
927
+ const a = w, m = t, {
928
+ myUsername: C,
929
+ myAvatar: N,
930
+ userInfo: I,
931
+ loadingUserInfo: T,
932
+ friendList: L,
933
+ filteredFriendList: H,
910
934
  searchText: x,
911
- inputText: _,
912
- messagesContainer: I,
913
- filteredUsers: B,
914
- filteredAvailableUsers: Y,
915
- currentUser: G,
916
- currentMessages: J,
917
- addFriendDialogVisible: ae,
918
- addFriendSearchText: ee,
919
- availableUsers: g,
920
- loadingAvailableUsers: U,
921
- friendApplyList: A,
922
- loadingFriendApply: E,
923
- formatTime: ne,
924
- formatLastTime: P,
925
- scrollToBottom: me,
926
- getFriendList: ve,
927
- getChatHistory: ye,
928
- setFriendToChatStatus: q,
929
- selectUser: $,
930
- sendMessage: le,
931
- sendFile: We,
932
- sendFilesAndText: Ce,
933
- initWebSocket: Ue,
934
- closeWebSocket: xe,
935
- reset: be,
936
- openAddFriendDialog: _e,
937
- addFriend: Ae,
938
- loadFriendApplyList: Se,
939
- agreeFriend: Ve,
940
- updateMyAvatar: Fe,
941
- getUserInfo: Re,
942
- updateUserInfo: Ie
943
- } = jt(a.config), Le = oe(() => {
944
- const d = [{ id: "chat", icon: Me, badge: 0 }];
945
- return a.config.modules.friends && d.push({ id: "friends", icon: Xe, badge: 0 }), a.config.modules.apply && d.push({ id: "apply", icon: kt, badge: A.value?.length || 0 }), d;
946
- }), Q = m("chat"), ce = m(null), D = m(null), M = m(null), de = m(!1), N = m(!1), K = m({ nickname: "", email: "", phone: "", bio: "" }), n = m(!1), r = m(!1), c = m(!1), T = m(!1), te = m(null), Z = m(""), ue = m(null), W = m([]), re = m({ visible: !1, x: 0, y: 0, chat: null }), Qe = (d, l) => {
947
- d.preventDefault(), d.stopPropagation(), re.value = { visible: !0, x: d.clientX, y: d.clientY, chat: l };
948
- }, Te = () => {
949
- re.value.visible = !1;
935
+ inputText: k,
936
+ messagesContainer: S,
937
+ filteredUsers: z,
938
+ filteredAvailableUsers: G,
939
+ currentUser: fe,
940
+ currentMessages: oe,
941
+ addFriendDialogVisible: Q,
942
+ addFriendSearchText: ne,
943
+ availableUsers: _e,
944
+ loadingAvailableUsers: $,
945
+ friendApplyList: R,
946
+ loadingFriendApply: M,
947
+ formatTime: Z,
948
+ formatLastTime: he,
949
+ scrollToBottom: re,
950
+ getFriendList: be,
951
+ getChatHistory: Ue,
952
+ setFriendToChatStatus: $e,
953
+ selectUser: ke,
954
+ sendMessage: ce,
955
+ sendFile: de,
956
+ sendFilesAndText: we,
957
+ initWebSocket: Te,
958
+ closeWebSocket: Me,
959
+ reset: Fe,
960
+ openAddFriendDialog: Ie,
961
+ addFriend: xe,
962
+ loadFriendApplyList: De,
963
+ agreeFriend: Ee,
964
+ updateMyAvatar: qe,
965
+ getUserInfo: We,
966
+ updateUserInfo: Be
967
+ } = Lt(a.config, (f) => {
968
+ m("message", f);
969
+ }), Ke = ye(() => {
970
+ var r;
971
+ const f = [{ id: "chat", icon: Re, badge: 0 }];
972
+ return a.config.modules.friends && f.push({ id: "friends", icon: Ge, badge: 0 }), a.config.modules.apply && f.push({ id: "apply", icon: Ut, badge: ((r = R.value) == null ? void 0 : r.length) || 0 }), f;
973
+ }), ve = h("chat"), ee = h(null), W = h(null), F = h(null), O = h(!1), j = h(!1), D = h({ nickname: "", email: "", phone: "", bio: "" }), X = h(!1), ge = h(!1), l = h(!1), d = h(!1), g = h(null), A = h(""), le = h(null), E = h([]), q = h({ visible: !1, x: 0, y: 0, chat: null }), pe = (f, r) => {
974
+ f.preventDefault(), f.stopPropagation(), q.value = { visible: !0, x: f.clientX, y: f.clientY, chat: r };
975
+ }, Ae = () => {
976
+ q.value.visible = !1;
950
977
  }, Ze = async () => {
951
- if (!re.value.chat) return;
952
- await q(re.value.chat.id, 0) && ce.value === re.value.chat.id && (ce.value = null, D.value = null), Te();
953
- }, ze = (d) => {
954
- ce.value = d.id, D.value = d, M.value = null, de.value = !1, $({
955
- id: d.id,
956
- name: d.name,
957
- avatar: d.avatar,
958
- online: d.online
978
+ if (!q.value.chat) return;
979
+ await $e(q.value.chat.id, 0) && ee.value === q.value.chat.id && (ee.value = null, W.value = null), Ae();
980
+ }, Ve = (f) => {
981
+ ee.value = f.id, W.value = f, F.value = null, O.value = !1, ke({
982
+ id: f.id,
983
+ name: f.name,
984
+ avatar: f.avatar,
985
+ online: f.online
959
986
  });
960
- }, et = (d) => {
961
- M.value = d, ce.value = null, D.value = null;
987
+ }, et = (f) => {
988
+ F.value = f, ee.value = null, W.value = null;
962
989
  }, tt = async () => {
963
- if (!M.value) return;
964
- if (await q(M.value.id)) {
965
- Q.value = "chat", await Ke();
966
- const l = B.value.find((p) => p.id === M.value.id);
967
- l && ze(l), M.value = null;
990
+ if (!F.value) return;
991
+ if (await $e(F.value.id)) {
992
+ ve.value = "chat", await Qe();
993
+ const r = z.value.find((u) => u.id === F.value.id);
994
+ r && Ve(r), F.value = null;
968
995
  }
969
996
  }, st = () => {
970
- r.value = !0;
997
+ ge.value = !0;
971
998
  }, at = () => {
972
- te.value?.click();
999
+ var f;
1000
+ (f = g.value) == null || f.click();
973
1001
  }, nt = () => {
974
- ue.value?.click();
975
- }, lt = (d) => {
976
- const l = Array.from(d.target.files || []);
977
- if (l.length !== 0) {
978
- for (const p of l) {
979
- if (p.size > 50 * 1024 * 1024) {
980
- X.warning(`文件 ${p.name} 超过50MB,已跳过`);
1002
+ var f;
1003
+ (f = le.value) == null || f.click();
1004
+ }, lt = (f) => {
1005
+ const r = Array.from(f.target.files || []);
1006
+ if (r.length !== 0) {
1007
+ for (const u of r) {
1008
+ if (u.size > 50 * 1024 * 1024) {
1009
+ P.warning(`文件 ${u.name} 超过50MB,已跳过`);
981
1010
  continue;
982
1011
  }
983
- const S = URL.createObjectURL(p);
984
- W.value.push({
1012
+ const s = URL.createObjectURL(u);
1013
+ E.value.push({
985
1014
  id: Date.now() + Math.random(),
986
- file: p,
987
- name: p.name,
988
- size: p.size,
989
- type: p.type,
990
- previewUrl: S,
991
- isImage: p.type.startsWith("image/")
1015
+ file: u,
1016
+ name: u.name,
1017
+ size: u.size,
1018
+ type: u.type,
1019
+ previewUrl: s,
1020
+ isImage: u.type.startsWith("image/")
992
1021
  });
993
1022
  }
994
- ue.value && (ue.value.value = "");
1023
+ le.value && (le.value.value = "");
995
1024
  }
996
- }, Be = (d) => {
997
- const l = W.value[d];
998
- l.previewUrl && URL.revokeObjectURL(l.previewUrl), W.value.splice(d, 1);
999
- }, Ne = (d) => {
1000
- if (d === 0) return "0 B";
1001
- const l = 1024, p = ["B", "KB", "MB", "GB"], S = Math.floor(Math.log(d) / Math.log(l));
1002
- return parseFloat((d / Math.pow(l, S)).toFixed(2)) + " " + p[S];
1025
+ }, Pe = (f) => {
1026
+ const r = E.value[f];
1027
+ r.previewUrl && URL.revokeObjectURL(r.previewUrl), E.value.splice(f, 1);
1028
+ }, Ne = (f) => {
1029
+ if (f === 0) return "0 B";
1030
+ const r = 1024, u = ["B", "KB", "MB", "GB"], s = Math.floor(Math.log(f) / Math.log(r));
1031
+ return parseFloat((f / Math.pow(r, s)).toFixed(2)) + " " + u[s];
1003
1032
  }, He = async () => {
1004
- if (!_.value.trim() && W.value.length === 0) return;
1005
- const d = [...W.value], l = _.value;
1006
- _.value = "", W.value.forEach((p) => {
1007
- p.previewUrl && URL.revokeObjectURL(p.previewUrl);
1008
- }), W.value = [], await Ce(d, l), o("send", { text: l, files: d });
1009
- }, rt = (d) => {
1010
- const l = d.clipboardData?.items;
1011
- if (l) {
1012
- for (const p of l)
1013
- if (p.kind === "file") {
1014
- const S = p.getAsFile();
1015
- if (S) {
1016
- if (S.size > 50 * 1024 * 1024) {
1017
- X.warning(`文件 ${S.name} 超过50MB,已跳过`);
1033
+ if (!k.value.trim() && E.value.length === 0) return;
1034
+ const f = [...E.value], r = k.value;
1035
+ k.value = "", E.value.forEach((u) => {
1036
+ u.previewUrl && URL.revokeObjectURL(u.previewUrl);
1037
+ }), E.value = [], await we(f, r), m("send", { text: r, files: f });
1038
+ }, it = (f) => {
1039
+ var u;
1040
+ const r = (u = f.clipboardData) == null ? void 0 : u.items;
1041
+ if (r) {
1042
+ for (const s of r)
1043
+ if (s.kind === "file") {
1044
+ const y = s.getAsFile();
1045
+ if (y) {
1046
+ if (y.size > 50 * 1024 * 1024) {
1047
+ P.warning(`文件 ${y.name} 超过50MB,已跳过`);
1018
1048
  continue;
1019
1049
  }
1020
- const ge = URL.createObjectURL(S);
1021
- W.value.push({
1050
+ const V = URL.createObjectURL(y);
1051
+ E.value.push({
1022
1052
  id: Date.now() + Math.random(),
1023
- file: S,
1024
- name: S.name,
1025
- size: S.size,
1026
- type: S.type,
1027
- previewUrl: ge,
1028
- isImage: S.type.startsWith("image/")
1053
+ file: y,
1054
+ name: y.name,
1055
+ size: y.size,
1056
+ type: y.type,
1057
+ previewUrl: V,
1058
+ isImage: y.type.startsWith("image/")
1029
1059
  });
1030
1060
  }
1031
1061
  }
1032
1062
  }
1033
- }, Pe = (d) => {
1034
- if (!d) {
1035
- X.warning("文件地址无效");
1063
+ }, Oe = (f) => {
1064
+ if (!f) {
1065
+ P.warning("文件地址无效");
1036
1066
  return;
1037
1067
  }
1038
- window.open(d, "_blank");
1039
- }, ot = (d) => {
1040
- console.warn("图片加载失败", d);
1041
- }, it = (d) => {
1042
- const l = d.target.files[0];
1043
- if (!l) return;
1044
- if (!l.type.startsWith("image/")) {
1045
- X.error("只能上传图片文件");
1068
+ window.open(f, "_blank");
1069
+ }, ot = (f) => {
1070
+ console.warn("图片加载失败", f);
1071
+ }, rt = (f) => {
1072
+ const r = f.target.files[0];
1073
+ if (!r) return;
1074
+ if (!r.type.startsWith("image/")) {
1075
+ P.error("只能上传图片文件");
1046
1076
  return;
1047
1077
  }
1048
- if (l.size > 5 * 1024 * 1024) {
1049
- X.error("图片大小不能超过 5MB");
1078
+ if (r.size > 5 * 1024 * 1024) {
1079
+ P.error("图片大小不能超过 5MB");
1050
1080
  return;
1051
1081
  }
1052
- const p = new FileReader();
1053
- p.onload = (S) => {
1054
- Z.value = S.target.result, c.value = !0;
1055
- }, p.readAsDataURL(l);
1056
- }, ct = async ({ file: d }) => {
1057
- if (d) {
1058
- T.value = !0;
1082
+ const u = new FileReader();
1083
+ u.onload = (s) => {
1084
+ A.value = s.target.result, l.value = !0;
1085
+ }, u.readAsDataURL(r);
1086
+ }, ct = async ({ file: f }) => {
1087
+ if (f) {
1088
+ d.value = !0;
1059
1089
  try {
1060
- const p = await new (require("../core/api.js")).ChatApi(a.config).uploadAvatar(d, L);
1061
- p.code === 200 ? (X.success("头像上传成功"), Fe(p.data), qe()) : X.error(p.msg || "头像上传失败");
1062
- } catch (l) {
1063
- console.error(l), X.error("头像上传失败");
1090
+ const { ChatApi: r } = await Promise.resolve().then(() => Rt), s = await new r(a.config).uploadAvatar(f, C);
1091
+ s.code === 200 ? (P.success("头像上传成功"), qe(s.data), je()) : P.error(s.msg || "头像上传失败");
1092
+ } catch (r) {
1093
+ console.error(r), P.error("头像上传失败");
1064
1094
  } finally {
1065
- T.value = !1;
1095
+ d.value = !1;
1066
1096
  }
1067
1097
  }
1068
- }, qe = () => {
1069
- Z.value = "", c.value = !1, te.value && (te.value.value = "");
1098
+ }, je = () => {
1099
+ A.value = "", l.value = !1, g.value && (g.value.value = "");
1070
1100
  }, dt = () => {
1071
- K.value = {
1072
- nickname: k.value.nickname || "",
1073
- email: k.value.email || "",
1074
- phone: k.value.phone || "",
1075
- bio: k.value.bio || ""
1076
- }, N.value = !0;
1101
+ D.value = {
1102
+ nickname: I.value.nickname || "",
1103
+ email: I.value.email || "",
1104
+ phone: I.value.phone || "",
1105
+ bio: I.value.bio || ""
1106
+ }, j.value = !0;
1077
1107
  }, ut = () => {
1078
- N.value = !1, K.value = { nickname: "", email: "", phone: "", bio: "" };
1079
- }, ft = async () => {
1080
- n.value = !0;
1108
+ j.value = !1, D.value = { nickname: "", email: "", phone: "", bio: "" };
1109
+ }, vt = async () => {
1110
+ X.value = !0;
1081
1111
  try {
1082
- await Ie(K.value) ? (X.success("保存成功"), N.value = !1) : X.error("保存失败");
1083
- } catch (d) {
1084
- console.error(d), X.error("保存失败");
1112
+ await Be(D.value) ? (P.success("保存成功"), j.value = !1) : P.error("保存失败");
1113
+ } catch (f) {
1114
+ console.error(f), P.error("保存失败");
1085
1115
  } finally {
1086
- n.value = !1;
1116
+ X.value = !1;
1087
1117
  }
1088
- }, ht = () => {
1089
- be(), xe(), de.value = !1, r.value = !1, qe(), N.value = !1, o("close");
1090
- }, pt = async () => {
1091
- await Promise.all([ve(), Se(), Re()]), Ue(), B.value.length > 0 && ze(B.value[0]), o("open");
1092
1118
  };
1093
- return vt(() => {
1094
- document.addEventListener("click", Te);
1095
- }), gt(() => {
1096
- document.removeEventListener("click", Te), xe();
1097
- }), (d, l) => {
1098
- const p = ie("el-icon"), S = ie("el-input"), ge = ie("el-empty"), fe = ie("el-button"), je = ie("el-dialog");
1099
- return i(), H(je, {
1100
- modelValue: R.value,
1101
- "onUpdate:modelValue": l[13] || (l[13] = (s) => R.value = s),
1102
- width: y.width,
1103
- "close-on-click-modal": !1,
1104
- class: "chat-dialog",
1105
- "append-to-body": "",
1106
- onClosed: ht,
1107
- onOpen: pt
1108
- }, {
1109
- default: b(() => [
1110
- t("div", Ht, [
1111
- t("div", Pt, [
1112
- t("div", {
1113
- class: "mb-4 cursor-pointer mt-4",
1114
- onClick: st
1115
- }, [
1116
- t("img", {
1117
- src: u(z),
1118
- alt: "头像",
1119
- class: "w-10 h-10 rounded-full border-2 border-gray-200"
1120
- }, null, 8, qt)
1119
+ return gt(async () => {
1120
+ await Promise.all([be(), De(), We()]), Te(), z.value.length > 0 && Ve(z.value[0]), m("init"), document.addEventListener("click", Ae);
1121
+ }), _t(() => {
1122
+ Fe(), Me(), document.removeEventListener("click", Ae);
1123
+ }), (f, r) => {
1124
+ var ue, ze, Se;
1125
+ const u = ie("el-icon"), s = ie("el-input"), y = ie("el-empty"), V = ie("el-button"), Y = ie("el-dialog");
1126
+ return n(), v("div", jt, [
1127
+ e("div", Xt, [
1128
+ e("div", {
1129
+ class: "sidebar-avatar",
1130
+ onClick: st
1131
+ }, [
1132
+ e("img", {
1133
+ src: c(N),
1134
+ alt: "头像",
1135
+ class: "sidebar-avatar-img"
1136
+ }, null, 8, Yt)
1137
+ ]),
1138
+ (n(!0), v(se, null, ae(Ke.value, (o) => (n(), v("div", {
1139
+ key: o.id,
1140
+ class: K([
1141
+ "sidebar-nav-item",
1142
+ ve.value === o.id ? "sidebar-nav-item-active" : "sidebar-nav-item-inactive"
1143
+ ]),
1144
+ onClick: (te) => ve.value = o.id
1145
+ }, [
1146
+ p(u, { size: 24 }, {
1147
+ default: b(() => [
1148
+ (n(), B(yt(o.icon)))
1121
1149
  ]),
1122
- (i(!0), f(he, null, pe(Le.value, (s) => (i(), f("div", {
1123
- key: s.id,
1124
- class: j([
1125
- "w-10 h-10 flex items-center justify-center cursor-pointer rounded-lg transition-all relative",
1126
- Q.value === s.id ? "bg-green-50 text-green-600" : "text-gray-500 hover:bg-gray-100"
1150
+ _: 2
1151
+ }, 1024),
1152
+ o.badge ? (n(), v("span", Jt, _(o.badge > 99 ? "99+" : o.badge), 1)) : U("", !0)
1153
+ ], 10, Gt))), 128)),
1154
+ r[13] || (r[13] = e("div", { class: "sidebar-spacer" }, null, -1)),
1155
+ w.config.modules.settings ? (n(), v("div", {
1156
+ key: 0,
1157
+ class: "sidebar-nav-item sidebar-nav-item-inactive",
1158
+ onClick: r[0] || (r[0] = (o) => ge.value = !0),
1159
+ title: "设置"
1160
+ }, [
1161
+ p(u, { size: 24 }, {
1162
+ default: b(() => [
1163
+ p(c($t))
1164
+ ]),
1165
+ _: 1
1166
+ })
1167
+ ])) : U("", !0)
1168
+ ]),
1169
+ e("div", Qt, [
1170
+ e("div", Zt, [
1171
+ p(s, {
1172
+ modelValue: c(x),
1173
+ "onUpdate:modelValue": r[1] || (r[1] = (o) => Ce(x) ? x.value = o : null),
1174
+ placeholder: "搜索",
1175
+ "prefix-icon": c(Le),
1176
+ class: "chat-search-input"
1177
+ }, null, 8, ["modelValue", "prefix-icon"])
1178
+ ]),
1179
+ e("div", es, [
1180
+ ve.value === "chat" ? (n(), v("div", ts, [
1181
+ (n(!0), v(se, null, ae(c(z), (o) => (n(), v("div", {
1182
+ key: o.id,
1183
+ class: K([
1184
+ "chat-list-item",
1185
+ ee.value === o.id ? "chat-list-item-active" : ""
1127
1186
  ]),
1128
- onClick: (O) => Q.value = s.id
1187
+ onClick: (te) => Ve(o),
1188
+ onContextmenu: Ye((te) => pe(te, o), ["prevent", "stop"])
1129
1189
  }, [
1130
- h(p, { size: 24 }, {
1131
- default: b(() => [
1132
- (i(), H(yt(s.icon)))
1190
+ e("div", as, [
1191
+ e("img", {
1192
+ src: o.avatar,
1193
+ alt: o.name,
1194
+ class: "chat-list-avatar"
1195
+ }, null, 8, ns),
1196
+ o.online ? (n(), v("span", ls)) : U("", !0)
1197
+ ]),
1198
+ e("div", is, [
1199
+ e("div", os, [
1200
+ e("span", rs, _(o.name), 1),
1201
+ e("span", cs, _(c(he)(o.lastTime)), 1)
1133
1202
  ]),
1134
- _: 2
1135
- }, 1024),
1136
- s.badge ? (i(), f("span", Xt, w(s.badge > 99 ? "99+" : s.badge), 1)) : F("", !0)
1137
- ], 10, Ot))), 128)),
1138
- l[14] || (l[14] = t("div", { class: "flex-1" }, null, -1)),
1139
- y.config.modules.settings ? (i(), f("div", {
1203
+ e("div", ds, [
1204
+ e("span", us, _(o.lastMsg), 1),
1205
+ o.unread > 0 ? (n(), v("span", vs, _(o.unread > 99 ? "99+" : o.unread), 1)) : U("", !0)
1206
+ ])
1207
+ ])
1208
+ ], 42, ss))), 128))
1209
+ ])) : U("", !0),
1210
+ ve.value === "friends" && w.config.modules.friends ? (n(), v("div", ps, [
1211
+ e("div", ms, [
1212
+ e("div", {
1213
+ class: "add-friend-btn",
1214
+ onClick: r[2] || (r[2] = (...o) => c(Ie) && c(Ie)(...o))
1215
+ }, [
1216
+ e("div", fs, [
1217
+ p(u, {
1218
+ class: "text-white",
1219
+ size: 20
1220
+ }, {
1221
+ default: b(() => [
1222
+ p(c(xt))
1223
+ ]),
1224
+ _: 1
1225
+ })
1226
+ ]),
1227
+ r[14] || (r[14] = e("span", { class: "add-friend-text" }, "添加好友", -1))
1228
+ ])
1229
+ ]),
1230
+ (n(!0), v(se, null, ae(c(H), (o) => (n(), v("div", {
1231
+ key: o.id,
1232
+ class: "chat-list-item",
1233
+ onClick: (te) => et(o)
1234
+ }, [
1235
+ e("div", gs, [
1236
+ e("img", {
1237
+ src: o.avatar,
1238
+ alt: o.name,
1239
+ class: "chat-list-avatar"
1240
+ }, null, 8, _s),
1241
+ e("span", {
1242
+ class: K([
1243
+ "chat-list-online-indicator",
1244
+ o.online ? "chat-list-online" : "chat-list-offline"
1245
+ ])
1246
+ }, null, 2)
1247
+ ]),
1248
+ e("div", ys, [
1249
+ e("span", bs, _(o.name), 1)
1250
+ ])
1251
+ ], 8, hs))), 128))
1252
+ ])) : U("", !0),
1253
+ ve.value === "apply" && w.config.modules.apply ? (n(), v("div", ks, [
1254
+ c(M) ? (n(), B(y, {
1140
1255
  key: 0,
1141
- class: "w-10 h-10 flex items-center justify-center cursor-pointer rounded-lg hover:bg-gray-100 transition-all mb-4 text-gray-500",
1142
- onClick: l[0] || (l[0] = (s) => r.value = !0),
1143
- title: "设置"
1256
+ description: "加载中..."
1257
+ })) : c(R).length === 0 ? (n(), B(y, {
1258
+ key: 1,
1259
+ description: "暂无好友申请"
1260
+ })) : (n(!0), v(se, { key: 2 }, ae(c(R), (o) => (n(), v("div", {
1261
+ key: o.applyUser || o.id,
1262
+ class: "friend-request-item"
1144
1263
  }, [
1145
- h(p, { size: 24 }, {
1264
+ e("div", ws, [
1265
+ e("img", {
1266
+ src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${o.applyUser}`,
1267
+ alt: o.applyUser,
1268
+ class: "friend-request-avatar"
1269
+ }, null, 8, Cs),
1270
+ e("div", Us, [
1271
+ e("div", $s, _(o.applyUser), 1),
1272
+ r[15] || (r[15] = e("div", { class: "friend-request-desc" }, "请求添加你为好友", -1))
1273
+ ])
1274
+ ]),
1275
+ p(V, {
1276
+ type: "primary",
1277
+ size: "small",
1278
+ onClick: (te) => c(Ee)(o.applyUser)
1279
+ }, {
1280
+ default: b(() => [...r[16] || (r[16] = [
1281
+ J("同意", -1)
1282
+ ])]),
1283
+ _: 1
1284
+ }, 8, ["onClick"])
1285
+ ]))), 128))
1286
+ ])) : U("", !0)
1287
+ ])
1288
+ ]),
1289
+ e("div", xs, [
1290
+ F.value && !W.value ? (n(), v("div", As, [
1291
+ e("img", {
1292
+ src: F.value.avatar,
1293
+ alt: F.value.name,
1294
+ class: "profile-avatar"
1295
+ }, null, 8, Vs),
1296
+ e("div", Ss, _(F.value.name), 1),
1297
+ e("div", Fs, [
1298
+ e("span", {
1299
+ class: K([
1300
+ "profile-status-dot",
1301
+ F.value.online ? "profile-status-online" : "profile-status-offline"
1302
+ ])
1303
+ }, null, 2),
1304
+ e("span", null, _(F.value.online ? "在线" : "离线"), 1)
1305
+ ]),
1306
+ p(V, {
1307
+ type: "primary",
1308
+ size: "large",
1309
+ onClick: tt,
1310
+ class: "profile-start-chat-btn"
1311
+ }, {
1312
+ default: b(() => [
1313
+ p(u, null, {
1314
+ default: b(() => [
1315
+ p(c(Re))
1316
+ ]),
1317
+ _: 1
1318
+ }),
1319
+ r[17] || (r[17] = e("span", null, "发消息", -1))
1320
+ ]),
1321
+ _: 1
1322
+ })
1323
+ ])) : U("", !0),
1324
+ W.value ? (n(), v("div", Is, [
1325
+ e("div", zs, [
1326
+ e("div", Rs, [
1327
+ e("span", Ls, _(W.value.name), 1),
1328
+ e("span", {
1329
+ class: K([
1330
+ "chat-window-status",
1331
+ W.value.online ? "chat-window-status-online" : "chat-window-status-offline"
1332
+ ])
1333
+ }, _(W.value.online ? "在线" : "离线"), 3)
1334
+ ]),
1335
+ e("div", Ts, [
1336
+ p(u, { class: "chat-action-icon" }, {
1337
+ default: b(() => [
1338
+ p(c(Le))
1339
+ ]),
1340
+ _: 1
1341
+ }),
1342
+ p(u, {
1343
+ class: "chat-action-icon",
1344
+ onClick: r[3] || (r[3] = (o) => O.value = !O.value)
1345
+ }, {
1146
1346
  default: b(() => [
1147
- h(u(Ct))
1347
+ p(c(At))
1148
1348
  ]),
1149
1349
  _: 1
1150
1350
  })
1151
- ])) : F("", !0)
1351
+ ])
1152
1352
  ]),
1153
- t("div", Yt, [
1154
- t("div", Gt, [
1155
- h(S, {
1156
- modelValue: u(x),
1157
- "onUpdate:modelValue": l[1] || (l[1] = (s) => we(x) ? x.value = s : null),
1158
- placeholder: "搜索",
1159
- "prefix-icon": u(Ee)
1160
- }, null, 8, ["modelValue", "prefix-icon"])
1161
- ]),
1162
- t("div", Jt, [
1163
- Q.value === "chat" ? (i(), f("div", Qt, [
1164
- (i(!0), f(he, null, pe(u(B), (s) => (i(), f("div", {
1165
- key: s.id,
1166
- class: j([
1167
- "flex items-center p-3 cursor-pointer hover:bg-[#e5e5e5] transition-colors",
1168
- ce.value === s.id ? "bg-[#d6d6d6]" : ""
1169
- ]),
1170
- onClick: (O) => ze(s),
1171
- onContextmenu: Oe((O) => Qe(O, s), ["prevent", "stop"])
1172
- }, [
1173
- t("div", es, [
1174
- t("img", {
1175
- src: s.avatar,
1176
- alt: s.name,
1177
- class: "w-11 h-11 rounded-full object-cover"
1178
- }, null, 8, ts),
1179
- s.online ? (i(), f("span", ss)) : F("", !0)
1180
- ]),
1181
- t("div", as, [
1182
- t("div", ns, [
1183
- t("span", ls, w(s.name), 1),
1184
- t("span", rs, w(u(P)(s.lastTime)), 1)
1185
- ]),
1186
- t("div", os, [
1187
- t("span", is, w(s.lastMsg), 1),
1188
- s.unread > 0 ? (i(), f("span", cs, w(s.unread > 99 ? "99+" : s.unread), 1)) : F("", !0)
1353
+ e("div", {
1354
+ ref_key: "messagesContainer",
1355
+ ref: S,
1356
+ class: "chat-messages-container"
1357
+ }, [
1358
+ (n(!0), v(se, null, ae(c(oe), (o, te) => (n(), v("div", {
1359
+ key: te,
1360
+ class: K([
1361
+ "message-wrapper",
1362
+ o.isSelf ? "message-self" : "message-other"
1363
+ ])
1364
+ }, [
1365
+ e("div", Ms, [
1366
+ e("img", {
1367
+ src: o.isSelf ? c(N) : W.value.avatar,
1368
+ class: "message-avatar-img"
1369
+ }, null, 8, Ds)
1370
+ ]),
1371
+ e("div", {
1372
+ class: K([
1373
+ "message-content",
1374
+ o.isSelf ? "message-content-self" : "message-content-other"
1375
+ ])
1376
+ }, [
1377
+ o.isSelf ? U("", !0) : (n(), v("div", Es, _(W.value.name), 1)),
1378
+ e("div", qs, [
1379
+ o.type === "text" ? (n(), v("div", {
1380
+ key: 0,
1381
+ class: K([
1382
+ "message-bubble",
1383
+ o.isSelf ? "message-bubble-self" : "message-bubble-other"
1189
1384
  ])
1190
- ])
1191
- ], 42, Zt))), 128))
1192
- ])) : F("", !0),
1193
- Q.value === "friends" && y.config.modules.friends ? (i(), f("div", ds, [
1194
- t("div", us, [
1195
- t("div", {
1196
- class: "flex items-center gap-2 p-2 rounded-lg cursor-pointer hover:bg-[#e5e5e5]",
1197
- onClick: l[2] || (l[2] = (...s) => u(_e) && u(_e)(...s))
1385
+ }, _(o.text), 3)) : o.type === "file" && o.fileType === "image" ? (n(), v("div", {
1386
+ key: 1,
1387
+ class: K([
1388
+ "message-bubble",
1389
+ "message-image-bubble",
1390
+ o.isSelf ? "message-bubble-self" : "message-bubble-other"
1391
+ ]),
1392
+ onClick: (i) => Oe(o.fileUrl)
1198
1393
  }, [
1199
- t("div", fs, [
1200
- h(p, {
1201
- class: "text-white",
1202
- size: 20
1203
- }, {
1204
- default: b(() => [
1205
- h(u(Ut))
1206
- ]),
1207
- _: 1
1208
- })
1394
+ e("img", {
1395
+ src: o.fileUrl,
1396
+ alt: o.fileName,
1397
+ class: "message-image",
1398
+ onError: ot
1399
+ }, null, 40, Bs),
1400
+ o.fileSize ? (n(), v("div", Ks, _(Ne(o.fileSize)), 1)) : U("", !0)
1401
+ ], 10, Ws)) : o.type === "file" ? (n(), v("div", {
1402
+ key: 2,
1403
+ class: K([
1404
+ "message-bubble",
1405
+ "message-file-bubble",
1406
+ o.isSelf ? "message-bubble-self" : "message-bubble-other"
1209
1407
  ]),
1210
- l[15] || (l[15] = t("span", { class: "text-sm text-gray-800" }, "添加好友", -1))
1211
- ])
1212
- ]),
1213
- (i(!0), f(he, null, pe(u(v), (s) => (i(), f("div", {
1214
- key: s.id,
1215
- class: "flex items-center p-3 cursor-pointer hover:bg-[#e5e5e5] transition-colors",
1216
- onClick: (O) => et(s)
1217
- }, [
1218
- t("div", ps, [
1219
- t("img", {
1220
- src: s.avatar,
1221
- alt: s.name,
1222
- class: "w-11 h-11 rounded-full object-cover"
1223
- }, null, 8, ms),
1224
- t("span", {
1225
- class: j([
1226
- "absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-white",
1227
- s.online ? "bg-green-500" : "bg-gray-400"
1408
+ onClick: (i) => Oe(o.fileUrl)
1409
+ }, [
1410
+ e("div", Ns, [
1411
+ e("div", Hs, [
1412
+ p(u, { size: 28 }, {
1413
+ default: b(() => [
1414
+ p(c(Vt))
1415
+ ]),
1416
+ _: 1
1417
+ })
1418
+ ]),
1419
+ e("div", Os, [
1420
+ e("div", js, _(o.fileName || o.text), 1),
1421
+ e("div", Xs, [
1422
+ p(u, { size: 12 }, {
1423
+ default: b(() => [
1424
+ p(c(St))
1425
+ ]),
1426
+ _: 1
1427
+ }),
1428
+ r[18] || (r[18] = e("span", null, "点击下载", -1)),
1429
+ o.fileSize ? (n(), v("span", Ys, "· " + _(Ne(o.fileSize)), 1)) : U("", !0)
1430
+ ])
1228
1431
  ])
1229
- }, null, 2)
1230
- ]),
1231
- t("div", vs, [
1232
- t("span", gs, w(s.name), 1)
1233
- ])
1234
- ], 8, hs))), 128))
1235
- ])) : F("", !0),
1236
- Q.value === "apply" && y.config.modules.apply ? (i(), f("div", ys, [
1237
- u(E) ? (i(), H(ge, {
1238
- key: 0,
1239
- description: "加载中..."
1240
- })) : u(A).length === 0 ? (i(), H(ge, {
1241
- key: 1,
1242
- description: "暂无好友申请"
1243
- })) : (i(!0), f(he, { key: 2 }, pe(u(A), (s) => (i(), f("div", {
1244
- key: s.applyUser || s.id,
1245
- class: "flex items-center justify-between p-3 hover:bg-[#e5e5e5]"
1246
- }, [
1247
- t("div", xs, [
1248
- t("img", {
1249
- src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${s.applyUser}`,
1250
- alt: s.applyUser,
1251
- class: "w-11 h-11 rounded-full object-cover"
1252
- }, null, 8, bs),
1253
- t("div", _s, [
1254
- t("div", ws, w(s.applyUser), 1),
1255
- l[16] || (l[16] = t("div", { class: "text-xs text-gray-500 mt-1" }, "请求添加你为好友", -1))
1256
- ])
1257
- ]),
1258
- h(fe, {
1259
- type: "primary",
1260
- size: "small",
1261
- onClick: (O) => u(Ve)(s.applyUser)
1262
- }, {
1263
- default: b(() => [...l[17] || (l[17] = [
1264
- se("同意", -1)
1265
- ])]),
1266
- _: 1
1267
- }, 8, ["onClick"])
1268
- ]))), 128))
1269
- ])) : F("", !0)
1270
- ])
1271
- ]),
1272
- t("div", ks, [
1273
- M.value && !D.value ? (i(), f("div", Cs, [
1274
- t("div", Us, [
1275
- t("img", {
1276
- src: M.value.avatar,
1277
- alt: M.value.name,
1278
- class: "w-24 h-24 rounded-full object-cover mb-6"
1279
- }, null, 8, As),
1280
- t("div", Ss, w(M.value.name), 1),
1281
- t("div", Vs, [
1282
- t("span", {
1283
- class: j([
1284
- "w-2 h-2 rounded-full",
1285
- M.value.online ? "bg-green-500" : "bg-gray-400"
1286
1432
  ])
1287
- }, null, 2),
1288
- t("span", Fs, w(M.value.online ? "在线" : "离线"), 1)
1289
- ]),
1290
- h(fe, {
1291
- type: "primary",
1292
- size: "large",
1293
- onClick: tt,
1294
- class: "w-40"
1295
- }, {
1296
- default: b(() => [
1297
- h(p, null, {
1298
- default: b(() => [
1299
- h(u(Me))
1300
- ]),
1301
- _: 1
1302
- }),
1303
- l[18] || (l[18] = t("span", null, "发消息", -1))
1304
- ]),
1305
- _: 1
1306
- })
1307
- ])
1308
- ])) : F("", !0),
1309
- D.value ? (i(), f("div", Rs, [
1310
- t("div", Is, [
1311
- t("div", Ls, [
1312
- t("span", Ts, w(D.value.name), 1),
1313
- t("span", {
1314
- class: j([
1315
- "text-xs px-2 py-0.5 rounded",
1316
- D.value.online ? "bg-green-100 text-green-600" : "bg-gray-100 text-gray-500"
1433
+ ], 10, Ps)) : U("", !0),
1434
+ e("div", {
1435
+ class: K([
1436
+ "message-time",
1437
+ o.isSelf ? "message-time-right" : "message-time-left"
1317
1438
  ])
1318
- }, w(D.value.online ? "在线" : "离线"), 3)
1319
- ]),
1320
- t("div", zs, [
1321
- h(p, { class: "cursor-pointer hover:text-gray-700" }, {
1439
+ }, _(c(Z)(o.time)), 3)
1440
+ ])
1441
+ ], 2)
1442
+ ], 2))), 128))
1443
+ ], 512),
1444
+ e("div", Gs, [
1445
+ E.value.length > 0 ? (n(), v("div", Js, [
1446
+ (n(!0), v(se, null, ae(E.value, (o, te) => (n(), v("div", {
1447
+ key: o.id,
1448
+ class: "pending-file-item"
1449
+ }, [
1450
+ o.isImage ? (n(), v("div", Qs, [
1451
+ e("img", {
1452
+ src: o.previewUrl,
1453
+ alt: o.name,
1454
+ class: "pending-image"
1455
+ }, null, 8, Zs),
1456
+ e("button", {
1457
+ onClick: (i) => Pe(te),
1458
+ class: "pending-file-remove-btn"
1459
+ }, " × ", 8, ea)
1460
+ ])) : (n(), v("div", ta, [
1461
+ p(u, { class: "pending-file-icon" }, {
1322
1462
  default: b(() => [
1323
- h(u(Ee))
1463
+ p(c(Je))
1324
1464
  ]),
1325
1465
  _: 1
1326
1466
  }),
1327
- h(p, {
1328
- class: "cursor-pointer hover:text-gray-700",
1329
- onClick: l[3] || (l[3] = (s) => de.value = !de.value)
1467
+ e("span", sa, _(o.name), 1),
1468
+ e("button", {
1469
+ onClick: (i) => Pe(te),
1470
+ class: "pending-file-remove-btn"
1471
+ }, " × ", 8, aa)
1472
+ ]))
1473
+ ]))), 128))
1474
+ ])) : U("", !0),
1475
+ w.config.modules.fileUpload ? (n(), v("div", na, [
1476
+ p(u, { class: "input-toolbar-icon" }, {
1477
+ default: b(() => [
1478
+ p(c(Re))
1479
+ ]),
1480
+ _: 1
1481
+ }),
1482
+ p(u, {
1483
+ class: "input-toolbar-icon",
1484
+ onClick: nt
1485
+ }, {
1486
+ default: b(() => [
1487
+ p(c(Je))
1488
+ ]),
1489
+ _: 1
1490
+ }),
1491
+ p(u, { class: "input-toolbar-icon" }, {
1492
+ default: b(() => [
1493
+ p(c(Ft))
1494
+ ]),
1495
+ _: 1
1496
+ })
1497
+ ])) : U("", !0),
1498
+ e("div", la, [
1499
+ bt(e("textarea", {
1500
+ "onUpdate:modelValue": r[4] || (r[4] = (o) => Ce(k) ? k.value = o : null),
1501
+ onKeydown: kt(Ye(He, ["prevent"]), ["enter"]),
1502
+ onPaste: it,
1503
+ placeholder: "输入消息或粘贴文件...",
1504
+ class: "message-input-textarea",
1505
+ rows: "3"
1506
+ }, null, 40, ia), [
1507
+ [wt, c(k)]
1508
+ ])
1509
+ ]),
1510
+ e("div", oa, [
1511
+ p(V, {
1512
+ type: "primary",
1513
+ disabled: !c(k).trim() && E.value.length === 0,
1514
+ onClick: He,
1515
+ class: "send-message-btn"
1516
+ }, {
1517
+ default: b(() => [...r[19] || (r[19] = [
1518
+ J(" 发送 ", -1)
1519
+ ])]),
1520
+ _: 1
1521
+ }, 8, ["disabled"])
1522
+ ]),
1523
+ e("input", {
1524
+ ref_key: "fileInputRef",
1525
+ ref: le,
1526
+ type: "file",
1527
+ multiple: "",
1528
+ class: "hidden-file-input",
1529
+ onChange: lt
1530
+ }, null, 544)
1531
+ ])
1532
+ ])) : F.value ? U("", !0) : (n(), v("div", ra, [
1533
+ p(u, {
1534
+ size: 64,
1535
+ class: "empty-state-icon"
1536
+ }, {
1537
+ default: b(() => [
1538
+ p(c(It))
1539
+ ]),
1540
+ _: 1
1541
+ }),
1542
+ e("div", ca, _(ve.value === "apply" ? "在左侧选择好友申请" : "在左侧选择好友开始聊天"), 1)
1543
+ ]))
1544
+ ]),
1545
+ O.value ? (n(), v("div", da, [
1546
+ r[21] || (r[21] = e("div", { class: "chat-detail-header" }, "聊天详情", -1)),
1547
+ e("div", ua, [
1548
+ e("div", va, [
1549
+ e("img", {
1550
+ src: (ue = W.value) == null ? void 0 : ue.avatar,
1551
+ alt: (ze = W.value) == null ? void 0 : ze.name,
1552
+ class: "chat-detail-avatar"
1553
+ }, null, 8, pa),
1554
+ e("div", ma, _((Se = W.value) == null ? void 0 : Se.name), 1),
1555
+ r[20] || (r[20] = e("div", { class: "chat-detail-actions" }, [
1556
+ e("div", { class: "chat-detail-action-item" }, "查找聊天记录"),
1557
+ e("div", { class: "chat-detail-action-item" }, "清空聊天记录")
1558
+ ], -1))
1559
+ ])
1560
+ ])
1561
+ ])) : U("", !0),
1562
+ p(Y, {
1563
+ modelValue: c(Q),
1564
+ "onUpdate:modelValue": r[6] || (r[6] = (o) => Ce(Q) ? Q.value = o : null),
1565
+ title: "添加好友",
1566
+ width: "500px",
1567
+ "append-to-body": ""
1568
+ }, {
1569
+ default: b(() => [
1570
+ e("div", fa, [
1571
+ p(s, {
1572
+ modelValue: c(ne),
1573
+ "onUpdate:modelValue": r[5] || (r[5] = (o) => Ce(ne) ? ne.value = o : null),
1574
+ placeholder: "搜索用户",
1575
+ "prefix-icon": c(Le),
1576
+ class: "add-friend-search-input"
1577
+ }, null, 8, ["modelValue", "prefix-icon"])
1578
+ ]),
1579
+ e("div", ha, [
1580
+ c($) ? (n(), B(y, {
1581
+ key: 0,
1582
+ description: "加载中..."
1583
+ })) : c(G).length === 0 ? (n(), B(y, {
1584
+ key: 1,
1585
+ description: "暂无用户"
1586
+ })) : (n(!0), v(se, { key: 2 }, ae(c(G), (o) => (n(), v("div", {
1587
+ key: o.username,
1588
+ class: "add-friend-user-item"
1589
+ }, [
1590
+ e("div", ga, [
1591
+ e("img", {
1592
+ src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${o.username}`,
1593
+ alt: o.username,
1594
+ class: "add-friend-user-avatar"
1595
+ }, null, 8, _a),
1596
+ e("div", ya, _(o.username), 1)
1597
+ ]),
1598
+ p(V, {
1599
+ type: "primary",
1600
+ size: "small",
1601
+ onClick: (te) => c(xe)(o)
1602
+ }, {
1603
+ default: b(() => [...r[22] || (r[22] = [
1604
+ J("添加", -1)
1605
+ ])]),
1606
+ _: 1
1607
+ }, 8, ["onClick"])
1608
+ ]))), 128))
1609
+ ])
1610
+ ]),
1611
+ _: 1
1612
+ }, 8, ["modelValue"]),
1613
+ p(Y, {
1614
+ modelValue: ge.value,
1615
+ "onUpdate:modelValue": r[11] || (r[11] = (o) => ge.value = o),
1616
+ title: "个人设置",
1617
+ width: "560px",
1618
+ "close-on-click-modal": !1,
1619
+ "append-to-body": "",
1620
+ class: "chat-settings-dialog"
1621
+ }, {
1622
+ default: b(() => [
1623
+ e("div", ba, [
1624
+ e("div", ka, [
1625
+ e("div", wa, [
1626
+ e("img", {
1627
+ src: c(N),
1628
+ alt: "头像",
1629
+ class: "chat-settings-avatar"
1630
+ }, null, 8, Ca),
1631
+ w.config.modules.avatarCrop ? (n(), v("div", {
1632
+ key: 0,
1633
+ class: "chat-settings-avatar-edit",
1634
+ onClick: at
1635
+ }, [
1636
+ p(u, {
1637
+ size: 18,
1638
+ class: "chat-settings-avatar-icon"
1330
1639
  }, {
1331
1640
  default: b(() => [
1332
- h(u(At))
1641
+ p(c(zt))
1333
1642
  ]),
1334
1643
  _: 1
1335
1644
  })
1336
- ])
1645
+ ])) : U("", !0),
1646
+ e("input", {
1647
+ ref_key: "avatarInputRef",
1648
+ ref: g,
1649
+ type: "file",
1650
+ accept: "image/*",
1651
+ class: "hidden-avatar-input",
1652
+ onChange: rt
1653
+ }, null, 544)
1337
1654
  ]),
1338
- t("div", {
1339
- ref_key: "messagesContainer",
1340
- ref: I,
1341
- class: "flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-0 message-list"
1342
- }, [
1343
- (i(!0), f(he, null, pe(u(J), (s, O) => (i(), f("div", {
1344
- key: O,
1345
- class: j([
1346
- "flex mb-6 items-start",
1347
- s.isSelf ? "flex-row-reverse" : "flex-row"
1348
- ])
1349
- }, [
1350
- t("div", js, [
1351
- t("img", {
1352
- src: s.isSelf ? u(z) : D.value.avatar,
1353
- class: "w-10 h-10 rounded-lg object-cover"
1354
- }, null, 8, Ds)
1355
- ]),
1356
- t("div", {
1357
- class: j([
1358
- "flex flex-col max-w-[75%]",
1359
- s.isSelf ? "mr-3 items-end" : "ml-3 items-start"
1360
- ])
1361
- }, [
1362
- s.isSelf ? F("", !0) : (i(), f("div", Ms, w(D.value.name), 1)),
1363
- t("div", Es, [
1364
- s.type === "text" ? (i(), f("div", {
1365
- key: 0,
1366
- class: j([
1367
- "px-3 py-2 text-sm break-all whitespace-pre-wrap rounded-lg shadow-sm",
1368
- s.isSelf ? "bg-[#95ec69] text-gray-800 self-end message-bubble-self" : "bg-white text-gray-800 message-bubble-other"
1369
- ])
1370
- }, w(s.text), 3)) : s.type === "file" && s.fileType === "image" ? (i(), f("div", {
1371
- key: 1,
1372
- class: j([
1373
- "rounded-lg relative shadow-sm cursor-pointer overflow-hidden max-w-[300px]",
1374
- s.isSelf ? "self-end" : "self-start"
1375
- ]),
1376
- onClick: (De) => Pe(s.fileUrl)
1377
- }, [
1378
- t("img", {
1379
- src: s.fileUrl,
1380
- alt: s.fileName,
1381
- class: "w-full h-auto block",
1382
- onError: ot
1383
- }, null, 40, Ks),
1384
- s.fileName || s.fileSize ? (i(), f("div", {
1385
- key: 0,
1386
- class: j([
1387
- s.isSelf ? "bg-[#95ec69] text-gray-700" : "bg-white text-gray-500"
1388
- ])
1389
- }, [
1390
- s.fileSize ? (i(), f("div", Ws, w(Ne(s.fileSize)), 1)) : F("", !0)
1391
- ], 2)) : F("", !0)
1392
- ], 10, $s)) : s.type === "file" ? (i(), f("div", {
1393
- key: 2,
1394
- class: j([
1395
- "rounded-lg shadow-sm cursor-pointer overflow-hidden min-w-[200px]",
1396
- s.isSelf ? "self-end message-bubble-self" : "message-bubble-other"
1397
- ]),
1398
- onClick: (De) => Pe(s.fileUrl)
1399
- }, [
1400
- t("div", {
1401
- class: j([
1402
- "flex items-center gap-3 px-4 py-3",
1403
- s.isSelf ? "bg-[#95ec69]" : "bg-white"
1404
- ])
1405
- }, [
1406
- t("div", Ns, [
1407
- h(p, {
1408
- size: 28,
1409
- class: j(s.isSelf ? "text-gray-700" : "text-gray-500")
1410
- }, {
1411
- default: b(() => [
1412
- h(u(St))
1413
- ]),
1414
- _: 1
1415
- }, 8, ["class"])
1416
- ]),
1417
- t("div", Hs, [
1418
- t("div", {
1419
- class: j([
1420
- "truncate text-sm font-medium leading-tight",
1421
- (s.isSelf, "text-gray-800")
1422
- ])
1423
- }, w(s.fileName || s.text), 3),
1424
- t("div", {
1425
- class: j([
1426
- "text-xs mt-1 flex items-center gap-2",
1427
- s.isSelf ? "text-gray-600" : "text-gray-500"
1428
- ])
1429
- }, [
1430
- h(p, { size: 12 }, {
1431
- default: b(() => [
1432
- h(u(Vt))
1433
- ]),
1434
- _: 1
1435
- }),
1436
- l[19] || (l[19] = t("span", null, "点击下载", -1)),
1437
- s.fileSize ? (i(), f("span", Ps, "· " + w(Ne(s.fileSize)), 1)) : F("", !0)
1438
- ], 2)
1439
- ])
1440
- ], 2)
1441
- ], 10, Bs)) : F("", !0),
1442
- t("div", {
1443
- class: j([
1444
- "text-[10px] text-gray-400 mt-1",
1445
- s.isSelf ? "text-right" : "text-left"
1446
- ])
1447
- }, w(u(ne)(s.time)), 3)
1448
- ])
1449
- ], 2)
1450
- ], 2))), 128))
1451
- ], 512),
1452
- t("div", qs, [
1453
- W.value.length > 0 ? (i(), f("div", Os, [
1454
- (i(!0), f(he, null, pe(W.value, (s, O) => (i(), f("div", {
1455
- key: s.id,
1456
- class: "relative group"
1457
- }, [
1458
- s.isImage ? (i(), f("div", Xs, [
1459
- t("img", {
1460
- src: s.previewUrl,
1461
- alt: s.name,
1462
- class: "w-full h-full object-cover"
1463
- }, null, 8, Ys),
1464
- t("button", {
1465
- onClick: (De) => Be(O),
1466
- class: "absolute top-1 right-1 w-5 h-5 bg-black/50 text-white rounded-full flex items-center justify-center hover:bg-black/70 transition-colors text-xs"
1467
- }, " × ", 8, Gs)
1468
- ])) : (i(), f("div", Js, [
1469
- h(p, { class: "text-gray-400 text-2xl mb-1" }, {
1470
- default: b(() => [
1471
- h(u(Ye))
1472
- ]),
1473
- _: 1
1474
- }),
1475
- t("span", Qs, w(s.name), 1),
1476
- t("button", {
1477
- onClick: (De) => Be(O),
1478
- class: "absolute top-1 right-1 w-5 h-5 bg-black/50 text-white rounded-full flex items-center justify-center hover:bg-black/70 transition-colors text-xs"
1479
- }, " × ", 8, Zs)
1480
- ]))
1481
- ]))), 128))
1482
- ])) : F("", !0),
1483
- y.config.modules.fileUpload ? (i(), f("div", ea, [
1484
- h(p, { class: "text-gray-500 cursor-pointer hover:text-gray-700" }, {
1655
+ e("div", Ua, [
1656
+ e("div", $a, _(c(I).nickname || c(C)), 1),
1657
+ e("div", xa, "@" + _(c(C)), 1)
1658
+ ])
1659
+ ]),
1660
+ e("div", Aa, [
1661
+ e("div", Va, [
1662
+ e("div", Sa, [
1663
+ p(u, null, {
1485
1664
  default: b(() => [
1486
- h(u(Me))
1665
+ p(c(Ge))
1487
1666
  ]),
1488
1667
  _: 1
1489
1668
  }),
1490
- h(p, {
1491
- class: "text-gray-500 cursor-pointer hover:text-gray-700",
1492
- onClick: nt
1669
+ r[23] || (r[23] = J(" 个人信息 ", -1))
1670
+ ]),
1671
+ j.value ? U("", !0) : (n(), B(V, {
1672
+ key: 0,
1673
+ type: "primary",
1674
+ size: "small",
1675
+ onClick: dt,
1676
+ class: "chat-settings-edit-btn"
1677
+ }, {
1678
+ default: b(() => [...r[24] || (r[24] = [
1679
+ J(" 编辑 ", -1)
1680
+ ])]),
1681
+ _: 1
1682
+ }))
1683
+ ]),
1684
+ e("div", Fa, [
1685
+ e("div", Ia, [
1686
+ r[25] || (r[25] = e("label", { class: "chat-settings-form-label" }, "昵称", -1)),
1687
+ j.value ? (n(), B(s, {
1688
+ key: 0,
1689
+ modelValue: D.value.nickname,
1690
+ "onUpdate:modelValue": r[7] || (r[7] = (o) => D.value.nickname = o),
1691
+ placeholder: "请输入昵称",
1692
+ size: "large"
1693
+ }, null, 8, ["modelValue"])) : (n(), v("div", za, _(c(I).nickname || "未设置"), 1))
1694
+ ]),
1695
+ e("div", Ra, [
1696
+ r[26] || (r[26] = e("label", { class: "chat-settings-form-label" }, "邮箱", -1)),
1697
+ j.value ? (n(), B(s, {
1698
+ key: 0,
1699
+ modelValue: D.value.email,
1700
+ "onUpdate:modelValue": r[8] || (r[8] = (o) => D.value.email = o),
1701
+ placeholder: "请输入邮箱",
1702
+ size: "large"
1703
+ }, null, 8, ["modelValue"])) : (n(), v("div", La, _(c(I).email || "未设置"), 1))
1704
+ ]),
1705
+ e("div", Ta, [
1706
+ r[27] || (r[27] = e("label", { class: "chat-settings-form-label" }, "手机号", -1)),
1707
+ j.value ? (n(), B(s, {
1708
+ key: 0,
1709
+ modelValue: D.value.phone,
1710
+ "onUpdate:modelValue": r[9] || (r[9] = (o) => D.value.phone = o),
1711
+ placeholder: "请输入手机号",
1712
+ size: "large"
1713
+ }, null, 8, ["modelValue"])) : (n(), v("div", Ma, _(c(I).phone || "未设置"), 1))
1714
+ ]),
1715
+ e("div", Da, [
1716
+ r[28] || (r[28] = e("label", { class: "chat-settings-form-label" }, "个人简介", -1)),
1717
+ j.value ? (n(), B(s, {
1718
+ key: 0,
1719
+ modelValue: D.value.bio,
1720
+ "onUpdate:modelValue": r[10] || (r[10] = (o) => D.value.bio = o),
1721
+ type: "textarea",
1722
+ rows: 4,
1723
+ placeholder: "介绍一下自己吧...",
1724
+ size: "large"
1725
+ }, null, 8, ["modelValue"])) : (n(), v("div", Ea, _(c(I).bio || "这个人很懒,什么都没写~"), 1))
1726
+ ]),
1727
+ j.value ? (n(), v("div", qa, [
1728
+ p(V, {
1729
+ size: "default",
1730
+ onClick: ut
1493
1731
  }, {
1494
- default: b(() => [
1495
- h(u(Ye))
1496
- ]),
1732
+ default: b(() => [...r[29] || (r[29] = [
1733
+ J("取消", -1)
1734
+ ])]),
1497
1735
  _: 1
1498
1736
  }),
1499
- h(p, { class: "text-gray-500 cursor-pointer hover:text-gray-700" }, {
1500
- default: b(() => [
1501
- h(u(Ft))
1502
- ]),
1503
- _: 1
1504
- })
1505
- ])) : F("", !0),
1506
- t("div", ta, [
1507
- xt(t("textarea", {
1508
- "onUpdate:modelValue": l[4] || (l[4] = (s) => we(_) ? _.value = s : null),
1509
- onKeydown: bt(Oe(He, ["prevent"]), ["enter"]),
1510
- onPaste: rt,
1511
- placeholder: "输入消息或粘贴文件...",
1512
- class: "w-full resize-none border-0 outline-none text-sm h-[80px]",
1513
- rows: "3"
1514
- }, null, 40, sa), [
1515
- [_t, u(_)]
1516
- ])
1517
- ]),
1518
- t("div", aa, [
1519
- h(fe, {
1737
+ p(V, {
1520
1738
  type: "primary",
1521
- disabled: !u(_).trim() && W.value.length === 0,
1522
- onClick: He,
1523
- class: "bg-[#07c160] hover:bg-[#06ad56] border-0 text-sm px-6"
1739
+ size: "default",
1740
+ loading: X.value,
1741
+ onClick: vt
1524
1742
  }, {
1525
- default: b(() => [...l[20] || (l[20] = [
1526
- se(" 发送 ", -1)
1743
+ default: b(() => [...r[30] || (r[30] = [
1744
+ J("保存更改", -1)
1527
1745
  ])]),
1528
1746
  _: 1
1529
- }, 8, ["disabled"])
1530
- ]),
1531
- t("input", {
1532
- ref_key: "fileInputRef",
1533
- ref: ue,
1534
- type: "file",
1535
- multiple: "",
1536
- class: "hidden",
1537
- onChange: lt
1538
- }, null, 544)
1539
- ])
1540
- ])) : M.value ? F("", !0) : (i(), f("div", na, [
1541
- h(p, {
1542
- size: 64,
1543
- class: "text-gray-300 mb-2"
1544
- }, {
1545
- default: b(() => [
1546
- h(u(Rt))
1547
- ]),
1548
- _: 1
1549
- }),
1550
- t("div", la, w(Q.value === "apply" ? "在左侧选择好友申请" : "在左侧选择好友开始聊天"), 1)
1551
- ]))
1552
- ]),
1553
- de.value ? (i(), f("div", ra, [
1554
- l[22] || (l[22] = t("div", { class: "h-14 flex items-center justify-center border-b border-gray-200" }, [
1555
- t("span", { class: "font-medium text-gray-700" }, "聊天详情")
1556
- ], -1)),
1557
- t("div", oa, [
1558
- t("div", ia, [
1559
- t("img", {
1560
- src: D.value?.avatar,
1561
- alt: D.value?.name,
1562
- class: "w-20 h-20 rounded-full object-cover"
1563
- }, null, 8, ca),
1564
- t("div", da, w(D.value?.name), 1),
1565
- l[21] || (l[21] = t("div", { class: "mt-6 w-full" }, [
1566
- t("div", { class: "bg-white rounded-lg" }, [
1567
- t("div", { class: "p-3 border-b border-gray-100 cursor-pointer hover:bg-gray-50" }, [
1568
- t("span", { class: "text-sm text-gray-700" }, "查找聊天记录")
1569
- ]),
1570
- t("div", { class: "p-3 border-b border-gray-100 cursor-pointer hover:bg-gray-50" }, [
1571
- t("span", { class: "text-sm text-gray-700" }, "清空聊天记录")
1572
- ])
1573
- ])
1574
- ], -1))
1747
+ }, 8, ["loading"])
1748
+ ])) : U("", !0)
1575
1749
  ])
1576
1750
  ])
1577
- ])) : F("", !0)
1751
+ ])
1578
1752
  ]),
1579
- h(je, {
1580
- modelValue: u(ae),
1581
- "onUpdate:modelValue": l[6] || (l[6] = (s) => we(ae) ? ae.value = s : null),
1582
- title: "添加好友",
1583
- width: "500px",
1584
- "append-to-body": ""
1585
- }, {
1586
- default: b(() => [
1587
- t("div", ua, [
1588
- t("div", fa, [
1589
- h(S, {
1590
- modelValue: u(ee),
1591
- "onUpdate:modelValue": l[5] || (l[5] = (s) => we(ee) ? ee.value = s : null),
1592
- placeholder: "搜索用户",
1593
- "prefix-icon": u(Ee)
1753
+ _: 1
1754
+ }, 8, ["modelValue"]),
1755
+ p(Tt, {
1756
+ modelValue: l.value,
1757
+ "onUpdate:modelValue": r[12] || (r[12] = (o) => l.value = o),
1758
+ src: A.value,
1759
+ onConfirm: ct
1760
+ }, null, 8, ["modelValue", "src"]),
1761
+ q.value.visible ? (n(), v("div", {
1762
+ key: 1,
1763
+ class: "chat-context-menu",
1764
+ style: Ct({ left: q.value.x + "px", top: q.value.y + "px" })
1765
+ }, [
1766
+ e("div", {
1767
+ class: "chat-context-menu-item",
1768
+ onClick: Ze
1769
+ }, "删除聊天")
1770
+ ], 4)) : U("", !0)
1771
+ ]);
1772
+ };
1773
+ }
1774
+ }, Kl = /* @__PURE__ */ ht(Wa, [["__scopeId", "data-v-f5908195"]]), Ba = { class: "chat-container" }, Ka = { class: "sidebar-nav" }, Pa = ["src"], Na = ["onClick"], Ha = {
1775
+ key: 0,
1776
+ class: "nav-badge"
1777
+ }, Oa = { class: "content-panel" }, ja = { class: "search-bar" }, Xa = { class: "content-scroll" }, Ya = { key: 0 }, Ga = ["onClick", "onContextmenu"], Ja = { class: "friend-avatar-wrapper" }, Qa = ["src", "alt"], Za = {
1778
+ key: 0,
1779
+ class: "online-indicator"
1780
+ }, en = { class: "friend-info" }, tn = { class: "friend-header" }, sn = { class: "friend-name" }, an = { class: "last-time" }, nn = { class: "friend-preview" }, ln = { class: "last-msg" }, on = {
1781
+ key: 0,
1782
+ class: "unread-badge"
1783
+ }, rn = { key: 1 }, cn = { class: "add-friend-section" }, dn = { class: "add-friend-icon" }, un = ["onClick"], vn = { class: "friend-avatar-wrapper" }, pn = ["src", "alt"], mn = { class: "friend-info" }, fn = { class: "friend-name" }, hn = { key: 2 }, gn = { class: "request-info" }, _n = ["src", "alt"], yn = { class: "request-details" }, bn = { class: "request-username" }, kn = { class: "chat-area" }, wn = {
1784
+ key: 0,
1785
+ class: "friend-profile"
1786
+ }, Cn = ["src", "alt"], Un = { class: "profile-name" }, $n = { class: "profile-status" }, xn = {
1787
+ key: 1,
1788
+ class: "chat-window"
1789
+ }, An = { class: "chat-header" }, Vn = { class: "chat-title" }, Sn = { class: "chat-name" }, Fn = { class: "chat-actions" }, In = { class: "message-avatar" }, zn = ["src"], Rn = {
1790
+ key: 0,
1791
+ class: "sender-name"
1792
+ }, Ln = { class: "message-bubble-wrapper" }, Tn = ["onClick"], Mn = ["src", "alt"], Dn = {
1793
+ key: 0,
1794
+ class: "image-size"
1795
+ }, En = ["onClick"], qn = { class: "file-content" }, Wn = { class: "file-icon" }, Bn = { class: "file-info" }, Kn = { class: "file-name" }, Pn = { class: "file-meta" }, Nn = { key: 0 }, Hn = { class: "input-area" }, On = {
1796
+ key: 0,
1797
+ class: "pending-files"
1798
+ }, jn = {
1799
+ key: 0,
1800
+ class: "pending-image-wrapper"
1801
+ }, Xn = ["src", "alt"], Yn = ["onClick"], Gn = {
1802
+ key: 1,
1803
+ class: "pending-file-wrapper"
1804
+ }, Jn = { class: "pending-file-name" }, Qn = ["onClick"], Zn = {
1805
+ key: 1,
1806
+ class: "input-actions"
1807
+ }, el = { class: "input-wrapper" }, tl = ["onKeydown"], sl = { class: "send-btn-wrapper" }, al = {
1808
+ key: 2,
1809
+ class: "empty-state"
1810
+ }, nl = { class: "empty-text" }, ll = {
1811
+ key: 0,
1812
+ class: "detail-panel"
1813
+ }, il = { class: "detail-content" }, ol = { class: "detail-profile" }, rl = ["src", "alt"], cl = { class: "detail-name" }, dl = { class: "search-users-wrapper" }, ul = { class: "search-users-input" }, vl = { class: "users-list-scroll" }, pl = { class: "available-user-info" }, ml = ["src", "alt"], fl = { class: "available-user-name" }, hl = { class: "settings-container" }, gl = { class: "settings-avatar-section" }, _l = { class: "settings-avatar-wrapper" }, yl = ["src"], bl = { class: "settings-user-display" }, kl = { class: "settings-nickname" }, wl = { class: "settings-username" }, Cl = { class: "settings-form-section" }, Ul = { class: "settings-form-header" }, $l = { class: "settings-form-title" }, xl = { class: "settings-form" }, Al = { class: "settings-form-item" }, Vl = {
1814
+ key: 1,
1815
+ class: "settings-form-value"
1816
+ }, Sl = { class: "settings-form-item" }, Fl = {
1817
+ key: 1,
1818
+ class: "settings-form-value"
1819
+ }, Il = { class: "settings-form-item" }, zl = {
1820
+ key: 1,
1821
+ class: "settings-form-value"
1822
+ }, Rl = { class: "settings-form-item" }, Ll = {
1823
+ key: 1,
1824
+ class: "settings-form-value bio-value"
1825
+ }, Tl = {
1826
+ key: 0,
1827
+ class: "settings-form-actions"
1828
+ }, Ml = {
1829
+ __name: "ChatWindow",
1830
+ props: {
1831
+ modelValue: { type: Boolean, default: !1 },
1832
+ config: { type: Object, required: !0 },
1833
+ width: { type: [String, Number], default: "1100px" }
1834
+ },
1835
+ emits: ["update:modelValue", "open", "close", "message", "send", "error"],
1836
+ setup(w, { emit: t }) {
1837
+ const a = w, m = t, C = ye({
1838
+ get: () => a.modelValue,
1839
+ set: (u) => m("update:modelValue", u)
1840
+ }), {
1841
+ myUsername: N,
1842
+ myAvatar: I,
1843
+ userInfo: T,
1844
+ loadingUserInfo: L,
1845
+ friendList: H,
1846
+ filteredFriendList: x,
1847
+ searchText: k,
1848
+ inputText: S,
1849
+ messagesContainer: z,
1850
+ filteredUsers: G,
1851
+ filteredAvailableUsers: fe,
1852
+ currentUser: oe,
1853
+ currentMessages: Q,
1854
+ addFriendDialogVisible: ne,
1855
+ addFriendSearchText: _e,
1856
+ availableUsers: $,
1857
+ loadingAvailableUsers: R,
1858
+ friendApplyList: M,
1859
+ loadingFriendApply: Z,
1860
+ formatTime: he,
1861
+ formatLastTime: re,
1862
+ scrollToBottom: be,
1863
+ getFriendList: Ue,
1864
+ getChatHistory: $e,
1865
+ setFriendToChatStatus: ke,
1866
+ selectUser: ce,
1867
+ sendMessage: de,
1868
+ sendFile: we,
1869
+ sendFilesAndText: Te,
1870
+ initWebSocket: Me,
1871
+ closeWebSocket: Fe,
1872
+ reset: Ie,
1873
+ openAddFriendDialog: xe,
1874
+ addFriend: De,
1875
+ loadFriendApplyList: Ee,
1876
+ agreeFriend: qe,
1877
+ updateMyAvatar: We,
1878
+ getUserInfo: Be,
1879
+ updateUserInfo: Ke
1880
+ } = Lt(a.config), ve = ye(() => {
1881
+ var s;
1882
+ const u = [{ id: "chat", icon: Re, badge: 0 }];
1883
+ return a.config.modules.friends && u.push({ id: "friends", icon: Ge, badge: 0 }), a.config.modules.apply && u.push({ id: "apply", icon: Ut, badge: ((s = M.value) == null ? void 0 : s.length) || 0 }), u;
1884
+ }), ee = h("chat"), W = h(null), F = h(null), O = h(null), j = h(!1), D = h(!1), X = h({ nickname: "", email: "", phone: "", bio: "" }), ge = h(!1), l = h(!1), d = h(!1), g = h(!1), A = h(null), le = h(""), E = h(null), q = h([]), pe = h({ visible: !1, x: 0, y: 0, chat: null }), Ae = () => {
1885
+ pe.value.visible = !1;
1886
+ }, Ze = async () => {
1887
+ if (!pe.value.chat) return;
1888
+ await ke(pe.value.chat.id, 0) && W.value === pe.value.chat.id && (W.value = null, F.value = null), Ae();
1889
+ }, Ve = (u) => {
1890
+ W.value = u.id, F.value = u, O.value = null, j.value = !1, ce({
1891
+ id: u.id,
1892
+ name: u.name,
1893
+ avatar: u.avatar,
1894
+ online: u.online
1895
+ });
1896
+ }, et = (u) => {
1897
+ O.value = u, W.value = null, F.value = null;
1898
+ }, tt = async () => {
1899
+ if (!O.value) return;
1900
+ if (await ke(O.value.id)) {
1901
+ ee.value = "chat", await Qe();
1902
+ const s = G.value.find((y) => y.id === O.value.id);
1903
+ s && Ve(s), O.value = null;
1904
+ }
1905
+ }, st = () => {
1906
+ l.value = !0;
1907
+ }, at = () => {
1908
+ var u;
1909
+ (u = A.value) == null || u.click();
1910
+ }, nt = () => {
1911
+ var u;
1912
+ (u = E.value) == null || u.click();
1913
+ }, lt = (u) => {
1914
+ const s = Array.from(u.target.files || []);
1915
+ if (s.length !== 0) {
1916
+ for (const y of s) {
1917
+ if (y.size > 50 * 1024 * 1024) {
1918
+ P.warning(`文件 ${y.name} 超过50MB,已跳过`);
1919
+ continue;
1920
+ }
1921
+ const V = URL.createObjectURL(y);
1922
+ q.value.push({
1923
+ id: Date.now() + Math.random(),
1924
+ file: y,
1925
+ name: y.name,
1926
+ size: y.size,
1927
+ type: y.type,
1928
+ previewUrl: V,
1929
+ isImage: y.type.startsWith("image/")
1930
+ });
1931
+ }
1932
+ E.value && (E.value.value = "");
1933
+ }
1934
+ }, Pe = (u) => {
1935
+ const s = q.value[u];
1936
+ s.previewUrl && URL.revokeObjectURL(s.previewUrl), q.value.splice(u, 1);
1937
+ }, Ne = (u) => {
1938
+ if (u === 0) return "0 B";
1939
+ const s = 1024, y = ["B", "KB", "MB", "GB"], V = Math.floor(Math.log(u) / Math.log(s));
1940
+ return parseFloat((u / Math.pow(s, V)).toFixed(2)) + " " + y[V];
1941
+ }, He = async () => {
1942
+ if (!S.value.trim() && q.value.length === 0) return;
1943
+ const u = [...q.value], s = S.value;
1944
+ S.value = "", q.value.forEach((y) => {
1945
+ y.previewUrl && URL.revokeObjectURL(y.previewUrl);
1946
+ }), q.value = [], await Te(u, s), m("send", { text: s, files: u });
1947
+ }, it = (u) => {
1948
+ var y;
1949
+ const s = (y = u.clipboardData) == null ? void 0 : y.items;
1950
+ if (s) {
1951
+ for (const V of s)
1952
+ if (V.kind === "file") {
1953
+ const Y = V.getAsFile();
1954
+ if (Y) {
1955
+ if (Y.size > 50 * 1024 * 1024) {
1956
+ P.warning(`文件 ${Y.name} 超过50MB,已跳过`);
1957
+ continue;
1958
+ }
1959
+ const ue = URL.createObjectURL(Y);
1960
+ q.value.push({
1961
+ id: Date.now() + Math.random(),
1962
+ file: Y,
1963
+ name: Y.name,
1964
+ size: Y.size,
1965
+ type: Y.type,
1966
+ previewUrl: ue,
1967
+ isImage: Y.type.startsWith("image/")
1968
+ });
1969
+ }
1970
+ }
1971
+ }
1972
+ }, Oe = (u) => {
1973
+ if (!u) {
1974
+ P.warning("文件地址无效");
1975
+ return;
1976
+ }
1977
+ window.open(u, "_blank");
1978
+ }, ot = (u) => {
1979
+ console.warn("图片加载失败", u);
1980
+ }, rt = (u) => {
1981
+ const s = u.target.files[0];
1982
+ if (!s) return;
1983
+ if (!s.type.startsWith("image/")) {
1984
+ P.error("只能上传图片文件");
1985
+ return;
1986
+ }
1987
+ if (s.size > 5 * 1024 * 1024) {
1988
+ P.error("图片大小不能超过 5MB");
1989
+ return;
1990
+ }
1991
+ const y = new FileReader();
1992
+ y.onload = (V) => {
1993
+ le.value = V.target.result, d.value = !0;
1994
+ }, y.readAsDataURL(s);
1995
+ }, ct = async ({ file: u }) => {
1996
+ if (u) {
1997
+ g.value = !0;
1998
+ try {
1999
+ const { ChatApi: s } = await Promise.resolve().then(() => Rt), V = await new s(a.config).uploadAvatar(u, N);
2000
+ V.code === 200 ? (P.success("头像上传成功"), We(V.data), je()) : P.error(V.msg || "头像上传失败");
2001
+ } catch (s) {
2002
+ console.error(s), P.error("头像上传失败");
2003
+ } finally {
2004
+ g.value = !1;
2005
+ }
2006
+ }
2007
+ }, je = () => {
2008
+ le.value = "", d.value = !1, A.value && (A.value.value = "");
2009
+ }, dt = () => {
2010
+ X.value = {
2011
+ nickname: T.value.nickname || "",
2012
+ email: T.value.email || "",
2013
+ phone: T.value.phone || "",
2014
+ bio: T.value.bio || ""
2015
+ }, D.value = !0;
2016
+ }, ut = () => {
2017
+ D.value = !1, X.value = { nickname: "", email: "", phone: "", bio: "" };
2018
+ }, vt = async () => {
2019
+ ge.value = !0;
2020
+ try {
2021
+ await Ke(X.value) ? (P.success("保存成功"), D.value = !1) : P.error("保存失败");
2022
+ } catch (u) {
2023
+ console.error(u), P.error("保存失败");
2024
+ } finally {
2025
+ ge.value = !1;
2026
+ }
2027
+ }, f = () => {
2028
+ Ie(), Fe(), j.value = !1, l.value = !1, je(), D.value = !1, m("close");
2029
+ }, r = async () => {
2030
+ await Promise.all([Ue(), Ee(), Be()]), Me(), G.value.length > 0 && Ve(G.value[0]), m("open");
2031
+ };
2032
+ return gt(() => {
2033
+ document.addEventListener("click", Ae);
2034
+ }), _t(() => {
2035
+ document.removeEventListener("click", Ae), Fe();
2036
+ }), (u, s) => {
2037
+ const y = ie("el-icon"), V = ie("el-input"), Y = ie("el-empty"), ue = ie("el-button"), ze = ie("el-dialog");
2038
+ return n(), B(ze, {
2039
+ modelValue: C.value,
2040
+ "onUpdate:modelValue": s[13] || (s[13] = (Se) => C.value = Se),
2041
+ width: w.width,
2042
+ "close-on-click-modal": !1,
2043
+ class: "chat-dialog",
2044
+ "append-to-body": "",
2045
+ onClosed: f,
2046
+ onOpen: r
2047
+ }, {
2048
+ default: b(() => {
2049
+ var Se, o, te;
2050
+ return [
2051
+ e("div", Ba, [
2052
+ e("div", Ka, [
2053
+ e("div", {
2054
+ class: "sidebar-avatar",
2055
+ onClick: st
2056
+ }, [
2057
+ e("img", {
2058
+ src: c(I),
2059
+ alt: "头像",
2060
+ class: "avatar-img"
2061
+ }, null, 8, Pa)
2062
+ ]),
2063
+ (n(!0), v(se, null, ae(ve.value, (i) => (n(), v("div", {
2064
+ key: i.id,
2065
+ class: K([
2066
+ "nav-item",
2067
+ ee.value === i.id ? "nav-item-active" : "nav-item-inactive"
2068
+ ]),
2069
+ onClick: (me) => ee.value = i.id
2070
+ }, [
2071
+ p(y, { size: 24 }, {
2072
+ default: b(() => [
2073
+ (n(), B(yt(i.icon)))
2074
+ ]),
2075
+ _: 2
2076
+ }, 1024),
2077
+ i.badge ? (n(), v("span", Ha, _(i.badge > 99 ? "99+" : i.badge), 1)) : U("", !0)
2078
+ ], 10, Na))), 128)),
2079
+ s[14] || (s[14] = e("div", { class: "nav-spacer" }, null, -1)),
2080
+ w.config.modules.settings ? (n(), v("div", {
2081
+ key: 0,
2082
+ class: "nav-item nav-item-inactive",
2083
+ onClick: s[0] || (s[0] = (i) => l.value = !0),
2084
+ title: "设置"
2085
+ }, [
2086
+ p(y, { size: 24 }, {
2087
+ default: b(() => [
2088
+ p(c($t))
2089
+ ]),
2090
+ _: 1
2091
+ })
2092
+ ])) : U("", !0)
2093
+ ]),
2094
+ e("div", Oa, [
2095
+ e("div", ja, [
2096
+ p(V, {
2097
+ modelValue: c(k),
2098
+ "onUpdate:modelValue": s[1] || (s[1] = (i) => Ce(k) ? k.value = i : null),
2099
+ placeholder: "搜索",
2100
+ "prefix-icon": c(Le)
1594
2101
  }, null, 8, ["modelValue", "prefix-icon"])
2102
+ ]),
2103
+ e("div", Xa, [
2104
+ ee.value === "chat" ? (n(), v("div", Ya, [
2105
+ (n(!0), v(se, null, ae(c(G), (i) => (n(), v("div", {
2106
+ key: i.id,
2107
+ class: K([
2108
+ "chat-item",
2109
+ W.value === i.id ? "chat-item-active" : ""
2110
+ ]),
2111
+ onClick: (me) => Ve(i),
2112
+ onContextmenu: Ye((me) => u.showContextMenu(me, i), ["prevent", "stop"])
2113
+ }, [
2114
+ e("div", Ja, [
2115
+ e("img", {
2116
+ src: i.avatar,
2117
+ alt: i.name,
2118
+ class: "friend-avatar"
2119
+ }, null, 8, Qa),
2120
+ i.online ? (n(), v("span", Za)) : U("", !0)
2121
+ ]),
2122
+ e("div", en, [
2123
+ e("div", tn, [
2124
+ e("span", sn, _(i.name), 1),
2125
+ e("span", an, _(c(re)(i.lastTime)), 1)
2126
+ ]),
2127
+ e("div", nn, [
2128
+ e("span", ln, _(i.lastMsg), 1),
2129
+ i.unread > 0 ? (n(), v("span", on, _(i.unread > 99 ? "99+" : i.unread), 1)) : U("", !0)
2130
+ ])
2131
+ ])
2132
+ ], 42, Ga))), 128))
2133
+ ])) : U("", !0),
2134
+ ee.value === "friends" && w.config.modules.friends ? (n(), v("div", rn, [
2135
+ e("div", cn, [
2136
+ e("div", {
2137
+ class: "add-friend-btn",
2138
+ onClick: s[2] || (s[2] = (...i) => c(xe) && c(xe)(...i))
2139
+ }, [
2140
+ e("div", dn, [
2141
+ p(y, {
2142
+ class: "text-white",
2143
+ size: 20
2144
+ }, {
2145
+ default: b(() => [
2146
+ p(c(xt))
2147
+ ]),
2148
+ _: 1
2149
+ })
2150
+ ]),
2151
+ s[15] || (s[15] = e("span", { class: "add-friend-text" }, "添加好友", -1))
2152
+ ])
2153
+ ]),
2154
+ (n(!0), v(se, null, ae(c(x), (i) => (n(), v("div", {
2155
+ key: i.id,
2156
+ class: "chat-item",
2157
+ onClick: (me) => et(i)
2158
+ }, [
2159
+ e("div", vn, [
2160
+ e("img", {
2161
+ src: i.avatar,
2162
+ alt: i.name,
2163
+ class: "friend-avatar"
2164
+ }, null, 8, pn),
2165
+ e("span", {
2166
+ class: K([
2167
+ "online-indicator",
2168
+ i.online ? "online" : "offline"
2169
+ ])
2170
+ }, null, 2)
2171
+ ]),
2172
+ e("div", mn, [
2173
+ e("span", fn, _(i.name), 1)
2174
+ ])
2175
+ ], 8, un))), 128))
2176
+ ])) : U("", !0),
2177
+ ee.value === "apply" && w.config.modules.apply ? (n(), v("div", hn, [
2178
+ c(Z) ? (n(), B(Y, {
2179
+ key: 0,
2180
+ description: "加载中..."
2181
+ })) : c(M).length === 0 ? (n(), B(Y, {
2182
+ key: 1,
2183
+ description: "暂无好友申请"
2184
+ })) : (n(!0), v(se, { key: 2 }, ae(c(M), (i) => (n(), v("div", {
2185
+ key: i.applyUser || i.id,
2186
+ class: "friend-request-item"
2187
+ }, [
2188
+ e("div", gn, [
2189
+ e("img", {
2190
+ src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${i.applyUser}`,
2191
+ alt: i.applyUser,
2192
+ class: "request-avatar"
2193
+ }, null, 8, _n),
2194
+ e("div", yn, [
2195
+ e("div", bn, _(i.applyUser), 1),
2196
+ s[16] || (s[16] = e("div", { class: "request-desc" }, "请求添加你为好友", -1))
2197
+ ])
2198
+ ]),
2199
+ p(ue, {
2200
+ type: "primary",
2201
+ size: "small",
2202
+ onClick: (me) => c(qe)(i.applyUser)
2203
+ }, {
2204
+ default: b(() => [...s[17] || (s[17] = [
2205
+ J("同意", -1)
2206
+ ])]),
2207
+ _: 1
2208
+ }, 8, ["onClick"])
2209
+ ]))), 128))
2210
+ ])) : U("", !0)
1595
2211
  ])
1596
2212
  ]),
1597
- t("div", ha, [
1598
- u(U) ? (i(), H(ge, {
1599
- key: 0,
1600
- description: "加载中..."
1601
- })) : u(Y).length === 0 ? (i(), H(ge, {
1602
- key: 1,
1603
- description: "暂无用户"
1604
- })) : (i(!0), f(he, { key: 2 }, pe(u(Y), (s) => (i(), f("div", {
1605
- key: s.username,
1606
- class: "flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg mb-2 transition-colors"
1607
- }, [
1608
- t("div", pa, [
1609
- t("img", {
1610
- src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${s.username}`,
1611
- alt: s.username,
1612
- class: "w-10 h-10 rounded-full object-cover"
1613
- }, null, 8, ma),
1614
- t("div", va, [
1615
- t("div", ga, w(s.username), 1)
1616
- ])
2213
+ e("div", kn, [
2214
+ O.value && !F.value ? (n(), v("div", wn, [
2215
+ e("img", {
2216
+ src: O.value.avatar,
2217
+ alt: O.value.name,
2218
+ class: "profile-avatar"
2219
+ }, null, 8, Cn),
2220
+ e("div", Un, _(O.value.name), 1),
2221
+ e("div", $n, [
2222
+ e("span", {
2223
+ class: K([
2224
+ "status-dot",
2225
+ O.value.online ? "status-online" : "status-offline"
2226
+ ])
2227
+ }, null, 2),
2228
+ e("span", null, _(O.value.online ? "在线" : "离线"), 1)
1617
2229
  ]),
1618
- h(fe, {
2230
+ p(ue, {
1619
2231
  type: "primary",
1620
- size: "small",
1621
- onClick: (O) => u(Ae)(s)
2232
+ size: "large",
2233
+ onClick: tt,
2234
+ class: "start-chat-btn"
1622
2235
  }, {
1623
- default: b(() => [...l[23] || (l[23] = [
1624
- se("添加", -1)
1625
- ])]),
2236
+ default: b(() => [
2237
+ p(y, null, {
2238
+ default: b(() => [
2239
+ p(c(Re))
2240
+ ]),
2241
+ _: 1
2242
+ }),
2243
+ s[18] || (s[18] = e("span", null, "发消息", -1))
2244
+ ]),
1626
2245
  _: 1
1627
- }, 8, ["onClick"])
1628
- ]))), 128))
1629
- ])
1630
- ]),
1631
- _: 1
1632
- }, 8, ["modelValue"]),
1633
- h(je, {
1634
- modelValue: r.value,
1635
- "onUpdate:modelValue": l[11] || (l[11] = (s) => r.value = s),
1636
- title: "个人设置",
1637
- width: "560px",
1638
- "close-on-click-modal": !1,
1639
- "append-to-body": "",
1640
- class: "settings-dialog"
1641
- }, {
1642
- default: b(() => [
1643
- t("div", ya, [
1644
- t("div", xa, [
1645
- t("div", ba, [
1646
- t("img", {
1647
- src: u(z),
1648
- alt: "头像",
1649
- class: "w-28 h-28 rounded-full object-cover border-4 border-white shadow-lg"
1650
- }, null, 8, _a),
1651
- y.config.modules.avatarCrop ? (i(), f("div", {
1652
- key: 0,
1653
- class: "absolute -bottom-1 -right-1 w-10 h-10 bg-green-500 rounded-full flex items-center justify-center cursor-pointer hover:bg-green-600 transition-all shadow-md",
1654
- onClick: at
1655
- }, [
1656
- h(p, {
1657
- size: 18,
1658
- class: "text-white"
2246
+ })
2247
+ ])) : U("", !0),
2248
+ F.value ? (n(), v("div", xn, [
2249
+ e("div", An, [
2250
+ e("div", Vn, [
2251
+ e("span", Sn, _(F.value.name), 1),
2252
+ e("span", {
2253
+ class: K([
2254
+ "status-badge",
2255
+ F.value.online ? "status-badge-online" : "status-badge-offline"
2256
+ ])
2257
+ }, _(F.value.online ? "在线" : "离线"), 3)
2258
+ ]),
2259
+ e("div", Fn, [
2260
+ p(y, { class: "action-icon" }, {
2261
+ default: b(() => [
2262
+ p(c(Le))
2263
+ ]),
2264
+ _: 1
2265
+ }),
2266
+ p(y, {
2267
+ class: "action-icon",
2268
+ onClick: s[3] || (s[3] = (i) => j.value = !j.value)
1659
2269
  }, {
1660
2270
  default: b(() => [
1661
- h(u(It))
2271
+ p(c(At))
1662
2272
  ]),
1663
2273
  _: 1
1664
2274
  })
1665
- ])) : F("", !0),
1666
- t("input", {
1667
- ref_key: "avatarInputRef",
1668
- ref: te,
1669
- type: "file",
1670
- accept: "image/*",
1671
- class: "hidden",
1672
- onChange: it
1673
- }, null, 544)
2275
+ ])
1674
2276
  ]),
1675
- t("div", wa, [
1676
- t("div", ka, w(u(k).nickname || u(L)), 1),
1677
- t("div", Ca, "@" + w(u(L)), 1)
1678
- ])
1679
- ]),
1680
- t("div", Ua, [
1681
- t("div", Aa, [
1682
- t("div", Sa, [
1683
- h(p, null, {
2277
+ e("div", {
2278
+ ref_key: "messagesContainer",
2279
+ ref: z,
2280
+ class: "messages-container"
2281
+ }, [
2282
+ (n(!0), v(se, null, ae(c(Q), (i, me) => (n(), v("div", {
2283
+ key: me,
2284
+ class: K([
2285
+ "message-wrapper",
2286
+ i.isSelf ? "message-self" : "message-other"
2287
+ ])
2288
+ }, [
2289
+ e("div", In, [
2290
+ e("img", {
2291
+ src: i.isSelf ? c(I) : F.value.avatar,
2292
+ class: "avatar-sm"
2293
+ }, null, 8, zn)
2294
+ ]),
2295
+ e("div", {
2296
+ class: K([
2297
+ "message-content-wrapper",
2298
+ i.isSelf ? "content-self" : "content-other"
2299
+ ])
2300
+ }, [
2301
+ i.isSelf ? U("", !0) : (n(), v("div", Rn, _(F.value.name), 1)),
2302
+ e("div", Ln, [
2303
+ i.type === "text" ? (n(), v("div", {
2304
+ key: 0,
2305
+ class: K([
2306
+ "message-bubble",
2307
+ i.isSelf ? "bubble-self" : "bubble-other"
2308
+ ])
2309
+ }, _(i.text), 3)) : i.type === "file" && i.fileType === "image" ? (n(), v("div", {
2310
+ key: 1,
2311
+ class: K([
2312
+ "message-bubble",
2313
+ "image-bubble",
2314
+ i.isSelf ? "bubble-self" : "bubble-other"
2315
+ ]),
2316
+ onClick: (pt) => Oe(i.fileUrl)
2317
+ }, [
2318
+ e("img", {
2319
+ src: i.fileUrl,
2320
+ alt: i.fileName,
2321
+ class: "message-image",
2322
+ onError: ot
2323
+ }, null, 40, Mn),
2324
+ i.fileSize ? (n(), v("div", Dn, _(Ne(i.fileSize)), 1)) : U("", !0)
2325
+ ], 10, Tn)) : i.type === "file" ? (n(), v("div", {
2326
+ key: 2,
2327
+ class: K([
2328
+ "message-bubble",
2329
+ "file-bubble",
2330
+ i.isSelf ? "bubble-self" : "bubble-other"
2331
+ ]),
2332
+ onClick: (pt) => Oe(i.fileUrl)
2333
+ }, [
2334
+ e("div", qn, [
2335
+ e("div", Wn, [
2336
+ p(y, { size: 28 }, {
2337
+ default: b(() => [
2338
+ p(c(Vt))
2339
+ ]),
2340
+ _: 1
2341
+ })
2342
+ ]),
2343
+ e("div", Bn, [
2344
+ e("div", Kn, _(i.fileName || i.text), 1),
2345
+ e("div", Pn, [
2346
+ p(y, { size: 12 }, {
2347
+ default: b(() => [
2348
+ p(c(St))
2349
+ ]),
2350
+ _: 1
2351
+ }),
2352
+ s[19] || (s[19] = e("span", null, "点击下载", -1)),
2353
+ i.fileSize ? (n(), v("span", Nn, "· " + _(Ne(i.fileSize)), 1)) : U("", !0)
2354
+ ])
2355
+ ])
2356
+ ])
2357
+ ], 10, En)) : U("", !0),
2358
+ e("div", {
2359
+ class: K([
2360
+ "message-time",
2361
+ i.isSelf ? "time-right" : "time-left"
2362
+ ])
2363
+ }, _(c(he)(i.time)), 3)
2364
+ ])
2365
+ ], 2)
2366
+ ], 2))), 128))
2367
+ ], 512),
2368
+ e("div", Hn, [
2369
+ q.value.length > 0 ? (n(), v("div", On, [
2370
+ (n(!0), v(se, null, ae(q.value, (i, me) => (n(), v("div", {
2371
+ key: i.id,
2372
+ class: "pending-file"
2373
+ }, [
2374
+ i.isImage ? (n(), v("div", jn, [
2375
+ e("img", {
2376
+ src: i.previewUrl,
2377
+ alt: i.name,
2378
+ class: "pending-image"
2379
+ }, null, 8, Xn),
2380
+ e("button", {
2381
+ onClick: (pt) => Pe(me),
2382
+ class: "remove-file-btn"
2383
+ }, " × ", 8, Yn)
2384
+ ])) : (n(), v("div", Gn, [
2385
+ p(y, { class: "pending-file-icon" }, {
2386
+ default: b(() => [
2387
+ p(c(Je))
2388
+ ]),
2389
+ _: 1
2390
+ }),
2391
+ e("span", Jn, _(i.name), 1),
2392
+ e("button", {
2393
+ onClick: (pt) => Pe(me),
2394
+ class: "remove-file-btn"
2395
+ }, " × ", 8, Qn)
2396
+ ]))
2397
+ ]))), 128))
2398
+ ])) : U("", !0),
2399
+ w.config.modules.fileUpload ? (n(), v("div", Zn, [
2400
+ p(y, { class: "action-icon" }, {
1684
2401
  default: b(() => [
1685
- h(u(Xe))
2402
+ p(c(Re))
1686
2403
  ]),
1687
2404
  _: 1
1688
2405
  }),
1689
- l[24] || (l[24] = se(" 个人信息 ", -1))
2406
+ p(y, {
2407
+ class: "action-icon",
2408
+ onClick: nt
2409
+ }, {
2410
+ default: b(() => [
2411
+ p(c(Je))
2412
+ ]),
2413
+ _: 1
2414
+ }),
2415
+ p(y, { class: "action-icon" }, {
2416
+ default: b(() => [
2417
+ p(c(Ft))
2418
+ ]),
2419
+ _: 1
2420
+ })
2421
+ ])) : U("", !0),
2422
+ e("div", el, [
2423
+ bt(e("textarea", {
2424
+ "onUpdate:modelValue": s[4] || (s[4] = (i) => Ce(S) ? S.value = i : null),
2425
+ onKeydown: kt(Ye(He, ["prevent"]), ["enter"]),
2426
+ onPaste: it,
2427
+ placeholder: "输入消息或粘贴文件...",
2428
+ class: "message-input",
2429
+ rows: "3"
2430
+ }, null, 40, tl), [
2431
+ [wt, c(S)]
2432
+ ])
1690
2433
  ]),
1691
- N.value ? F("", !0) : (i(), H(fe, {
1692
- key: 0,
2434
+ e("div", sl, [
2435
+ p(ue, {
2436
+ type: "primary",
2437
+ disabled: !c(S).trim() && q.value.length === 0,
2438
+ onClick: He,
2439
+ class: "send-btn"
2440
+ }, {
2441
+ default: b(() => [...s[20] || (s[20] = [
2442
+ J(" 发送 ", -1)
2443
+ ])]),
2444
+ _: 1
2445
+ }, 8, ["disabled"])
2446
+ ]),
2447
+ e("input", {
2448
+ ref_key: "fileInputRef",
2449
+ ref: E,
2450
+ type: "file",
2451
+ multiple: "",
2452
+ class: "hidden-file-input",
2453
+ onChange: lt
2454
+ }, null, 544)
2455
+ ])
2456
+ ])) : O.value ? U("", !0) : (n(), v("div", al, [
2457
+ p(y, {
2458
+ size: 64,
2459
+ class: "empty-icon"
2460
+ }, {
2461
+ default: b(() => [
2462
+ p(c(It))
2463
+ ]),
2464
+ _: 1
2465
+ }),
2466
+ e("div", nl, _(ee.value === "apply" ? "在左侧选择好友申请" : "在左侧选择好友开始聊天"), 1)
2467
+ ]))
2468
+ ]),
2469
+ j.value ? (n(), v("div", ll, [
2470
+ s[22] || (s[22] = e("div", { class: "detail-header" }, "聊天详情", -1)),
2471
+ e("div", il, [
2472
+ e("div", ol, [
2473
+ e("img", {
2474
+ src: (Se = F.value) == null ? void 0 : Se.avatar,
2475
+ alt: (o = F.value) == null ? void 0 : o.name,
2476
+ class: "detail-avatar"
2477
+ }, null, 8, rl),
2478
+ e("div", cl, _((te = F.value) == null ? void 0 : te.name), 1),
2479
+ s[21] || (s[21] = e("div", { class: "detail-actions" }, [
2480
+ e("div", { class: "detail-action-item" }, "查找聊天记录"),
2481
+ e("div", { class: "detail-action-item" }, "清空聊天记录")
2482
+ ], -1))
2483
+ ])
2484
+ ])
2485
+ ])) : U("", !0)
2486
+ ]),
2487
+ p(ze, {
2488
+ modelValue: c(ne),
2489
+ "onUpdate:modelValue": s[6] || (s[6] = (i) => Ce(ne) ? ne.value = i : null),
2490
+ title: "添加好友",
2491
+ width: "500px",
2492
+ "append-to-body": ""
2493
+ }, {
2494
+ default: b(() => [
2495
+ e("div", dl, [
2496
+ e("div", ul, [
2497
+ p(V, {
2498
+ modelValue: c(_e),
2499
+ "onUpdate:modelValue": s[5] || (s[5] = (i) => Ce(_e) ? _e.value = i : null),
2500
+ placeholder: "搜索用户",
2501
+ "prefix-icon": c(Le)
2502
+ }, null, 8, ["modelValue", "prefix-icon"])
2503
+ ])
2504
+ ]),
2505
+ e("div", vl, [
2506
+ c(R) ? (n(), B(Y, {
2507
+ key: 0,
2508
+ description: "加载中..."
2509
+ })) : c(fe).length === 0 ? (n(), B(Y, {
2510
+ key: 1,
2511
+ description: "暂无用户"
2512
+ })) : (n(!0), v(se, { key: 2 }, ae(c(fe), (i) => (n(), v("div", {
2513
+ key: i.username,
2514
+ class: "available-user-item"
2515
+ }, [
2516
+ e("div", pl, [
2517
+ e("img", {
2518
+ src: `https://api.dicebear.com/7.x/avataaars/svg?seed=${i.username}`,
2519
+ alt: i.username,
2520
+ class: "available-user-avatar"
2521
+ }, null, 8, ml),
2522
+ e("div", fl, _(i.username), 1)
2523
+ ]),
2524
+ p(ue, {
1693
2525
  type: "primary",
1694
2526
  size: "small",
1695
- onClick: dt,
1696
- class: "rounded-full"
2527
+ onClick: (me) => c(De)(i)
1697
2528
  }, {
1698
- default: b(() => [...l[25] || (l[25] = [
1699
- se(" 编辑 ", -1)
2529
+ default: b(() => [...s[23] || (s[23] = [
2530
+ J("添加", -1)
1700
2531
  ])]),
1701
2532
  _: 1
1702
- }))
1703
- ]),
1704
- t("div", Va, [
1705
- t("div", null, [
1706
- l[26] || (l[26] = t("label", { class: "block text-sm text-gray-600 mb-2 font-medium" }, "昵称", -1)),
1707
- N.value ? (i(), H(S, {
1708
- key: 0,
1709
- modelValue: K.value.nickname,
1710
- "onUpdate:modelValue": l[7] || (l[7] = (s) => K.value.nickname = s),
1711
- placeholder: "请输入昵称",
1712
- size: "large"
1713
- }, null, 8, ["modelValue"])) : (i(), f("div", Fa, w(u(k).nickname || "未设置"), 1))
1714
- ]),
1715
- t("div", null, [
1716
- l[27] || (l[27] = t("label", { class: "block text-sm text-gray-600 mb-2 font-medium" }, "邮箱", -1)),
1717
- N.value ? (i(), H(S, {
1718
- key: 0,
1719
- modelValue: K.value.email,
1720
- "onUpdate:modelValue": l[8] || (l[8] = (s) => K.value.email = s),
1721
- placeholder: "请输入邮箱",
1722
- size: "large"
1723
- }, null, 8, ["modelValue"])) : (i(), f("div", Ra, w(u(k).email || "未设置"), 1))
1724
- ]),
1725
- t("div", null, [
1726
- l[28] || (l[28] = t("label", { class: "block text-sm text-gray-600 mb-2 font-medium" }, "手机号", -1)),
1727
- N.value ? (i(), H(S, {
2533
+ }, 8, ["onClick"])
2534
+ ]))), 128))
2535
+ ])
2536
+ ]),
2537
+ _: 1
2538
+ }, 8, ["modelValue"]),
2539
+ p(ze, {
2540
+ modelValue: l.value,
2541
+ "onUpdate:modelValue": s[11] || (s[11] = (i) => l.value = i),
2542
+ title: "个人设置",
2543
+ width: "560px",
2544
+ "close-on-click-modal": !1,
2545
+ "append-to-body": "",
2546
+ class: "settings-dialog"
2547
+ }, {
2548
+ default: b(() => [
2549
+ e("div", hl, [
2550
+ e("div", gl, [
2551
+ e("div", _l, [
2552
+ e("img", {
2553
+ src: c(I),
2554
+ alt: "头像",
2555
+ class: "settings-avatar"
2556
+ }, null, 8, yl),
2557
+ w.config.modules.avatarCrop ? (n(), v("div", {
1728
2558
  key: 0,
1729
- modelValue: K.value.phone,
1730
- "onUpdate:modelValue": l[9] || (l[9] = (s) => K.value.phone = s),
1731
- placeholder: "请输入手机号",
1732
- size: "large"
1733
- }, null, 8, ["modelValue"])) : (i(), f("div", Ia, w(u(k).phone || "未设置"), 1))
2559
+ class: "settings-avatar-edit",
2560
+ onClick: at
2561
+ }, [
2562
+ p(y, {
2563
+ size: 18,
2564
+ class: "settings-avatar-icon"
2565
+ }, {
2566
+ default: b(() => [
2567
+ p(c(zt))
2568
+ ]),
2569
+ _: 1
2570
+ })
2571
+ ])) : U("", !0),
2572
+ e("input", {
2573
+ ref_key: "avatarInputRef",
2574
+ ref: A,
2575
+ type: "file",
2576
+ accept: "image/*",
2577
+ class: "hidden-avatar-input",
2578
+ onChange: rt
2579
+ }, null, 544)
1734
2580
  ]),
1735
- t("div", null, [
1736
- l[29] || (l[29] = t("label", { class: "block text-sm text-gray-600 mb-2 font-medium" }, "个人简介", -1)),
1737
- N.value ? (i(), H(S, {
2581
+ e("div", bl, [
2582
+ e("div", kl, _(c(T).nickname || c(N)), 1),
2583
+ e("div", wl, "@" + _(c(N)), 1)
2584
+ ])
2585
+ ]),
2586
+ e("div", Cl, [
2587
+ e("div", Ul, [
2588
+ e("div", $l, [
2589
+ p(y, null, {
2590
+ default: b(() => [
2591
+ p(c(Ge))
2592
+ ]),
2593
+ _: 1
2594
+ }),
2595
+ s[24] || (s[24] = J(" 个人信息 ", -1))
2596
+ ]),
2597
+ D.value ? U("", !0) : (n(), B(ue, {
1738
2598
  key: 0,
1739
- modelValue: K.value.bio,
1740
- "onUpdate:modelValue": l[10] || (l[10] = (s) => K.value.bio = s),
1741
- type: "textarea",
1742
- rows: 4,
1743
- placeholder: "介绍一下自己吧...",
1744
- size: "large"
1745
- }, null, 8, ["modelValue"])) : (i(), f("div", La, w(u(k).bio || "这个人很懒,什么都没写~"), 1))
1746
- ]),
1747
- N.value ? (i(), f("div", Ta, [
1748
- h(fe, {
1749
- size: "default",
1750
- onClick: ut
1751
- }, {
1752
- default: b(() => [...l[30] || (l[30] = [
1753
- se("取消", -1)
1754
- ])]),
1755
- _: 1
1756
- }),
1757
- h(fe, {
1758
2599
  type: "primary",
1759
- size: "default",
1760
- loading: n.value,
1761
- onClick: ft
2600
+ size: "small",
2601
+ onClick: dt,
2602
+ class: "settings-edit-btn"
1762
2603
  }, {
1763
- default: b(() => [...l[31] || (l[31] = [
1764
- se("保存更改", -1)
2604
+ default: b(() => [...s[25] || (s[25] = [
2605
+ J(" 编辑 ", -1)
1765
2606
  ])]),
1766
2607
  _: 1
1767
- }, 8, ["loading"])
1768
- ])) : F("", !0)
2608
+ }))
2609
+ ]),
2610
+ e("div", xl, [
2611
+ e("div", Al, [
2612
+ s[26] || (s[26] = e("label", { class: "settings-form-label" }, "昵称", -1)),
2613
+ D.value ? (n(), B(V, {
2614
+ key: 0,
2615
+ modelValue: X.value.nickname,
2616
+ "onUpdate:modelValue": s[7] || (s[7] = (i) => X.value.nickname = i),
2617
+ placeholder: "请输入昵称",
2618
+ size: "large"
2619
+ }, null, 8, ["modelValue"])) : (n(), v("div", Vl, _(c(T).nickname || "未设置"), 1))
2620
+ ]),
2621
+ e("div", Sl, [
2622
+ s[27] || (s[27] = e("label", { class: "settings-form-label" }, "邮箱", -1)),
2623
+ D.value ? (n(), B(V, {
2624
+ key: 0,
2625
+ modelValue: X.value.email,
2626
+ "onUpdate:modelValue": s[8] || (s[8] = (i) => X.value.email = i),
2627
+ placeholder: "请输入邮箱",
2628
+ size: "large"
2629
+ }, null, 8, ["modelValue"])) : (n(), v("div", Fl, _(c(T).email || "未设置"), 1))
2630
+ ]),
2631
+ e("div", Il, [
2632
+ s[28] || (s[28] = e("label", { class: "settings-form-label" }, "手机号", -1)),
2633
+ D.value ? (n(), B(V, {
2634
+ key: 0,
2635
+ modelValue: X.value.phone,
2636
+ "onUpdate:modelValue": s[9] || (s[9] = (i) => X.value.phone = i),
2637
+ placeholder: "请输入手机号",
2638
+ size: "large"
2639
+ }, null, 8, ["modelValue"])) : (n(), v("div", zl, _(c(T).phone || "未设置"), 1))
2640
+ ]),
2641
+ e("div", Rl, [
2642
+ s[29] || (s[29] = e("label", { class: "settings-form-label" }, "个人简介", -1)),
2643
+ D.value ? (n(), B(V, {
2644
+ key: 0,
2645
+ modelValue: X.value.bio,
2646
+ "onUpdate:modelValue": s[10] || (s[10] = (i) => X.value.bio = i),
2647
+ type: "textarea",
2648
+ rows: 4,
2649
+ placeholder: "介绍一下自己吧...",
2650
+ size: "large"
2651
+ }, null, 8, ["modelValue"])) : (n(), v("div", Ll, _(c(T).bio || "这个人很懒,什么都没写~"), 1))
2652
+ ]),
2653
+ D.value ? (n(), v("div", Tl, [
2654
+ p(ue, {
2655
+ size: "default",
2656
+ onClick: ut
2657
+ }, {
2658
+ default: b(() => [...s[30] || (s[30] = [
2659
+ J("取消", -1)
2660
+ ])]),
2661
+ _: 1
2662
+ }),
2663
+ p(ue, {
2664
+ type: "primary",
2665
+ size: "default",
2666
+ loading: ge.value,
2667
+ onClick: vt
2668
+ }, {
2669
+ default: b(() => [...s[31] || (s[31] = [
2670
+ J("保存更改", -1)
2671
+ ])]),
2672
+ _: 1
2673
+ }, 8, ["loading"])
2674
+ ])) : U("", !0)
2675
+ ])
1769
2676
  ])
1770
2677
  ])
1771
- ])
1772
- ]),
1773
- _: 1
1774
- }, 8, ["modelValue"]),
1775
- h(Nt, {
1776
- modelValue: c.value,
1777
- "onUpdate:modelValue": l[12] || (l[12] = (s) => c.value = s),
1778
- src: Z.value,
1779
- onConfirm: ct
1780
- }, null, 8, ["modelValue", "src"]),
1781
- re.value.visible ? (i(), f("div", {
1782
- key: 0,
1783
- class: "context-menu fixed bg-white rounded-lg shadow-lg border py-1 z-50",
1784
- style: wt({ left: re.value.x + "px", top: re.value.y + "px" })
1785
- }, [
1786
- t("div", {
1787
- class: "px-4 py-2 hover:bg-gray-100 cursor-pointer",
1788
- onClick: Ze
1789
- }, "删除聊天")
1790
- ], 4)) : F("", !0)
1791
- ]),
2678
+ ]),
2679
+ _: 1
2680
+ }, 8, ["modelValue"]),
2681
+ p(Tt, {
2682
+ modelValue: d.value,
2683
+ "onUpdate:modelValue": s[12] || (s[12] = (i) => d.value = i),
2684
+ src: le.value,
2685
+ onConfirm: ct
2686
+ }, null, 8, ["modelValue", "src"]),
2687
+ pe.value.visible ? (n(), v("div", {
2688
+ key: 0,
2689
+ class: "context-menu",
2690
+ style: Ct({ left: pe.value.x + "px", top: pe.value.y + "px" })
2691
+ }, [
2692
+ e("div", {
2693
+ class: "context-menu-item",
2694
+ onClick: Ze
2695
+ }, "删除聊天")
2696
+ ], 4)) : U("", !0)
2697
+ ];
2698
+ }),
1792
2699
  _: 1
1793
2700
  }, 8, ["modelValue", "width"]);
1794
2701
  };
1795
2702
  }
1796
- }, Ka = /* @__PURE__ */ Ge(za, [["__scopeId", "data-v-fc6ab10a"]]), ja = {
2703
+ }, Pl = /* @__PURE__ */ ht(Ml, [["__scopeId", "data-v-a76a4ef3"]]), Dl = {
1797
2704
  // API 配置
1798
2705
  api: {
1799
2706
  baseUrl: "",
@@ -1840,6 +2747,10 @@ const Ge = (y, e) => {
1840
2747
  },
1841
2748
  // 自定义请求头
1842
2749
  headers: {},
2750
+ // 请求拦截器 (可选)
2751
+ requestInterceptors: [],
2752
+ // 响应拦截器 (可选)
2753
+ responseInterceptors: [],
1843
2754
  // WebSocket 配置
1844
2755
  websocket: {
1845
2756
  maxReconnectAttempts: 5,
@@ -1852,29 +2763,30 @@ const Ge = (y, e) => {
1852
2763
  allowedTypes: ["*"]
1853
2764
  }
1854
2765
  };
1855
- function Wa(y = {}) {
1856
- const e = Je(ja, y);
1857
- return e.api.baseUrl || console.warn("[VueChatKit] 请配置 api.baseUrl"), e.api.websocketUrl || console.warn("[VueChatKit] 请配置 api.websocketUrl"), e.user.username || console.warn("[VueChatKit] 请配置 user.username"), e;
2766
+ function Nl(w = {}) {
2767
+ const t = Mt(Dl, w);
2768
+ return t.api.baseUrl || console.warn("[VueChatKit] 请配置 api.baseUrl"), t.api.websocketUrl || console.warn("[VueChatKit] 请配置 api.websocketUrl"), t.user.username || console.warn("[VueChatKit] 请配置 user.username"), t;
1858
2769
  }
1859
- function Je(y, e) {
1860
- const a = { ...y };
1861
- for (const o in e)
1862
- e[o] && typeof e[o] == "object" && !Array.isArray(e[o]) ? a[o] = Je(y[o] || {}, e[o]) : a[o] = e[o];
2770
+ function Mt(w, t) {
2771
+ const a = { ...w };
2772
+ for (const m in t)
2773
+ t[m] && typeof t[m] == "object" && !Array.isArray(t[m]) ? a[m] = Mt(w[m] || {}, t[m]) : a[m] = t[m];
1863
2774
  return a;
1864
2775
  }
1865
- const Ba = {
1866
- install(y) {
1867
- y.component("ChatWindow", ChatWindow), y.component("AvatarCrop", AvatarCrop);
2776
+ const Hl = {
2777
+ install(w) {
2778
+ w.component("ChatPanel", ChatPanel), w.component("ChatWindow", ChatWindow), w.component("AvatarCrop", AvatarCrop);
1868
2779
  }
1869
2780
  };
1870
2781
  export {
1871
- Nt as AvatarCrop,
1872
- zt as ChatApi,
1873
- Lt as ChatWebSocket,
1874
- Ka as ChatWindow,
1875
- Tt as HttpClient,
1876
- Ba as VueChatKit,
1877
- Wa as createChatConfig,
1878
- Ba as default,
1879
- jt as useChat
2782
+ Tt as AvatarCrop,
2783
+ ft as ChatApi,
2784
+ Kl as ChatPanel,
2785
+ Et as ChatWebSocket,
2786
+ Pl as ChatWindow,
2787
+ qt as HttpClient,
2788
+ Hl as VueChatKit,
2789
+ Nl as createChatConfig,
2790
+ Hl as default,
2791
+ Lt as useChat
1880
2792
  };