@burdenoff/microfe-conversations 2026.530.1 → 2026.601.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.
- package/dist/conversations/ConversationsAdminRoutes.js +19 -21
- package/dist/conversations/ConversationsAdminRoutes.js.map +1 -1
- package/dist/conversations/hooks/useConversationQueries.js +46 -36
- package/dist/conversations/hooks/useConversationQueries.js.map +1 -1
- package/dist/conversations/hooks/useMessageQueries.js +2 -1
- package/dist/conversations/hooks/useMessageQueries.js.map +1 -1
- package/dist/conversations/hooks/useMessageSubscriptions.js +22 -23
- package/dist/conversations/hooks/useMessageSubscriptions.js.map +1 -1
- package/dist/conversations/pages/ConversationAdminPages.js +60 -38
- package/dist/conversations/pages/ConversationAdminPages.js.map +1 -1
- package/dist/conversations/pages/ConversationDetailPage.js +237 -179
- package/dist/conversations/pages/ConversationDetailPage.js.map +1 -1
- package/dist/conversations/providers/ConversationsProvider.js +75 -67
- package/dist/conversations/providers/ConversationsProvider.js.map +1 -1
- package/dist/generated/wspace-operations.js +82 -58
- package/dist/generated/wspace-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,180 +9,223 @@ import { PermissionGuard as o } from "../components/PermissionGuard.js";
|
|
|
9
9
|
import { CONVERSATIONS_PERMISSIONS as s } from "../constants/permissions.js";
|
|
10
10
|
import { nativeImpact as ae, nativeNotify as c } from "../../utils/nativeBridge.js";
|
|
11
11
|
import { useCallback as l, useEffect as u, useMemo as d, useRef as f, useState as p } from "react";
|
|
12
|
-
import { Archive as oe, ArrowLeft as se, Bell as ce, BellOff as le, ExternalLink as ue, Hash as de, Loader2 as fe,
|
|
13
|
-
import { useNavigate as
|
|
14
|
-
import { useEventBus as
|
|
12
|
+
import { Archive as oe, ArrowLeft as se, Bell as ce, BellOff as le, ExternalLink as ue, Hash as de, Loader2 as fe, LogOut as pe, MessageCircle as me, MoreVertical as he, Pin as ge, PinOff as _e, SendHorizontal as ve, Users as ye, X as be } from "lucide-react";
|
|
13
|
+
import { useNavigate as xe, useParams as Se } from "react-router-dom";
|
|
14
|
+
import { useEventBus as Ce } from "@burdenoff/fe-libs/shared/events";
|
|
15
15
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
16
|
-
import { useI18n as
|
|
16
|
+
import { useI18n as we } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
17
17
|
//#region src/conversations/pages/ConversationDetailPage.tsx
|
|
18
|
-
var g = 100;
|
|
18
|
+
var g = 100, Te = 3e4;
|
|
19
19
|
function _() {
|
|
20
|
-
let { conversationId: o } =
|
|
21
|
-
let n =
|
|
20
|
+
let { conversationId: o } = Se(), s = xe(), { basePath: _, currentUser: Ee } = e(), b = Ce(), { t: x } = we(), S = l((e, t) => {
|
|
21
|
+
let n = x(e);
|
|
22
22
|
return n === e ? t : n;
|
|
23
|
-
}, { clearMessageDraft:
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
}, [x]), { clearMessageDraft: C, isParticipantsPanelOpen: w, messageDrafts: De, setMessageDraft: T, toggleParticipantsPanel: E } = n(), [D, O] = p(De[o ?? ""] ?? ""), [k, A] = p([]), j = f(null), { conversation: M, members: N, membersTotalCount: Oe, loading: ke, error: Ae } = a(o ?? ""), { messages: P, loading: je, error: Me, refetch: Ne } = te(o ?? "", {
|
|
24
|
+
first: g,
|
|
25
|
+
pollInterval: Te
|
|
26
|
+
});
|
|
27
|
+
ie(o, g);
|
|
28
|
+
let { sendMessage: Pe, loading: F } = re(), { editMessage: Fe, loading: I } = ee(), { deleteMessage: Ie, addReaction: Le, removeReaction: Re, pinMessage: ze, unpinMessage: Be } = ne(), { archiveConversation: Ve, pinConversation: He, unpinConversation: Ue, muteConversation: We, unmuteConversation: Ge, leaveConversation: Ke } = i(), [L, R] = p(!1), [z, B] = p(null), [V, H] = p(""), [U, W] = p(null), G = f(null), K = Ee?.id ?? "", q = M?.sourceContext, J = d(() => {
|
|
26
29
|
let e = /* @__PURE__ */ new Map();
|
|
27
|
-
for (let t of
|
|
28
|
-
for (let t of
|
|
30
|
+
for (let t of k) t.conversationId === o && e.set(t.id, t);
|
|
31
|
+
for (let t of P) e.set(t.id, t);
|
|
29
32
|
return Array.from(e.values()).sort((e, t) => new Date(e.createdAt).getTime() - new Date(t.createdAt).getTime());
|
|
30
33
|
}, [
|
|
31
34
|
o,
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
k,
|
|
36
|
+
P
|
|
34
37
|
]);
|
|
35
38
|
u(() => {
|
|
36
|
-
|
|
37
|
-
}, [
|
|
38
|
-
|
|
39
|
+
j.current?.scrollIntoView({ behavior: "smooth" });
|
|
40
|
+
}, [J.length]), u(() => {
|
|
41
|
+
A([]);
|
|
39
42
|
}, [o]), u(() => {
|
|
40
|
-
if (
|
|
41
|
-
let e = new Set(
|
|
42
|
-
|
|
43
|
+
if (k.length === 0 || P.length === 0) return;
|
|
44
|
+
let e = new Set(P.map((e) => e.id));
|
|
45
|
+
A((t) => {
|
|
43
46
|
let n = t.filter((t) => !e.has(t.id));
|
|
44
47
|
return n.length === t.length ? t : n;
|
|
45
48
|
});
|
|
46
|
-
}, [
|
|
49
|
+
}, [
|
|
50
|
+
k.length,
|
|
51
|
+
P,
|
|
52
|
+
A
|
|
53
|
+
]), u(() => {
|
|
47
54
|
if (o) {
|
|
48
|
-
if (
|
|
49
|
-
|
|
55
|
+
if (D.trim()) {
|
|
56
|
+
T(o, D);
|
|
50
57
|
return;
|
|
51
58
|
}
|
|
52
|
-
|
|
59
|
+
C(o);
|
|
53
60
|
}
|
|
54
61
|
}, [
|
|
55
|
-
|
|
62
|
+
D,
|
|
56
63
|
o,
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
T,
|
|
65
|
+
C
|
|
59
66
|
]);
|
|
60
|
-
let
|
|
67
|
+
let Y = d(() => {
|
|
61
68
|
let e = /* @__PURE__ */ new Map();
|
|
62
|
-
for (let t of
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
for (let t of J) !t.authorId || e.has(t.authorId) || t.sender.name && e.set(t.authorId, t.sender.name);
|
|
70
|
+
return e;
|
|
71
|
+
}, [J]), X = d(() => N.length > 0 ? N.filter((e) => e.status === "ACTIVE" && !e.leftAt).map((e) => ({
|
|
72
|
+
id: e.userId,
|
|
73
|
+
name: Y.get(e.userId) || e.customTitle || S("conversations.member", "Member"),
|
|
74
|
+
role: e.role
|
|
75
|
+
})) : Array.from(Y.entries()).map(([e, t]) => ({
|
|
76
|
+
id: e,
|
|
77
|
+
name: t,
|
|
78
|
+
role: S("conversations.member", "Member")
|
|
79
|
+
})), [
|
|
80
|
+
N,
|
|
81
|
+
Y,
|
|
82
|
+
S
|
|
83
|
+
]), Z = M?.memberCount ? Math.max(M.memberCount - X.length, 0) : 0, Q = l(async () => {
|
|
84
|
+
if (!o || !D.trim() || F) return;
|
|
85
|
+
let e = await Pe({
|
|
70
86
|
conversationId: o,
|
|
71
|
-
content:
|
|
87
|
+
content: D.trim(),
|
|
72
88
|
type: "TEXT",
|
|
73
|
-
parentMessageId:
|
|
89
|
+
parentMessageId: U?.id,
|
|
74
90
|
refetchFirst: g
|
|
75
91
|
});
|
|
76
|
-
e && (
|
|
92
|
+
e && (A((t) => [...t, e]), b.emit("conversations.message.sent", {
|
|
77
93
|
messageId: e.id,
|
|
78
94
|
conversationId: o
|
|
79
|
-
}),
|
|
95
|
+
}), O(""), W(null), C(o));
|
|
80
96
|
}, [
|
|
81
97
|
b,
|
|
82
98
|
o,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
]),
|
|
89
|
-
e.key !== "Enter" || e.shiftKey || (e.preventDefault(),
|
|
90
|
-
}, [
|
|
99
|
+
D,
|
|
100
|
+
F,
|
|
101
|
+
Pe,
|
|
102
|
+
C,
|
|
103
|
+
U
|
|
104
|
+
]), qe = l((e) => {
|
|
105
|
+
e.key !== "Enter" || e.shiftKey || (e.preventDefault(), Q());
|
|
106
|
+
}, [Q]);
|
|
91
107
|
u(() => {
|
|
92
108
|
o && b.emit("conversations.conversation.opened", { conversationId: o });
|
|
93
109
|
}, [b, o]), u(() => {
|
|
94
|
-
if (!
|
|
110
|
+
if (!L) return;
|
|
95
111
|
let e = (e) => {
|
|
96
|
-
|
|
112
|
+
G.current && !G.current.contains(e.target) && R(!1);
|
|
97
113
|
};
|
|
98
114
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
99
|
-
}, [
|
|
100
|
-
let
|
|
101
|
-
|
|
115
|
+
}, [L]);
|
|
116
|
+
let Je = l((e) => {
|
|
117
|
+
W({
|
|
102
118
|
id: e.id,
|
|
103
119
|
content: e.content,
|
|
104
120
|
sender: e.sender.name
|
|
105
121
|
});
|
|
106
|
-
}, []),
|
|
122
|
+
}, []), Ye = l(async (e, t) => {
|
|
107
123
|
try {
|
|
108
|
-
await
|
|
124
|
+
await Le(e, t);
|
|
109
125
|
} catch {
|
|
110
|
-
await
|
|
126
|
+
await Re(e, t).catch(() => {});
|
|
111
127
|
}
|
|
112
|
-
}, [
|
|
113
|
-
|
|
114
|
-
}, []),
|
|
115
|
-
!
|
|
128
|
+
}, [Le, Re]), Xe = l((e) => {
|
|
129
|
+
B(e.id), H(e.content);
|
|
130
|
+
}, []), Ze = l(async () => {
|
|
131
|
+
!z || !V.trim() || I || (await Fe(z, V.trim()), B(null), H(""));
|
|
116
132
|
}, [
|
|
117
|
-
W,
|
|
118
|
-
K,
|
|
119
133
|
z,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
V,
|
|
135
|
+
I,
|
|
136
|
+
Fe
|
|
137
|
+
]), $ = l(() => {
|
|
138
|
+
B(null), H("");
|
|
139
|
+
}, []), Qe = l(async (e) => {
|
|
140
|
+
if (window.confirm(S("conversations.confirmDeleteMessage", "Delete this message? This action cannot be undone."))) {
|
|
141
|
+
ae("medium");
|
|
142
|
+
try {
|
|
143
|
+
await Ie(e), Ne(), c("success");
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error("[microfe-conversations] message delete failed", e), c("error");
|
|
146
|
+
}
|
|
129
147
|
}
|
|
130
|
-
}, [
|
|
148
|
+
}, [
|
|
149
|
+
Ie,
|
|
150
|
+
Ne,
|
|
151
|
+
S
|
|
152
|
+
]), $e = l(async (e, t) => {
|
|
131
153
|
if (t) {
|
|
132
|
-
await
|
|
154
|
+
await Be(e);
|
|
133
155
|
return;
|
|
134
156
|
}
|
|
135
|
-
await
|
|
136
|
-
}, [
|
|
137
|
-
o && (
|
|
157
|
+
await ze(e);
|
|
158
|
+
}, [ze, Be]), et = l(async () => {
|
|
159
|
+
o && (M?.isPinned ? await Ue(o) : await He(o), R(!1));
|
|
138
160
|
}, [
|
|
139
161
|
o,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
]),
|
|
144
|
-
o && (
|
|
162
|
+
M?.isPinned,
|
|
163
|
+
He,
|
|
164
|
+
Ue
|
|
165
|
+
]), tt = l(async () => {
|
|
166
|
+
o && (M?.isMuted ? await Ge(o) : await We(o), R(!1));
|
|
145
167
|
}, [
|
|
146
168
|
o,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
]),
|
|
151
|
-
|
|
169
|
+
M?.isMuted,
|
|
170
|
+
We,
|
|
171
|
+
Ge
|
|
172
|
+
]), nt = l(async () => {
|
|
173
|
+
if (o) try {
|
|
174
|
+
await Ve(o), b.emit("conversations.conversation.archived", { conversationId: o }), R(!1), s(_ || "/conversations");
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.error("[microfe-conversations] conversation archive failed", e), c("error");
|
|
177
|
+
}
|
|
152
178
|
}, [
|
|
153
|
-
|
|
179
|
+
Ve,
|
|
154
180
|
_,
|
|
155
181
|
b,
|
|
156
182
|
o,
|
|
157
183
|
s
|
|
158
|
-
]),
|
|
159
|
-
if (
|
|
184
|
+
]), rt = l(async () => {
|
|
185
|
+
if (o && window.confirm(S("conversations.confirmLeaveConversation", "Leave this conversation? You will lose access unless someone adds you again."))) try {
|
|
186
|
+
await Ke(o), K && b.emit("conversations.member.removed", {
|
|
187
|
+
conversationId: o,
|
|
188
|
+
userId: K
|
|
189
|
+
}), R(!1), s(_ || "/conversations");
|
|
190
|
+
} catch (e) {
|
|
191
|
+
console.error("[microfe-conversations] conversation leave failed", e), c("error");
|
|
192
|
+
}
|
|
193
|
+
}, [
|
|
194
|
+
_,
|
|
195
|
+
b,
|
|
196
|
+
o,
|
|
197
|
+
K,
|
|
198
|
+
Ke,
|
|
199
|
+
s,
|
|
200
|
+
S
|
|
201
|
+
]), it = l(() => {
|
|
202
|
+
if (q?.contextHref) {
|
|
160
203
|
try {
|
|
161
|
-
let e = new URL(
|
|
204
|
+
let e = new URL(q.contextHref);
|
|
162
205
|
if (e.origin === window.location.origin) {
|
|
163
206
|
s(`${e.pathname}${e.search}${e.hash}`);
|
|
164
207
|
return;
|
|
165
208
|
}
|
|
166
209
|
} catch {}
|
|
167
|
-
window.location.assign(
|
|
210
|
+
window.location.assign(q.contextHref);
|
|
168
211
|
}
|
|
169
|
-
}, [s,
|
|
170
|
-
return !
|
|
212
|
+
}, [s, q?.contextHref]);
|
|
213
|
+
return !M && ke ? /* @__PURE__ */ m("div", {
|
|
171
214
|
className: "flex items-center justify-center h-[calc(100vh-64px)] text-sm text-muted-foreground",
|
|
172
|
-
children:
|
|
173
|
-
}) : !
|
|
215
|
+
children: S("conversations.loading", "Loading conversation...")
|
|
216
|
+
}) : !M || Ae ? /* @__PURE__ */ h("div", {
|
|
174
217
|
className: "flex flex-col items-center justify-center h-[calc(100vh-64px)] text-center gap-3 px-4",
|
|
175
218
|
children: [
|
|
176
|
-
/* @__PURE__ */ m(
|
|
219
|
+
/* @__PURE__ */ m(me, { className: "size-8 text-muted-foreground" }),
|
|
177
220
|
/* @__PURE__ */ m("p", {
|
|
178
221
|
className: "text-sm text-muted-foreground",
|
|
179
|
-
children:
|
|
222
|
+
children: Ae ? S("conversations.unavailable", "We couldn't load this conversation. Please try again.") : S("conversations.notFound", "Conversation not found")
|
|
180
223
|
}),
|
|
181
224
|
/* @__PURE__ */ m("button", {
|
|
182
225
|
type: "button",
|
|
183
226
|
onClick: () => s(_ || "/conversations"),
|
|
184
227
|
className: "px-3 py-2 text-sm font-medium rounded-lg border border-border hover:bg-muted/50",
|
|
185
|
-
children:
|
|
228
|
+
children: S("conversations.back", "Back to conversations")
|
|
186
229
|
})
|
|
187
230
|
]
|
|
188
231
|
}) : /* @__PURE__ */ h("div", {
|
|
@@ -204,60 +247,66 @@ function _() {
|
|
|
204
247
|
className: "min-w-0",
|
|
205
248
|
children: [/* @__PURE__ */ h("div", {
|
|
206
249
|
className: "flex items-center gap-1.5",
|
|
207
|
-
children: [
|
|
250
|
+
children: [M.type === "CHANNEL" && /* @__PURE__ */ m(de, {
|
|
208
251
|
size: 14,
|
|
209
252
|
className: "text-muted-foreground flex-shrink-0"
|
|
210
253
|
}), /* @__PURE__ */ m("h2", {
|
|
211
254
|
className: "text-sm font-semibold text-foreground truncate",
|
|
212
|
-
children:
|
|
255
|
+
children: M.title
|
|
213
256
|
})]
|
|
214
257
|
}), /* @__PURE__ */ m("p", {
|
|
215
258
|
className: "text-xs text-muted-foreground",
|
|
216
|
-
children:
|
|
259
|
+
children: M.type === "DIRECT" ? S("conversations.directConversation", "Direct conversation") : M.type === "CHANNEL" ? `${S("conversations.channel", "Channel")} · ${M.memberCount} ${S("conversations.membersCountLabel", "members")}` : M.type === "ANNOUNCEMENT" ? `${S("conversations.announcement", "Announcement")} · ${M.memberCount} ${S("conversations.membersCountLabel", "members")}` : `${M.memberCount} ${S("conversations.membersCountLabel", "members")}`
|
|
217
260
|
})]
|
|
218
261
|
})]
|
|
219
262
|
}), /* @__PURE__ */ h("div", {
|
|
220
263
|
className: "flex shrink-0 items-center gap-1",
|
|
221
264
|
children: [
|
|
222
|
-
|
|
265
|
+
q?.contextHref && /* @__PURE__ */ m(y, {
|
|
223
266
|
dataTour: "conversation-open-context",
|
|
224
267
|
icon: /* @__PURE__ */ m(ue, { size: 16 }),
|
|
225
|
-
label:
|
|
226
|
-
onClick:
|
|
268
|
+
label: S("conversations.openContext", "Open context"),
|
|
269
|
+
onClick: it
|
|
227
270
|
}),
|
|
228
|
-
|
|
271
|
+
M.isGroup && /* @__PURE__ */ m(y, {
|
|
229
272
|
dataTour: "conversation-participants-button",
|
|
230
|
-
icon: /* @__PURE__ */ m(
|
|
231
|
-
label:
|
|
232
|
-
active:
|
|
233
|
-
onClick:
|
|
273
|
+
icon: /* @__PURE__ */ m(ye, { size: 16 }),
|
|
274
|
+
label: S("conversations.participants", "Participants"),
|
|
275
|
+
active: w,
|
|
276
|
+
onClick: E
|
|
234
277
|
}),
|
|
235
278
|
/* @__PURE__ */ h("div", {
|
|
236
279
|
className: "relative",
|
|
237
|
-
ref:
|
|
280
|
+
ref: G,
|
|
238
281
|
children: [/* @__PURE__ */ m(y, {
|
|
239
|
-
icon: /* @__PURE__ */ m(
|
|
240
|
-
label:
|
|
241
|
-
active:
|
|
242
|
-
onClick: () =>
|
|
243
|
-
}),
|
|
282
|
+
icon: /* @__PURE__ */ m(he, { size: 16 }),
|
|
283
|
+
label: S("conversations.moreOptions", "More options"),
|
|
284
|
+
active: L,
|
|
285
|
+
onClick: () => R((e) => !e)
|
|
286
|
+
}), L && /* @__PURE__ */ h("div", {
|
|
244
287
|
className: "absolute right-0 top-full mt-1 w-48 bg-popover border border-border rounded-lg shadow-lg z-50 py-1 animate-in fade-in-0 zoom-in-95 duration-100",
|
|
245
288
|
children: [
|
|
246
289
|
/* @__PURE__ */ m(v, {
|
|
247
|
-
icon:
|
|
248
|
-
label:
|
|
249
|
-
onClick: () => void
|
|
290
|
+
icon: M.isPinned ? /* @__PURE__ */ m(_e, { size: 14 }) : /* @__PURE__ */ m(ge, { size: 14 }),
|
|
291
|
+
label: M.isPinned ? S("conversations.unpinConversation", "Unpin conversation") : S("conversations.pinConversation", "Pin conversation"),
|
|
292
|
+
onClick: () => void et()
|
|
250
293
|
}),
|
|
251
294
|
/* @__PURE__ */ m(v, {
|
|
252
|
-
icon:
|
|
253
|
-
label:
|
|
254
|
-
onClick: () => void
|
|
295
|
+
icon: M.isMuted ? /* @__PURE__ */ m(ce, { size: 14 }) : /* @__PURE__ */ m(le, { size: 14 }),
|
|
296
|
+
label: M.isMuted ? S("conversations.unmuteConversation", "Unmute conversation") : S("conversations.muteConversation", "Mute conversation"),
|
|
297
|
+
onClick: () => void tt()
|
|
255
298
|
}),
|
|
256
299
|
/* @__PURE__ */ m("div", { className: "h-px bg-border my-1" }),
|
|
257
300
|
/* @__PURE__ */ m(v, {
|
|
258
301
|
icon: /* @__PURE__ */ m(oe, { size: 14 }),
|
|
259
|
-
label:
|
|
260
|
-
onClick: () => void
|
|
302
|
+
label: S("conversations.archiveConversation", "Archive conversation"),
|
|
303
|
+
onClick: () => void nt(),
|
|
304
|
+
destructive: !0
|
|
305
|
+
}),
|
|
306
|
+
M.isGroup && /* @__PURE__ */ m(v, {
|
|
307
|
+
icon: /* @__PURE__ */ m(pe, { size: 14 }),
|
|
308
|
+
label: S("conversations.leaveConversation", "Leave conversation"),
|
|
309
|
+
onClick: () => void rt(),
|
|
261
310
|
destructive: !0
|
|
262
311
|
})
|
|
263
312
|
]
|
|
@@ -269,106 +318,106 @@ function _() {
|
|
|
269
318
|
/* @__PURE__ */ h("div", {
|
|
270
319
|
className: "flex-1 overflow-y-auto py-4 space-y-0.5",
|
|
271
320
|
children: [
|
|
272
|
-
|
|
321
|
+
q?.pagePath && /* @__PURE__ */ h("div", {
|
|
273
322
|
className: "mx-4 mb-4 rounded-lg border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground",
|
|
274
323
|
children: [/* @__PURE__ */ m("span", {
|
|
275
324
|
className: "font-medium text-foreground",
|
|
276
|
-
children:
|
|
277
|
-
}),
|
|
325
|
+
children: q.contextTitle || q.pagePath
|
|
326
|
+
}), q.entityType && q.entityId ? ` · ${q.entityType} ${q.entityId}` : ""]
|
|
278
327
|
}),
|
|
279
|
-
|
|
328
|
+
Me && /* @__PURE__ */ m("div", {
|
|
280
329
|
className: "mx-4 mb-4 rounded-lg border border-status-warning-border bg-status-warning-bg px-3 py-2 text-sm text-status-warning-text",
|
|
281
|
-
children:
|
|
330
|
+
children: S("conversations.messagesUnavailable", "Messages couldn't be loaded right now. The conversation header and actions are still available.")
|
|
282
331
|
}),
|
|
283
|
-
|
|
332
|
+
je && /* @__PURE__ */ h("div", {
|
|
284
333
|
className: "mx-4 mb-4 flex items-center gap-2 rounded-lg border border-border bg-muted/20 px-3 py-2 text-sm text-muted-foreground",
|
|
285
334
|
children: [/* @__PURE__ */ m(fe, {
|
|
286
335
|
size: 14,
|
|
287
336
|
className: "animate-spin"
|
|
288
|
-
}),
|
|
337
|
+
}), S("conversations.loadingMessages", "Loading messages...")]
|
|
289
338
|
}),
|
|
290
|
-
!
|
|
339
|
+
!je && !Me && J.length === 0 && /* @__PURE__ */ m("div", {
|
|
291
340
|
className: "mx-4 mb-4 rounded-lg border border-dashed border-border bg-muted/20 px-3 py-6 text-center text-sm text-muted-foreground",
|
|
292
|
-
children:
|
|
341
|
+
children: S("conversations.noMessagesYet", "No messages yet. Start the conversation below.")
|
|
293
342
|
}),
|
|
294
|
-
|
|
295
|
-
let n =
|
|
296
|
-
return /* @__PURE__ */ m("div", { children:
|
|
343
|
+
J.map((e, t) => {
|
|
344
|
+
let n = J[t - 1], i = !n || n.authorId !== e.authorId || n.type === "SYSTEM";
|
|
345
|
+
return /* @__PURE__ */ m("div", { children: z === e.id ? /* @__PURE__ */ h("div", {
|
|
297
346
|
className: "px-4 py-2",
|
|
298
347
|
children: [/* @__PURE__ */ h("div", {
|
|
299
348
|
className: "flex items-center gap-2 text-xs text-muted-foreground mb-1",
|
|
300
|
-
children: [/* @__PURE__ */ m("span", { children:
|
|
349
|
+
children: [/* @__PURE__ */ m("span", { children: S("conversations.editingMessage", "Editing message") }), /* @__PURE__ */ m("button", {
|
|
301
350
|
type: "button",
|
|
302
|
-
onClick:
|
|
351
|
+
onClick: $,
|
|
303
352
|
className: "hover:text-foreground",
|
|
304
|
-
children: /* @__PURE__ */ m(
|
|
353
|
+
children: /* @__PURE__ */ m(be, { size: 12 })
|
|
305
354
|
})]
|
|
306
355
|
}), /* @__PURE__ */ h("div", {
|
|
307
356
|
className: "flex items-end gap-2",
|
|
308
357
|
children: [/* @__PURE__ */ m("textarea", {
|
|
309
358
|
"aria-label": "Edit message",
|
|
310
|
-
value:
|
|
311
|
-
onChange: (e) =>
|
|
359
|
+
value: V,
|
|
360
|
+
onChange: (e) => H(e.target.value),
|
|
312
361
|
onKeyDown: (e) => {
|
|
313
|
-
e.key === "Enter" && !e.shiftKey && (e.preventDefault(),
|
|
362
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Ze()), e.key === "Escape" && $();
|
|
314
363
|
},
|
|
315
364
|
className: "flex-1 px-3 py-2 text-sm rounded-lg border border-border bg-muted/30 resize-none focus:outline-none focus:ring-2 focus:ring-ring",
|
|
316
365
|
rows: 2
|
|
317
366
|
}), /* @__PURE__ */ m("button", {
|
|
318
367
|
type: "button",
|
|
319
|
-
onClick: () => void
|
|
320
|
-
disabled: !
|
|
368
|
+
onClick: () => void Ze(),
|
|
369
|
+
disabled: !V.trim() || I,
|
|
321
370
|
className: "px-3 py-2 text-xs font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50",
|
|
322
|
-
children:
|
|
371
|
+
children: S("conversations.save", "Save")
|
|
323
372
|
})]
|
|
324
373
|
})]
|
|
325
374
|
}) : /* @__PURE__ */ m(r, {
|
|
326
375
|
message: e,
|
|
327
|
-
isOwnMessage: e.authorId ===
|
|
376
|
+
isOwnMessage: e.authorId === K,
|
|
328
377
|
showAvatar: i,
|
|
329
378
|
showSender: i,
|
|
330
|
-
onReply:
|
|
331
|
-
onReact: (e, t) => void
|
|
332
|
-
onEdit:
|
|
333
|
-
onDelete: (e) => void
|
|
334
|
-
onTogglePin: (e, t) => void
|
|
379
|
+
onReply: Je,
|
|
380
|
+
onReact: (e, t) => void Ye(e, t),
|
|
381
|
+
onEdit: Xe,
|
|
382
|
+
onDelete: (e) => void Qe(e),
|
|
383
|
+
onTogglePin: (e, t) => void $e(e, t)
|
|
335
384
|
}) }, e.id);
|
|
336
385
|
}),
|
|
337
|
-
/* @__PURE__ */ m("div", { ref:
|
|
386
|
+
/* @__PURE__ */ m("div", { ref: j })
|
|
338
387
|
]
|
|
339
388
|
}),
|
|
340
389
|
/* @__PURE__ */ h("div", {
|
|
341
390
|
"data-tour": "conversation-message-composer",
|
|
342
391
|
className: "border-t border-border px-4 py-3 bg-background",
|
|
343
|
-
children: [
|
|
392
|
+
children: [U && /* @__PURE__ */ h("div", {
|
|
344
393
|
className: "flex items-center gap-2 mb-2 px-3 py-1.5 rounded-lg bg-muted/50 text-xs text-muted-foreground",
|
|
345
394
|
children: [/* @__PURE__ */ h("span", { children: [
|
|
346
|
-
|
|
395
|
+
S("conversations.replyingTo", "Replying to"),
|
|
347
396
|
" ",
|
|
348
397
|
/* @__PURE__ */ m("strong", {
|
|
349
398
|
className: "text-foreground",
|
|
350
|
-
children:
|
|
399
|
+
children: U.sender
|
|
351
400
|
}),
|
|
352
401
|
": ",
|
|
353
|
-
|
|
354
|
-
|
|
402
|
+
U.content.slice(0, 80),
|
|
403
|
+
U.content.length > 80 ? "…" : ""
|
|
355
404
|
] }), /* @__PURE__ */ m("button", {
|
|
356
405
|
type: "button",
|
|
357
|
-
onClick: () =>
|
|
358
|
-
"aria-label":
|
|
406
|
+
onClick: () => W(null),
|
|
407
|
+
"aria-label": S("conversations.cancelReply", "Cancel reply"),
|
|
359
408
|
className: "ml-auto flex min-h-9 min-w-9 items-center justify-center rounded-md hover:bg-muted/70 hover:text-foreground",
|
|
360
|
-
children: /* @__PURE__ */ m(
|
|
409
|
+
children: /* @__PURE__ */ m(be, { size: 12 })
|
|
361
410
|
})]
|
|
362
411
|
}), /* @__PURE__ */ h("div", {
|
|
363
412
|
className: "flex items-end gap-2",
|
|
364
413
|
children: [/* @__PURE__ */ m("div", {
|
|
365
414
|
className: "flex-1 relative",
|
|
366
415
|
children: /* @__PURE__ */ m("textarea", {
|
|
367
|
-
"aria-label":
|
|
368
|
-
value:
|
|
369
|
-
onChange: (e) =>
|
|
370
|
-
onKeyDown:
|
|
371
|
-
placeholder: `${
|
|
416
|
+
"aria-label": S("conversations.messageComposer", "Message composer"),
|
|
417
|
+
value: D,
|
|
418
|
+
onChange: (e) => O(e.target.value),
|
|
419
|
+
onKeyDown: qe,
|
|
420
|
+
placeholder: `${S("conversations.messageConversationPrefix", "Message")} ${M.title}...`,
|
|
372
421
|
rows: 1,
|
|
373
422
|
className: t("w-full px-4 py-2.5 text-sm rounded-xl border border-border bg-muted/30", "resize-none overflow-hidden placeholder:text-muted-foreground", "focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent max-h-32"),
|
|
374
423
|
style: {
|
|
@@ -382,19 +431,19 @@ function _() {
|
|
|
382
431
|
})
|
|
383
432
|
}), /* @__PURE__ */ m("button", {
|
|
384
433
|
type: "button",
|
|
385
|
-
"aria-label":
|
|
386
|
-
onClick: () => void
|
|
387
|
-
disabled: !
|
|
388
|
-
className: t("p-2.5 rounded-xl transition-all duration-150",
|
|
389
|
-
children:
|
|
434
|
+
"aria-label": S("conversations.sendMessage", "Send message"),
|
|
435
|
+
onClick: () => void Q(),
|
|
436
|
+
disabled: !D.trim() || F,
|
|
437
|
+
className: t("p-2.5 rounded-xl transition-all duration-150", D.trim() && !F ? "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm" : "bg-muted text-muted-foreground cursor-not-allowed"),
|
|
438
|
+
children: F ? /* @__PURE__ */ m(fe, {
|
|
390
439
|
size: 18,
|
|
391
440
|
className: "animate-spin"
|
|
392
|
-
}) : /* @__PURE__ */ m(
|
|
441
|
+
}) : /* @__PURE__ */ m(ve, { size: 18 })
|
|
393
442
|
})]
|
|
394
443
|
})]
|
|
395
444
|
})
|
|
396
445
|
]
|
|
397
|
-
}),
|
|
446
|
+
}), w && M.isGroup && /* @__PURE__ */ m("aside", {
|
|
398
447
|
className: "absolute inset-y-0 right-0 z-20 w-full max-w-72 border-l border-border bg-background shadow-lg animate-in slide-in-from-right-4 duration-200 md:relative md:z-auto md:w-64 md:shadow-none",
|
|
399
448
|
children: /* @__PURE__ */ h("div", {
|
|
400
449
|
className: "p-4",
|
|
@@ -403,20 +452,20 @@ function _() {
|
|
|
403
452
|
children: [/* @__PURE__ */ h("h3", {
|
|
404
453
|
className: "text-sm font-semibold text-foreground",
|
|
405
454
|
children: [
|
|
406
|
-
|
|
455
|
+
S("conversations.members", "Members"),
|
|
407
456
|
" (",
|
|
408
|
-
|
|
457
|
+
M.memberCount ?? X.length,
|
|
409
458
|
")"
|
|
410
459
|
]
|
|
411
460
|
}), /* @__PURE__ */ m("button", {
|
|
412
461
|
type: "button",
|
|
413
|
-
onClick:
|
|
462
|
+
onClick: E,
|
|
414
463
|
className: "p-1 rounded text-muted-foreground hover:text-foreground",
|
|
415
|
-
children: /* @__PURE__ */ m(
|
|
464
|
+
children: /* @__PURE__ */ m(ge, { size: 14 })
|
|
416
465
|
})]
|
|
417
|
-
}), /* @__PURE__ */
|
|
466
|
+
}), /* @__PURE__ */ h("div", {
|
|
418
467
|
className: "space-y-1",
|
|
419
|
-
children:
|
|
468
|
+
children: [X.map((e) => /* @__PURE__ */ h("div", {
|
|
420
469
|
className: "flex items-center gap-2.5 px-2 py-1.5 rounded-lg hover:bg-muted/50",
|
|
421
470
|
children: [/* @__PURE__ */ m("div", {
|
|
422
471
|
className: "size-7 rounded-full bg-muted flex items-center justify-center text-xs font-medium text-muted-foreground",
|
|
@@ -428,10 +477,19 @@ function _() {
|
|
|
428
477
|
children: e.name
|
|
429
478
|
}), /* @__PURE__ */ m("p", {
|
|
430
479
|
className: "text-[10px] text-muted-foreground",
|
|
431
|
-
children:
|
|
480
|
+
children: e.role
|
|
432
481
|
})]
|
|
433
482
|
})]
|
|
434
|
-
}, e.id))
|
|
483
|
+
}, e.id)), Z > 0 && /* @__PURE__ */ h("p", {
|
|
484
|
+
className: "px-2 pt-2 text-xs text-muted-foreground",
|
|
485
|
+
children: [
|
|
486
|
+
S("conversations.moreMembersPrefix", "and"),
|
|
487
|
+
" ",
|
|
488
|
+
Z,
|
|
489
|
+
" ",
|
|
490
|
+
S("conversations.moreMembersSuffix", "more")
|
|
491
|
+
]
|
|
492
|
+
})]
|
|
435
493
|
})]
|
|
436
494
|
})
|
|
437
495
|
})]
|