@burdenoff/microfe-conversations 2026.510.117

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 (155) hide show
  1. package/README.md +12 -0
  2. package/dist/__tests__/setup.d.ts +2 -0
  3. package/dist/__tests__/setup.d.ts.map +1 -0
  4. package/dist/conversations/ConversationsAdminRoot.d.ts +19 -0
  5. package/dist/conversations/ConversationsAdminRoot.d.ts.map +1 -0
  6. package/dist/conversations/ConversationsAdminRoot.js +104 -0
  7. package/dist/conversations/ConversationsAdminRoot.js.map +1 -0
  8. package/dist/conversations/ConversationsAdminRoutes.d.ts +18 -0
  9. package/dist/conversations/ConversationsAdminRoutes.d.ts.map +1 -0
  10. package/dist/conversations/ConversationsAdminRoutes.js +42 -0
  11. package/dist/conversations/ConversationsAdminRoutes.js.map +1 -0
  12. package/dist/conversations/ConversationsRoot.d.ts +33 -0
  13. package/dist/conversations/ConversationsRoot.d.ts.map +1 -0
  14. package/dist/conversations/ConversationsRoot.js +100 -0
  15. package/dist/conversations/ConversationsRoot.js.map +1 -0
  16. package/dist/conversations/ConversationsUserRoot.d.ts +17 -0
  17. package/dist/conversations/ConversationsUserRoot.d.ts.map +1 -0
  18. package/dist/conversations/ConversationsUserRoot.js +101 -0
  19. package/dist/conversations/ConversationsUserRoot.js.map +1 -0
  20. package/dist/conversations/ConversationsUserRoutes.d.ts +12 -0
  21. package/dist/conversations/ConversationsUserRoutes.d.ts.map +1 -0
  22. package/dist/conversations/ConversationsUserRoutes.js +45 -0
  23. package/dist/conversations/ConversationsUserRoutes.js.map +1 -0
  24. package/dist/conversations/components/ConversationCard.d.ts +14 -0
  25. package/dist/conversations/components/ConversationCard.d.ts.map +1 -0
  26. package/dist/conversations/components/ConversationCard.js +118 -0
  27. package/dist/conversations/components/ConversationCard.js.map +1 -0
  28. package/dist/conversations/components/LazyPageBoundary.d.ts +25 -0
  29. package/dist/conversations/components/LazyPageBoundary.d.ts.map +1 -0
  30. package/dist/conversations/components/LazyPageBoundary.js +144 -0
  31. package/dist/conversations/components/LazyPageBoundary.js.map +1 -0
  32. package/dist/conversations/components/MessageBubble.d.ts +21 -0
  33. package/dist/conversations/components/MessageBubble.d.ts.map +1 -0
  34. package/dist/conversations/components/MessageBubble.js +242 -0
  35. package/dist/conversations/components/MessageBubble.js.map +1 -0
  36. package/dist/conversations/components/PageLayout.d.ts +55 -0
  37. package/dist/conversations/components/PageLayout.d.ts.map +1 -0
  38. package/dist/conversations/components/PageLayout.js +93 -0
  39. package/dist/conversations/components/PageLayout.js.map +1 -0
  40. package/dist/conversations/components/PermissionGuard.d.ts +21 -0
  41. package/dist/conversations/components/PermissionGuard.d.ts.map +1 -0
  42. package/dist/conversations/components/PermissionGuard.js +25 -0
  43. package/dist/conversations/components/PermissionGuard.js.map +1 -0
  44. package/dist/conversations/constants/featureFlags.d.ts +8 -0
  45. package/dist/conversations/constants/featureFlags.d.ts.map +1 -0
  46. package/dist/conversations/constants/featureFlags.js +12 -0
  47. package/dist/conversations/constants/featureFlags.js.map +1 -0
  48. package/dist/conversations/constants/permissions.d.ts +174 -0
  49. package/dist/conversations/constants/permissions.d.ts.map +1 -0
  50. package/dist/conversations/constants/permissions.js +68 -0
  51. package/dist/conversations/constants/permissions.js.map +1 -0
  52. package/dist/conversations/hooks/useAdminFeatureFlags.d.ts +8 -0
  53. package/dist/conversations/hooks/useAdminFeatureFlags.d.ts.map +1 -0
  54. package/dist/conversations/hooks/useAdminFeatureFlags.js +16 -0
  55. package/dist/conversations/hooks/useAdminFeatureFlags.js.map +1 -0
  56. package/dist/conversations/hooks/useConversationQueries.d.ts +83 -0
  57. package/dist/conversations/hooks/useConversationQueries.d.ts.map +1 -0
  58. package/dist/conversations/hooks/useConversationQueries.js +136 -0
  59. package/dist/conversations/hooks/useConversationQueries.js.map +1 -0
  60. package/dist/conversations/hooks/useExportConversation.d.ts +10 -0
  61. package/dist/conversations/hooks/useExportConversation.d.ts.map +1 -0
  62. package/dist/conversations/hooks/useExportConversation.js +41 -0
  63. package/dist/conversations/hooks/useExportConversation.js.map +1 -0
  64. package/dist/conversations/hooks/useMessageQueries.d.ts +84 -0
  65. package/dist/conversations/hooks/useMessageQueries.d.ts.map +1 -0
  66. package/dist/conversations/hooks/useMessageQueries.js +123 -0
  67. package/dist/conversations/hooks/useMessageQueries.js.map +1 -0
  68. package/dist/conversations/hooks/useMessageSubscriptions.d.ts +24 -0
  69. package/dist/conversations/hooks/useMessageSubscriptions.d.ts.map +1 -0
  70. package/dist/conversations/hooks/useMessageSubscriptions.js +90 -0
  71. package/dist/conversations/hooks/useMessageSubscriptions.js.map +1 -0
  72. package/dist/conversations/hooks/useUserFeatureFlags.d.ts +5 -0
  73. package/dist/conversations/hooks/useUserFeatureFlags.d.ts.map +1 -0
  74. package/dist/conversations/hooks/useUserFeatureFlags.js +10 -0
  75. package/dist/conversations/hooks/useUserFeatureFlags.js.map +1 -0
  76. package/dist/conversations/index.d.ts +31 -0
  77. package/dist/conversations/index.d.ts.map +1 -0
  78. package/dist/conversations/index.js +5 -0
  79. package/dist/conversations/pages/AdminConversationsLandingPage.d.ts +9 -0
  80. package/dist/conversations/pages/AdminConversationsLandingPage.d.ts.map +1 -0
  81. package/dist/conversations/pages/AdminConversationsLandingPage.js +117 -0
  82. package/dist/conversations/pages/AdminConversationsLandingPage.js.map +1 -0
  83. package/dist/conversations/pages/ConversationAdminPages.d.ts +5 -0
  84. package/dist/conversations/pages/ConversationAdminPages.d.ts.map +1 -0
  85. package/dist/conversations/pages/ConversationAdminPages.js +573 -0
  86. package/dist/conversations/pages/ConversationAdminPages.js.map +1 -0
  87. package/dist/conversations/pages/ConversationDetailPage.d.ts +2 -0
  88. package/dist/conversations/pages/ConversationDetailPage.d.ts.map +1 -0
  89. package/dist/conversations/pages/ConversationDetailPage.js +439 -0
  90. package/dist/conversations/pages/ConversationDetailPage.js.map +1 -0
  91. package/dist/conversations/pages/ConversationListPage.d.ts +6 -0
  92. package/dist/conversations/pages/ConversationListPage.d.ts.map +1 -0
  93. package/dist/conversations/pages/ConversationListPage.js +269 -0
  94. package/dist/conversations/pages/ConversationListPage.js.map +1 -0
  95. package/dist/conversations/pages/ConversationsLandingPage.d.ts +9 -0
  96. package/dist/conversations/pages/ConversationsLandingPage.d.ts.map +1 -0
  97. package/dist/conversations/pages/ConversationsLandingPage.js +124 -0
  98. package/dist/conversations/pages/ConversationsLandingPage.js.map +1 -0
  99. package/dist/conversations/pages/ConversationsSettingsPage.d.ts +2 -0
  100. package/dist/conversations/pages/ConversationsSettingsPage.d.ts.map +1 -0
  101. package/dist/conversations/pages/ConversationsSettingsPage.js +215 -0
  102. package/dist/conversations/pages/ConversationsSettingsPage.js.map +1 -0
  103. package/dist/conversations/pages/NewConversationPage.d.ts +2 -0
  104. package/dist/conversations/pages/NewConversationPage.d.ts.map +1 -0
  105. package/dist/conversations/pages/NewConversationPage.js +287 -0
  106. package/dist/conversations/pages/NewConversationPage.js.map +1 -0
  107. package/dist/conversations/providers/ConversationsProvider.d.ts +13 -0
  108. package/dist/conversations/providers/ConversationsProvider.d.ts.map +1 -0
  109. package/dist/conversations/providers/ConversationsProvider.js +109 -0
  110. package/dist/conversations/providers/ConversationsProvider.js.map +1 -0
  111. package/dist/conversations/store/conversationsStore.d.ts +29 -0
  112. package/dist/conversations/store/conversationsStore.d.ts.map +1 -0
  113. package/dist/conversations/store/conversationsStore.js +56 -0
  114. package/dist/conversations/store/conversationsStore.js.map +1 -0
  115. package/dist/conversations/types/index.d.ts +352 -0
  116. package/dist/conversations/types/index.d.ts.map +1 -0
  117. package/dist/conversations/utils/cn.d.ts +8 -0
  118. package/dist/conversations/utils/cn.d.ts.map +1 -0
  119. package/dist/conversations/utils/cn.js +10 -0
  120. package/dist/conversations/utils/cn.js.map +1 -0
  121. package/dist/conversations/utils/i18n.d.ts +15 -0
  122. package/dist/conversations/utils/i18n.d.ts.map +1 -0
  123. package/dist/conversations/utils/i18n.js +14 -0
  124. package/dist/conversations/utils/i18n.js.map +1 -0
  125. package/dist/conversations/utils/mappers.d.ts +32 -0
  126. package/dist/conversations/utils/mappers.d.ts.map +1 -0
  127. package/dist/conversations/utils/mappers.js +164 -0
  128. package/dist/conversations/utils/mappers.js.map +1 -0
  129. package/dist/conversations/utils/navigation.d.ts +18 -0
  130. package/dist/conversations/utils/navigation.d.ts.map +1 -0
  131. package/dist/conversations/utils/navigation.js +8 -0
  132. package/dist/conversations/utils/navigation.js.map +1 -0
  133. package/dist/dev/main.d.ts +2 -0
  134. package/dist/dev/main.d.ts.map +1 -0
  135. package/dist/generated/global-operations.d.ts +2 -0
  136. package/dist/generated/global-operations.d.ts.map +1 -0
  137. package/dist/generated/global-types.d.ts +20716 -0
  138. package/dist/generated/global-types.d.ts.map +1 -0
  139. package/dist/generated/wspace-operations.d.ts +2008 -0
  140. package/dist/generated/wspace-operations.d.ts.map +1 -0
  141. package/dist/generated/wspace-operations.js +997 -0
  142. package/dist/generated/wspace-operations.js.map +1 -0
  143. package/dist/generated/wspace-types.d.ts +53363 -0
  144. package/dist/generated/wspace-types.d.ts.map +1 -0
  145. package/dist/index.d.ts +6 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +7 -0
  148. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  149. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  150. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1674 -0
  151. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  152. package/dist/utils/nativeBridge.d.ts +3 -0
  153. package/dist/utils/nativeBridge.d.ts.map +1 -0
  154. package/dist/utils/nativeBridge.js +2 -0
  155. package/package.json +115 -0
