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