@@ -0,0 +1,439 @@
1
+ import { useConversations as e } from "../providers/ConversationsProvider.js";
2
+ import { cn as t } from "../utils/cn.js";
3
+ import { useConversationActions as n, useGetConversation as r } from "../hooks/useConversationQueries.js";
4
+ import { useMessageStreamForConversation as i } from "../hooks/useMessageSubscriptions.js";
5
+ import { useConversationsStore as ee } from "../store/conversationsStore.js";
6
+ import { PermissionGuard as a } from "../components/PermissionGuard.js";
7
+ import { CONVERSATIONS_PERMISSIONS as o } from "../constants/permissions.js";
8
+ import { nativeImpact as te, nativeNotify as s } from "../../utils/nativeBridge.js";
9
+ import { MessageBubble as ne } from "../components/MessageBubble.js";
10
+ import { useEditMessage as re, useGetMessages as ie, useMessageActions as ae, useSendMessage as oe } from "../hooks/useMessageQueries.js";
11
+ import { useCallback as c, useEffect as l, useMemo as se, useRef as u, useState as d } from "react";
12
+ import { Archive as ce, ArrowLeft as le, Bell as ue, BellOff as de, ExternalLink as fe, Hash as pe, Loader2 as me, MessageCircle as he, MoreVertical as ge, Pin as _e, PinOff as ve, SendHorizontal as ye, Users as be, X as xe } from "lucide-react";
13
+ import { useNavigate as Se, useParams as Ce } from "react-router-dom";
14
+ import { useEventBus as we } from "@burdenoff/fe-libs/shared/events";
15
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
16
+ import { useI18n as Te } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
+ //#region src/conversations/pages/ConversationDetailPage.tsx
18
+ function m() {
19
+ let { conversationId: a } = Ce(), o = Se(), { basePath: m, currentUser: Ee } = e(), _ = we(), { t: De } = Te(), v = (e, t) => {
20
+ let n = De(e);
21
+ return n === e ? t : n;
22
+ }, { clearMessageDraft: y, isParticipantsPanelOpen: b, messageDrafts: Oe, setMessageDraft: x, toggleParticipantsPanel: S } = ee(), [C, w] = d(Oe[a ?? ""] ?? ""), T = u(null), { conversation: E, loading: ke, error: D } = r(a ?? ""), { messages: O, loading: k, error: A } = ie(a ?? "", { first: 100 });
23
+ i(a);
24
+ let { sendMessage: j, loading: M } = oe(), { editMessage: N, loading: P } = re(), { deleteMessage: F, addReaction: I, removeReaction: L, pinMessage: R, unpinMessage: z } = ae(), { archiveConversation: B, pinConversation: V, unpinConversation: Ae, muteConversation: je, unmuteConversation: Me } = n(), [H, U] = d(!1), [W, G] = d(null), [K, q] = d(""), [J, Y] = d(null), X = u(null), Ne = Ee?.id ?? "", Z = E?.sourceContext;
25
+ l(() => {
26
+ T.current?.scrollIntoView({ behavior: "smooth" });
27
+ }, [O.length]), l(() => {
28
+ if (a) {
29
+ if (C.trim()) {
30
+ x(a, C);
31
+ return;
32
+ }
33
+ y(a);
34
+ }
35
+ }, [
36
+ C,
37
+ a,
38
+ x,
39
+ y
40
+ ]);
41
+ let Pe = se(() => {
42
+ let e = /* @__PURE__ */ new Map();
43
+ for (let t of O) !t.authorId || e.has(t.authorId) || e.set(t.authorId, {
44
+ id: t.authorId,
45
+ name: t.sender.name || t.authorId
46
+ });
47
+ return Array.from(e.values());
48
+ }, [O]), Q = c(async () => {
49
+ if (!a || !C.trim() || M) return;
50
+ let e = await j({
51
+ conversationId: a,
52
+ content: C.trim(),
53
+ type: "TEXT",
54
+ parentMessageId: J?.id
55
+ });
56
+ e && (_.emit("conversations.message.sent", {
57
+ messageId: e.id,
58
+ conversationId: a
59
+ }), w(""), Y(null), y(a));
60
+ }, [
61
+ _,
62
+ a,
63
+ C,
64
+ M,
65
+ j,
66
+ y,
67
+ J
68
+ ]), Fe = c((e) => {
69
+ e.key !== "Enter" || e.shiftKey || (e.preventDefault(), Q());
70
+ }, [Q]);
71
+ l(() => {
72
+ a && _.emit("conversations.conversation.opened", { conversationId: a });
73
+ }, [_, a]), l(() => {
74
+ if (!H) return;
75
+ let e = (e) => {
76
+ X.current && !X.current.contains(e.target) && U(!1);
77
+ };
78
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
79
+ }, [H]);
80
+ let Ie = c((e) => {
81
+ Y({
82
+ id: e.id,
83
+ content: e.content,
84
+ sender: e.sender.name
85
+ });
86
+ }, []), Le = c(async (e, t) => {
87
+ try {
88
+ await I(e, t);
89
+ } catch {
90
+ await L(e, t).catch(() => {});
91
+ }
92
+ }, [I, L]), Re = c((e) => {
93
+ G(e.id), q(e.content);
94
+ }, []), ze = c(async () => {
95
+ !W || !K.trim() || P || (await N(W, K.trim()), G(null), q(""));
96
+ }, [
97
+ W,
98
+ K,
99
+ P,
100
+ N
101
+ ]), $ = c(() => {
102
+ G(null), q("");
103
+ }, []), Be = c(async (e) => {
104
+ te("medium");
105
+ try {
106
+ await F(e), s("success");
107
+ } catch (e) {
108
+ throw s("error"), e;
109
+ }
110
+ }, [F]), Ve = c(async (e, t) => {
111
+ if (t) {
112
+ await z(e);
113
+ return;
114
+ }
115
+ await R(e);
116
+ }, [R, z]), He = c(async () => {
117
+ a && (E?.isPinned ? await Ae(a) : await V(a), U(!1));
118
+ }, [
119
+ a,
120
+ E?.isPinned,
121
+ V,
122
+ Ae
123
+ ]), Ue = c(async () => {
124
+ a && (E?.isMuted ? await Me(a) : await je(a), U(!1));
125
+ }, [
126
+ a,
127
+ E?.isMuted,
128
+ je,
129
+ Me
130
+ ]), We = c(async () => {
131
+ a && (await B(a), _.emit("conversations.conversation.archived", { conversationId: a }), U(!1), o(m || "/conversations"));
132
+ }, [
133
+ B,
134
+ m,
135
+ _,
136
+ a,
137
+ o
138
+ ]), Ge = c(() => {
139
+ if (Z?.contextHref) {
140
+ try {
141
+ let e = new URL(Z.contextHref);
142
+ if (e.origin === window.location.origin) {
143
+ o(`${e.pathname}${e.search}${e.hash}`);
144
+ return;
145
+ }
146
+ } catch {}
147
+ window.location.assign(Z.contextHref);
148
+ }
149
+ }, [o, Z?.contextHref]);
150
+ return !E && ke ? /* @__PURE__ */ f("div", {
151
+ className: "flex items-center justify-center h-[calc(100vh-64px)] text-sm text-muted-foreground",
152
+ children: v("conversations.loading", "Loading conversation...")
153
+ }) : !E || D ? /* @__PURE__ */ p("div", {
154
+ className: "flex flex-col items-center justify-center h-[calc(100vh-64px)] text-center gap-3 px-4",
155
+ children: [
156
+ /* @__PURE__ */ f(he, { className: "h-8 w-8 text-muted-foreground" }),
157
+ /* @__PURE__ */ f("p", {
158
+ className: "text-sm text-muted-foreground",
159
+ children: D ? v("conversations.unavailable", "We couldn't load this conversation. Please try again.") : v("conversations.notFound", "Conversation not found")
160
+ }),
161
+ /* @__PURE__ */ f("button", {
162
+ type: "button",
163
+ onClick: () => o(m || "/conversations"),
164
+ className: "px-3 py-2 text-sm font-medium rounded-lg border border-border hover:bg-muted/50",
165
+ children: v("conversations.back", "Back to conversations")
166
+ })
167
+ ]
168
+ }) : /* @__PURE__ */ p("div", {
169
+ className: "flex h-[calc(100vh-64px)] bg-background",
170
+ children: [/* @__PURE__ */ p("div", {
171
+ className: "flex-1 flex flex-col min-w-0",
172
+ children: [
173
+ /* @__PURE__ */ p("header", {
174
+ className: "flex items-center justify-between px-4 py-3 border-b border-border bg-background/95 backdrop-blur-sm",
175
+ children: [/* @__PURE__ */ p("div", {
176
+ className: "flex items-center gap-3 min-w-0",
177
+ children: [/* @__PURE__ */ f("button", {
178
+ type: "button",
179
+ onClick: () => o(m || "/conversations"),
180
+ className: "p-1.5 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
181
+ children: /* @__PURE__ */ f(le, { size: 18 })
182
+ }), /* @__PURE__ */ p("div", {
183
+ className: "min-w-0",
184
+ children: [/* @__PURE__ */ p("div", {
185
+ className: "flex items-center gap-1.5",
186
+ children: [E.type === "CHANNEL" && /* @__PURE__ */ f(pe, {
187
+ size: 14,
188
+ className: "text-muted-foreground flex-shrink-0"
189
+ }), /* @__PURE__ */ f("h2", {
190
+ className: "text-sm font-semibold text-foreground truncate",
191
+ children: E.title
192
+ })]
193
+ }), /* @__PURE__ */ f("p", {
194
+ className: "text-xs text-muted-foreground",
195
+ children: E.type === "DIRECT" ? v("conversations.directConversation", "Direct conversation") : E.type === "CHANNEL" ? `${v("conversations.channel", "Channel")} · ${E.memberCount} ${v("conversations.membersCountLabel", "members")}` : E.type === "ANNOUNCEMENT" ? `${v("conversations.announcement", "Announcement")} · ${E.memberCount} ${v("conversations.membersCountLabel", "members")}` : `${E.memberCount} ${v("conversations.membersCountLabel", "members")}`
196
+ })]
197
+ })]
198
+ }), /* @__PURE__ */ p("div", {
199
+ className: "flex items-center gap-1",
200
+ children: [
201
+ Z?.contextHref && /* @__PURE__ */ f(g, {
202
+ icon: /* @__PURE__ */ f(fe, { size: 16 }),
203
+ label: v("conversations.openContext", "Open context"),
204
+ onClick: Ge
205
+ }),
206
+ E.isGroup && /* @__PURE__ */ f(g, {
207
+ icon: /* @__PURE__ */ f(be, { size: 16 }),
208
+ label: v("conversations.participants", "Participants"),
209
+ active: b,
210
+ onClick: S
211
+ }),
212
+ /* @__PURE__ */ p("div", {
213
+ className: "relative",
214
+ ref: X,
215
+ children: [/* @__PURE__ */ f(g, {
216
+ icon: /* @__PURE__ */ f(ge, { size: 16 }),
217
+ label: v("conversations.moreOptions", "More options"),
218
+ active: H,
219
+ onClick: () => U((e) => !e)
220
+ }), H && /* @__PURE__ */ p("div", {
221
+ 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",
222
+ children: [
223
+ /* @__PURE__ */ f(h, {
224
+ icon: E.isPinned ? /* @__PURE__ */ f(ve, { size: 14 }) : /* @__PURE__ */ f(_e, { size: 14 }),
225
+ label: E.isPinned ? v("conversations.unpinConversation", "Unpin conversation") : v("conversations.pinConversation", "Pin conversation"),
226
+ onClick: () => void He()
227
+ }),
228
+ /* @__PURE__ */ f(h, {
229
+ icon: E.isMuted ? /* @__PURE__ */ f(ue, { size: 14 }) : /* @__PURE__ */ f(de, { size: 14 }),
230
+ label: E.isMuted ? v("conversations.unmuteConversation", "Unmute conversation") : v("conversations.muteConversation", "Mute conversation"),
231
+ onClick: () => void Ue()
232
+ }),
233
+ /* @__PURE__ */ f("div", { className: "h-px bg-border my-1" }),
234
+ /* @__PURE__ */ f(h, {
235
+ icon: /* @__PURE__ */ f(ce, { size: 14 }),
236
+ label: v("conversations.archiveConversation", "Archive conversation"),
237
+ onClick: () => void We(),
238
+ destructive: !0
239
+ })
240
+ ]
241
+ })]
242
+ })
243
+ ]
244
+ })]
245
+ }),
246
+ /* @__PURE__ */ p("div", {
247
+ className: "flex-1 overflow-y-auto py-4 space-y-0.5",
248
+ children: [
249
+ Z?.pagePath && /* @__PURE__ */ p("div", {
250
+ className: "mx-4 mb-4 rounded-lg border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground",
251
+ children: [/* @__PURE__ */ f("span", {
252
+ className: "font-medium text-foreground",
253
+ children: Z.contextTitle || Z.pagePath
254
+ }), Z.entityType && Z.entityId ? ` · ${Z.entityType} ${Z.entityId}` : ""]
255
+ }),
256
+ A && /* @__PURE__ */ f("div", {
257
+ 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",
258
+ children: v("conversations.messagesUnavailable", "Messages couldn't be loaded right now. The conversation header and actions are still available.")
259
+ }),
260
+ k && /* @__PURE__ */ p("div", {
261
+ 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",
262
+ children: [/* @__PURE__ */ f(me, {
263
+ size: 14,
264
+ className: "animate-spin"
265
+ }), v("conversations.loadingMessages", "Loading messages...")]
266
+ }),
267
+ !k && !A && O.length === 0 && /* @__PURE__ */ f("div", {
268
+ 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",
269
+ children: v("conversations.noMessagesYet", "No messages yet. Start the conversation below.")
270
+ }),
271
+ O.map((e, t) => {
272
+ let n = O[t - 1], r = !n || n.authorId !== e.authorId || n.type === "SYSTEM";
273
+ return /* @__PURE__ */ f("div", { children: W === e.id ? /* @__PURE__ */ p("div", {
274
+ className: "px-4 py-2",
275
+ children: [/* @__PURE__ */ p("div", {
276
+ className: "flex items-center gap-2 text-xs text-muted-foreground mb-1",
277
+ children: [/* @__PURE__ */ f("span", { children: v("conversations.editingMessage", "Editing message") }), /* @__PURE__ */ f("button", {
278
+ type: "button",
279
+ onClick: $,
280
+ className: "hover:text-foreground",
281
+ children: /* @__PURE__ */ f(xe, { size: 12 })
282
+ })]
283
+ }), /* @__PURE__ */ p("div", {
284
+ className: "flex items-end gap-2",
285
+ children: [/* @__PURE__ */ f("textarea", {
286
+ value: K,
287
+ onChange: (e) => q(e.target.value),
288
+ onKeyDown: (e) => {
289
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), ze()), e.key === "Escape" && $();
290
+ },
291
+ 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",
292
+ rows: 2
293
+ }), /* @__PURE__ */ f("button", {
294
+ type: "button",
295
+ onClick: () => void ze(),
296
+ disabled: !K.trim() || P,
297
+ className: "px-3 py-2 text-xs font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50",
298
+ children: v("conversations.save", "Save")
299
+ })]
300
+ })]
301
+ }) : /* @__PURE__ */ f(ne, {
302
+ message: e,
303
+ isOwnMessage: e.authorId === Ne,
304
+ showAvatar: r,
305
+ showSender: r,
306
+ onReply: Ie,
307
+ onReact: (e, t) => void Le(e, t),
308
+ onEdit: Re,
309
+ onDelete: (e) => void Be(e),
310
+ onTogglePin: (e, t) => void Ve(e, t)
311
+ }) }, e.id);
312
+ }),
313
+ /* @__PURE__ */ f("div", { ref: T })
314
+ ]
315
+ }),
316
+ /* @__PURE__ */ p("div", {
317
+ className: "border-t border-border px-4 py-3 bg-background",
318
+ children: [J && /* @__PURE__ */ p("div", {
319
+ className: "flex items-center gap-2 mb-2 px-3 py-1.5 rounded-lg bg-muted/50 text-xs text-muted-foreground",
320
+ children: [/* @__PURE__ */ p("span", { children: [
321
+ v("conversations.replyingTo", "Replying to"),
322
+ " ",
323
+ /* @__PURE__ */ f("strong", {
324
+ className: "text-foreground",
325
+ children: J.sender
326
+ }),
327
+ ": ",
328
+ J.content.slice(0, 80),
329
+ J.content.length > 80 ? "…" : ""
330
+ ] }), /* @__PURE__ */ f("button", {
331
+ type: "button",
332
+ onClick: () => Y(null),
333
+ className: "ml-auto hover:text-foreground",
334
+ children: /* @__PURE__ */ f(xe, { size: 12 })
335
+ })]
336
+ }), /* @__PURE__ */ p("div", {
337
+ className: "flex items-end gap-2",
338
+ children: [/* @__PURE__ */ f("div", {
339
+ className: "flex-1 relative",
340
+ children: /* @__PURE__ */ f("textarea", {
341
+ "aria-label": v("conversations.messageComposer", "Message composer"),
342
+ value: C,
343
+ onChange: (e) => w(e.target.value),
344
+ onKeyDown: Fe,
345
+ placeholder: `${v("conversations.messageConversationPrefix", "Message")} ${E.title}...`,
346
+ rows: 1,
347
+ 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"),
348
+ style: {
349
+ height: "auto",
350
+ minHeight: "40px"
351
+ },
352
+ onInput: (e) => {
353
+ let t = e.target;
354
+ t.style.height = "auto", t.style.height = `${Math.min(t.scrollHeight, 128)}px`;
355
+ }
356
+ })
357
+ }), /* @__PURE__ */ f("button", {
358
+ type: "button",
359
+ "aria-label": v("conversations.sendMessage", "Send message"),
360
+ onClick: () => void Q(),
361
+ disabled: !C.trim() || M,
362
+ className: t("p-2.5 rounded-xl transition-all duration-150", C.trim() && !M ? "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm" : "bg-muted text-muted-foreground cursor-not-allowed"),
363
+ children: M ? /* @__PURE__ */ f(me, {
364
+ size: 18,
365
+ className: "animate-spin"
366
+ }) : /* @__PURE__ */ f(ye, { size: 18 })
367
+ })]
368
+ })]
369
+ })
370
+ ]
371
+ }), b && E.isGroup && /* @__PURE__ */ f("aside", {
372
+ className: "w-64 border-l border-border bg-background overflow-y-auto animate-in slide-in-from-right-4 duration-200",
373
+ children: /* @__PURE__ */ p("div", {
374
+ className: "p-4",
375
+ children: [/* @__PURE__ */ p("div", {
376
+ className: "flex items-center justify-between mb-4",
377
+ children: [/* @__PURE__ */ p("h3", {
378
+ className: "text-sm font-semibold text-foreground",
379
+ children: [
380
+ v("conversations.members", "Members"),
381
+ " (",
382
+ Pe.length || E.memberCount,
383
+ ")"
384
+ ]
385
+ }), /* @__PURE__ */ f("button", {
386
+ type: "button",
387
+ onClick: S,
388
+ className: "p-1 rounded text-muted-foreground hover:text-foreground",
389
+ children: /* @__PURE__ */ f(_e, { size: 14 })
390
+ })]
391
+ }), /* @__PURE__ */ f("div", {
392
+ className: "space-y-1",
393
+ children: Pe.map((e) => /* @__PURE__ */ p("div", {
394
+ className: "flex items-center gap-2.5 px-2 py-1.5 rounded-lg hover:bg-muted/50",
395
+ children: [/* @__PURE__ */ f("div", {
396
+ className: "w-7 h-7 rounded-full bg-muted flex items-center justify-center text-xs font-medium text-muted-foreground",
397
+ children: e.name.split(" ").map((e) => e[0]).join("").slice(0, 2)
398
+ }), /* @__PURE__ */ p("div", {
399
+ className: "min-w-0",
400
+ children: [/* @__PURE__ */ f("p", {
401
+ className: "text-xs font-medium text-foreground truncate",
402
+ children: e.name
403
+ }), /* @__PURE__ */ f("p", {
404
+ className: "text-[10px] text-muted-foreground",
405
+ children: v("conversations.member", "Member")
406
+ })]
407
+ })]
408
+ }, e.id))
409
+ })]
410
+ })
411
+ })]
412
+ });
413
+ }
414
+ function h({ icon: e, label: n, onClick: r, destructive: i }) {
415
+ return /* @__PURE__ */ p("button", {
416
+ type: "button",
417
+ onClick: r,
418
+ 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"),
419
+ children: [e, /* @__PURE__ */ f("span", { children: n })]
420
+ });
421
+ }
422
+ function g({ icon: e, label: n, active: r, onClick: i }) {
423
+ return /* @__PURE__ */ f(a, {
424
+ permission: o.CONVERSATION_READ,
425
+ allowUnavailablePermissions: !0,
426
+ children: /* @__PURE__ */ f("button", {
427
+ type: "button",
428
+ onClick: i,
429
+ "aria-label": n,
430
+ title: n,
431
+ className: t("p-2 rounded-lg transition-colors", r ? "bg-primary/10 text-primary" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"),
432
+ children: e
433
+ })
434
+ });
435
+ }
436
+ //#endregion
437
+ export { m as ConversationDetailPage };
438
+
439
+ //# sourceMappingURL=ConversationDetailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationDetailPage.js","names":[],"sources":["../../../src/conversations/pages/ConversationDetailPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport { useNavigate, useParams } from \"react-router-dom\";\nimport {\n Archive,\n ArrowLeft,\n BellOff,\n Bell,\n ExternalLink,\n Hash,\n Loader2,\n MessageCircle,\n MoreVertical,\n Pin,\n PinOff,\n SendHorizontal,\n Users,\n X,\n} from \"lucide-react\";\nimport { MessageBubble } from \"../components/MessageBubble\";\nimport {\n useGetConversation,\n useConversationActions,\n} from \"../hooks/useConversationQueries\";\nimport {\n useGetMessages,\n useSendMessage,\n useEditMessage,\n useMessageActions,\n} from \"../hooks/useMessageQueries\";\nimport { useMessageStreamForConversation } from \"../hooks/useMessageSubscriptions\";\nimport { useConversations } from \"../providers/ConversationsProvider\";\nimport { useConversationsStore } from \"../store/conversationsStore\";\nimport { cn } from \"../utils/cn\";\nimport { PermissionGuard } from \"../components/PermissionGuard\";\nimport { CONVERSATIONS_PERMISSIONS } from \"../constants/permissions\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\nexport function ConversationDetailPage() {\n const { conversationId } = useParams<{ conversationId: string }>();\n const navigate = useNavigate();\n const { basePath, currentUser } = useConversations();\n const bus = useEventBus();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const {\n clearMessageDraft,\n isParticipantsPanelOpen,\n messageDrafts,\n setMessageDraft,\n toggleParticipantsPanel,\n } = useConversationsStore();\n\n const [messageInput, setMessageInput] = useState(\n messageDrafts[conversationId ?? \"\"] ?? \"\",\n );\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const {\n conversation,\n loading: conversationLoading,\n error: conversationError,\n } = useGetConversation(conversationId ?? \"\");\n const {\n messages,\n loading: messagesLoading,\n error: messagesError,\n } = useGetMessages(conversationId ?? \"\", {\n first: 100,\n });\n // Subscribe to live message events so the list updates without polling.\n // Apollo cache merges by id; the hook handles append / evict explicitly.\n useMessageStreamForConversation(conversationId);\n const { sendMessage, loading: sendingMessage } = useSendMessage();\n const { editMessage, loading: editingMessage } = useEditMessage();\n const {\n deleteMessage,\n addReaction,\n removeReaction,\n pinMessage,\n unpinMessage,\n } = useMessageActions();\n const {\n archiveConversation,\n pinConversation,\n unpinConversation,\n muteConversation,\n unmuteConversation,\n } = useConversationActions();\n\n const [moreMenuOpen, setMoreMenuOpen] = useState(false);\n const [editingMessageId, setEditingMessageId] = useState<string | null>(null);\n const [editingContent, setEditingContent] = useState(\"\");\n const [replyingTo, setReplyingTo] = useState<{\n id: string;\n content: string;\n sender: string;\n } | null>(null);\n const moreMenuRef = useRef<HTMLDivElement>(null);\n\n const currentUserId = currentUser?.id ?? \"\";\n const sourceContext = conversation?.sourceContext;\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages.length]);\n\n useEffect(() => {\n if (!conversationId) return;\n if (messageInput.trim()) {\n setMessageDraft(conversationId, messageInput);\n return;\n }\n clearMessageDraft(conversationId);\n }, [messageInput, conversationId, setMessageDraft, clearMessageDraft]);\n\n const participants = useMemo(() => {\n const byAuthor = new Map<string, { id: string; name: string }>();\n for (const message of messages) {\n if (!message.authorId || byAuthor.has(message.authorId)) continue;\n byAuthor.set(message.authorId, {\n id: message.authorId,\n name: message.sender.name || message.authorId,\n });\n }\n return Array.from(byAuthor.values());\n }, [messages]);\n\n const handleSendMessage = useCallback(async () => {\n if (!conversationId || !messageInput.trim() || sendingMessage) return;\n const message = await sendMessage({\n conversationId,\n content: messageInput.trim(),\n type: \"TEXT\",\n parentMessageId: replyingTo?.id,\n });\n if (!message) return;\n bus.emit(\"conversations.message.sent\", {\n messageId: message.id,\n conversationId,\n });\n setMessageInput(\"\");\n setReplyingTo(null);\n clearMessageDraft(conversationId);\n }, [\n bus,\n conversationId,\n messageInput,\n sendingMessage,\n sendMessage,\n clearMessageDraft,\n replyingTo,\n ]);\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey) return;\n event.preventDefault();\n void handleSendMessage();\n },\n [handleSendMessage],\n );\n\n // Emit opened event so sinks (analytics/audit) can record the view\n useEffect(() => {\n if (!conversationId) return;\n bus.emit(\"conversations.conversation.opened\", { conversationId });\n }, [bus, conversationId]);\n\n // Close more-menu on outside click\n useEffect(() => {\n if (!moreMenuOpen) return;\n const handler = (e: MouseEvent) => {\n if (\n moreMenuRef.current &&\n !moreMenuRef.current.contains(e.target as Node)\n ) {\n setMoreMenuOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [moreMenuOpen]);\n\n const handleReply = useCallback(\n (message: { id: string; content: string; sender: { name: string } }) => {\n setReplyingTo({\n id: message.id,\n content: message.content,\n sender: message.sender.name,\n });\n },\n [],\n );\n\n const handleReact = useCallback(\n async (messageId: string, emoji: string) => {\n try {\n await addReaction(messageId, emoji);\n } catch {\n // If already reacted, toggle off\n await removeReaction(messageId, emoji).catch(() => {});\n }\n },\n [addReaction, removeReaction],\n );\n\n const handleEdit = useCallback((message: { id: string; content: string }) => {\n setEditingMessageId(message.id);\n setEditingContent(message.content);\n }, []);\n\n const handleEditSubmit = useCallback(async () => {\n if (!editingMessageId || !editingContent.trim() || editingMessage) return;\n await editMessage(editingMessageId, editingContent.trim());\n setEditingMessageId(null);\n setEditingContent(\"\");\n }, [editingMessageId, editingContent, editingMessage, editMessage]);\n\n const handleEditCancel = useCallback(() => {\n setEditingMessageId(null);\n setEditingContent(\"\");\n }, []);\n\n const handleDelete = useCallback(\n async (messageId: string) => {\n nativeImpact(\"medium\");\n try {\n await deleteMessage(messageId);\n nativeNotify(\"success\");\n } catch (error) {\n nativeNotify(\"error\");\n throw error;\n }\n },\n [deleteMessage],\n );\n\n const handleTogglePinMessage = useCallback(\n async (messageId: string, isPinned: boolean) => {\n if (isPinned) {\n await unpinMessage(messageId);\n return;\n }\n await pinMessage(messageId);\n },\n [pinMessage, unpinMessage],\n );\n\n const handlePin = useCallback(async () => {\n if (!conversationId) return;\n if (conversation?.isPinned) {\n await unpinConversation(conversationId);\n } else {\n await pinConversation(conversationId);\n }\n setMoreMenuOpen(false);\n }, [\n conversationId,\n conversation?.isPinned,\n pinConversation,\n unpinConversation,\n ]);\n\n const handleMute = useCallback(async () => {\n if (!conversationId) return;\n if (conversation?.isMuted) {\n await unmuteConversation(conversationId);\n } else {\n await muteConversation(conversationId);\n }\n setMoreMenuOpen(false);\n }, [\n conversationId,\n conversation?.isMuted,\n muteConversation,\n unmuteConversation,\n ]);\n\n const handleArchive = useCallback(async () => {\n if (!conversationId) return;\n await archiveConversation(conversationId);\n bus.emit(\"conversations.conversation.archived\", { conversationId });\n setMoreMenuOpen(false);\n navigate(basePath || \"/conversations\");\n }, [archiveConversation, basePath, bus, conversationId, navigate]);\n\n const handleOpenContext = useCallback(() => {\n if (!sourceContext?.contextHref) return;\n try {\n const url = new URL(sourceContext.contextHref);\n if (url.origin === window.location.origin) {\n navigate(`${url.pathname}${url.search}${url.hash}`);\n return;\n }\n } catch {\n // Fall through to full navigation for relative or invalid URLs.\n }\n\n window.location.assign(sourceContext.contextHref);\n }, [navigate, sourceContext?.contextHref]);\n\n if (!conversation && conversationLoading) {\n return (\n <div className=\"flex items-center justify-center h-[calc(100vh-64px)] text-sm text-muted-foreground\">\n {tr(\"conversations.loading\", \"Loading conversation...\")}\n </div>\n );\n }\n\n if (!conversation || conversationError) {\n return (\n <div className=\"flex flex-col items-center justify-center h-[calc(100vh-64px)] text-center gap-3 px-4\">\n <MessageCircle className=\"h-8 w-8 text-muted-foreground\" />\n <p className=\"text-sm text-muted-foreground\">\n {conversationError\n ? tr(\n \"conversations.unavailable\",\n \"We couldn't load this conversation. Please try again.\",\n )\n : tr(\"conversations.notFound\", \"Conversation not found\")}\n </p>\n <button\n type=\"button\"\n onClick={() => navigate(basePath || \"/conversations\")}\n className=\"px-3 py-2 text-sm font-medium rounded-lg border border-border hover:bg-muted/50\"\n >\n {tr(\"conversations.back\", \"Back to conversations\")}\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-[calc(100vh-64px)] bg-background\">\n <div className=\"flex-1 flex flex-col min-w-0\">\n <header className=\"flex items-center justify-between px-4 py-3 border-b border-border bg-background/95 backdrop-blur-sm\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <button\n type=\"button\"\n onClick={() => navigate(basePath || \"/conversations\")}\n className=\"p-1.5 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowLeft size={18} />\n </button>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n {conversation.type === \"CHANNEL\" && (\n <Hash\n size={14}\n className=\"text-muted-foreground flex-shrink-0\"\n />\n )}\n <h2 className=\"text-sm font-semibold text-foreground truncate\">\n {conversation.title}\n </h2>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {conversation.type === \"DIRECT\"\n ? tr(\n \"conversations.directConversation\",\n \"Direct conversation\",\n )\n : conversation.type === \"CHANNEL\"\n ? `${tr(\"conversations.channel\", \"Channel\")} · ${conversation.memberCount} ${tr(\"conversations.membersCountLabel\", \"members\")}`\n : conversation.type === \"ANNOUNCEMENT\"\n ? `${tr(\"conversations.announcement\", \"Announcement\")} · ${conversation.memberCount} ${tr(\"conversations.membersCountLabel\", \"members\")}`\n : `${conversation.memberCount} ${tr(\"conversations.membersCountLabel\", \"members\")}`}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-1\">\n {sourceContext?.contextHref && (\n <HeaderButton\n icon={<ExternalLink size={16} />}\n label={tr(\"conversations.openContext\", \"Open context\")}\n onClick={handleOpenContext}\n />\n )}\n {conversation.isGroup && (\n <HeaderButton\n icon={<Users size={16} />}\n label={tr(\"conversations.participants\", \"Participants\")}\n active={isParticipantsPanelOpen}\n onClick={toggleParticipantsPanel}\n />\n )}\n <div className=\"relative\" ref={moreMenuRef}>\n <HeaderButton\n icon={<MoreVertical size={16} />}\n label={tr(\"conversations.moreOptions\", \"More options\")}\n active={moreMenuOpen}\n onClick={() => setMoreMenuOpen((prev) => !prev)}\n />\n {moreMenuOpen && (\n <div 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\">\n <DropdownItem\n icon={\n conversation.isPinned ? (\n <PinOff size={14} />\n ) : (\n <Pin size={14} />\n )\n }\n label={\n conversation.isPinned\n ? tr(\n \"conversations.unpinConversation\",\n \"Unpin conversation\",\n )\n : tr(\n \"conversations.pinConversation\",\n \"Pin conversation\",\n )\n }\n onClick={() => void handlePin()}\n />\n <DropdownItem\n icon={\n conversation.isMuted ? (\n <Bell size={14} />\n ) : (\n <BellOff size={14} />\n )\n }\n label={\n conversation.isMuted\n ? tr(\n \"conversations.unmuteConversation\",\n \"Unmute conversation\",\n )\n : tr(\n \"conversations.muteConversation\",\n \"Mute conversation\",\n )\n }\n onClick={() => void handleMute()}\n />\n <div className=\"h-px bg-border my-1\" />\n <DropdownItem\n icon={<Archive size={14} />}\n label={tr(\n \"conversations.archiveConversation\",\n \"Archive conversation\",\n )}\n onClick={() => void handleArchive()}\n destructive\n />\n </div>\n )}\n </div>\n </div>\n </header>\n\n <div className=\"flex-1 overflow-y-auto py-4 space-y-0.5\">\n {sourceContext?.pagePath && (\n <div className=\"mx-4 mb-4 rounded-lg border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {sourceContext.contextTitle || sourceContext.pagePath}\n </span>\n {sourceContext.entityType && sourceContext.entityId\n ? ` · ${sourceContext.entityType} ${sourceContext.entityId}`\n : \"\"}\n </div>\n )}\n {messagesError && (\n <div 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\">\n {tr(\n \"conversations.messagesUnavailable\",\n \"Messages couldn't be loaded right now. The conversation header and actions are still available.\",\n )}\n </div>\n )}\n {messagesLoading && (\n <div 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\">\n <Loader2 size={14} className=\"animate-spin\" />\n {tr(\"conversations.loadingMessages\", \"Loading messages...\")}\n </div>\n )}\n {!messagesLoading && !messagesError && messages.length === 0 && (\n <div 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\">\n {tr(\n \"conversations.noMessagesYet\",\n \"No messages yet. Start the conversation below.\",\n )}\n </div>\n )}\n {messages.map((message, index) => {\n const prevMessage = messages[index - 1];\n const showAvatar =\n !prevMessage ||\n prevMessage.authorId !== message.authorId ||\n prevMessage.type === \"SYSTEM\";\n\n return (\n <div key={message.id}>\n {editingMessageId === message.id ? (\n <div className=\"px-4 py-2\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground mb-1\">\n <span>\n {tr(\"conversations.editingMessage\", \"Editing message\")}\n </span>\n <button\n type=\"button\"\n onClick={handleEditCancel}\n className=\"hover:text-foreground\"\n >\n <X size={12} />\n </button>\n </div>\n <div className=\"flex items-end gap-2\">\n <textarea\n value={editingContent}\n onChange={(e) => setEditingContent(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n void handleEditSubmit();\n }\n if (e.key === \"Escape\") handleEditCancel();\n }}\n 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\"\n rows={2}\n />\n <button\n type=\"button\"\n onClick={() => void handleEditSubmit()}\n disabled={!editingContent.trim() || editingMessage}\n className=\"px-3 py-2 text-xs font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50\"\n >\n {tr(\"conversations.save\", \"Save\")}\n </button>\n </div>\n </div>\n ) : (\n <MessageBubble\n message={message}\n isOwnMessage={message.authorId === currentUserId}\n showAvatar={showAvatar}\n showSender={showAvatar}\n onReply={handleReply}\n onReact={(id, emoji) => void handleReact(id, emoji)}\n onEdit={handleEdit}\n onDelete={(id) => void handleDelete(id)}\n onTogglePin={(id, isPinned) =>\n void handleTogglePinMessage(id, isPinned)\n }\n />\n )}\n </div>\n );\n })}\n <div ref={messagesEndRef} />\n </div>\n\n <div className=\"border-t border-border px-4 py-3 bg-background\">\n {/* Reply-to indicator */}\n {replyingTo && (\n <div className=\"flex items-center gap-2 mb-2 px-3 py-1.5 rounded-lg bg-muted/50 text-xs text-muted-foreground\">\n <span>\n {tr(\"conversations.replyingTo\", \"Replying to\")}{\" \"}\n <strong className=\"text-foreground\">{replyingTo.sender}</strong>\n : {replyingTo.content.slice(0, 80)}\n {replyingTo.content.length > 80 ? \"…\" : \"\"}\n </span>\n <button\n type=\"button\"\n onClick={() => setReplyingTo(null)}\n className=\"ml-auto hover:text-foreground\"\n >\n <X size={12} />\n </button>\n </div>\n )}\n <div className=\"flex items-end gap-2\">\n <div className=\"flex-1 relative\">\n <textarea\n aria-label={tr(\n \"conversations.messageComposer\",\n \"Message composer\",\n )}\n value={messageInput}\n onChange={(event) => setMessageInput(event.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={`${tr(\"conversations.messageConversationPrefix\", \"Message\")} ${conversation.title}...`}\n rows={1}\n className={cn(\n \"w-full px-4 py-2.5 text-sm rounded-xl border border-border bg-muted/30\",\n \"resize-none overflow-hidden placeholder:text-muted-foreground\",\n \"focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent max-h-32\",\n )}\n style={{\n height: \"auto\",\n minHeight: \"40px\",\n }}\n onInput={(event) => {\n const target = event.target as HTMLTextAreaElement;\n target.style.height = \"auto\";\n target.style.height = `${Math.min(target.scrollHeight, 128)}px`;\n }}\n />\n </div>\n\n <button\n type=\"button\"\n aria-label={tr(\"conversations.sendMessage\", \"Send message\")}\n onClick={() => void handleSendMessage()}\n disabled={!messageInput.trim() || sendingMessage}\n className={cn(\n \"p-2.5 rounded-xl transition-all duration-150\",\n messageInput.trim() && !sendingMessage\n ? \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\",\n )}\n >\n {sendingMessage ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <SendHorizontal size={18} />\n )}\n </button>\n </div>\n </div>\n </div>\n\n {isParticipantsPanelOpen && conversation.isGroup && (\n <aside className=\"w-64 border-l border-border bg-background overflow-y-auto animate-in slide-in-from-right-4 duration-200\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {tr(\"conversations.members\", \"Members\")} (\n {participants.length || conversation.memberCount})\n </h3>\n <button\n type=\"button\"\n onClick={toggleParticipantsPanel}\n className=\"p-1 rounded text-muted-foreground hover:text-foreground\"\n >\n <Pin size={14} />\n </button>\n </div>\n\n <div className=\"space-y-1\">\n {participants.map((participant) => (\n <div\n key={participant.id}\n className=\"flex items-center gap-2.5 px-2 py-1.5 rounded-lg hover:bg-muted/50\"\n >\n <div className=\"w-7 h-7 rounded-full bg-muted flex items-center justify-center text-xs font-medium text-muted-foreground\">\n {participant.name\n .split(\" \")\n .map((word) => word[0])\n .join(\"\")\n .slice(0, 2)}\n </div>\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium text-foreground truncate\">\n {participant.name}\n </p>\n <p className=\"text-[10px] text-muted-foreground\">\n {tr(\"conversations.member\", \"Member\")}\n </p>\n </div>\n </div>\n ))}\n </div>\n </div>\n </aside>\n )}\n </div>\n );\n}\n\nfunction DropdownItem({\n icon,\n label,\n onClick,\n destructive,\n}: {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n destructive?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex items-center gap-2.5 w-full px-3 py-2 text-sm transition-colors text-left\",\n destructive\n ? \"text-destructive hover:bg-destructive/10\"\n : \"text-foreground hover:bg-muted/50\",\n )}\n >\n {icon}\n <span>{label}</span>\n </button>\n );\n}\n\nfunction HeaderButton({\n icon,\n label,\n active,\n onClick,\n}: {\n icon: React.ReactNode;\n label: string;\n active?: boolean;\n onClick?: () => void;\n}) {\n return (\n <PermissionGuard\n permission={CONVERSATIONS_PERMISSIONS.CONVERSATION_READ}\n allowUnavailablePermissions\n >\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={label}\n title={label}\n className={cn(\n \"p-2 rounded-lg transition-colors\",\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted/50\",\n )}\n >\n {icon}\n </button>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface ConversationListPageProps {
2
+ forcedFilterParam?: "channel" | "direct" | "group" | "archived";
3
+ }
4
+ export declare function ConversationListPage({ forcedFilterParam, }?: ConversationListPageProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=ConversationListPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationListPage.d.ts","sourceRoot":"","sources":["../../../src/conversations/pages/ConversationListPage.tsx"],"names":[],"mappings":"AAuDA,UAAU,yBAAyB;IACjC,iBAAiB,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;CACjE;AAED,wBAAgB,oBAAoB,CAAC,EACnC,iBAAiB,GAClB,GAAE,yBAA8B,2CAgYhC"}