@samirify/messenger 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,142 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ var chunk42TCO5DV_cjs = require('../chunk-42TCO5DV.cjs');
3
4
  var reactNative = require('react-native');
4
- var react = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var reactQuery = require('@tanstack/react-query');
7
-
8
- // src/native/InboxScreen.tsx
9
- var MessengerContext = react.createContext(null);
10
- function useMessengerConfig() {
11
- const ctx = react.useContext(MessengerContext);
12
- if (!ctx) {
13
- throw new Error(
14
- "@gymlium/messenger: useMessengerConfig must be used within MessengerProvider"
15
- );
16
- }
17
- return ctx;
18
- }
19
-
20
- // src/api.ts
21
- async function listThreads(http) {
22
- const res = await http.getJson(
23
- "/api/messages/threads"
24
- );
25
- return { ...res, data: res.data?.threads ?? [] };
26
- }
27
- async function openThread(http, clientUserId) {
28
- return http.postJson("/api/messages/threads", {
29
- ...clientUserId ? { client_user_id: clientUserId } : {}
30
- });
31
- }
32
- async function getThread(http, threadId, limit = 50, beforeId) {
33
- const params = new URLSearchParams({ limit: String(limit) });
34
- return http.getJson(`/api/messages/threads/${threadId}?${params.toString()}`);
35
- }
36
- async function sendMessage(http, threadId, body, image) {
37
- const path = `/api/messages/threads/${threadId}/messages`;
38
- if (image?.uri || image?.file) {
39
- const form = new FormData();
40
- if (body.trim()) form.append("body", body.trim());
41
- const filename = image.name ?? image.uri?.split("/").pop() ?? "photo.jpg";
42
- const match = /\.(\w+)$/.exec(filename);
43
- const type = image.type ?? (match ? `image/${match[1]}` : "image/jpeg");
44
- if (image.file) {
45
- form.append("image", image.file, filename);
46
- } else if (image.uri.startsWith("blob:") || image.uri.startsWith("data:")) {
47
- const blob = await fetch(image.uri).then((r) => r.blob());
48
- form.append("image", blob, filename);
49
- } else {
50
- form.append("image", {
51
- uri: image.uri,
52
- name: filename,
53
- type
54
- });
55
- }
56
- return http.postForm(path, form);
57
- }
58
- return http.postJson(path, { body });
59
- }
60
-
61
- // src/queryKeys.ts
62
- var messengerKeys = {
63
- all: ["messenger"],
64
- threads: () => [...messengerKeys.all, "threads"],
65
- thread: (id) => [...messengerKeys.all, "thread", id]
66
- };
67
-
68
- // src/hooks/useThreads.ts
69
- function useThreads(options) {
70
- const { http, enabled: featureOn } = useMessengerConfig();
71
- const enabled = featureOn;
72
- return reactQuery.useQuery({
73
- queryKey: messengerKeys.threads(),
74
- queryFn: async () => {
75
- const res = await listThreads(http);
76
- if (!res.success) {
77
- throw new Error(res.message ?? "Failed to load threads");
78
- }
79
- return res.data;
80
- },
81
- enabled
82
- });
83
- }
84
- function useOpenThread() {
85
- const { http, navigation } = useMessengerConfig();
86
- const qc = reactQuery.useQueryClient();
87
- return reactQuery.useMutation({
88
- mutationFn: async (clientUserId) => {
89
- const res = await openThread(http, clientUserId);
90
- if (!res.success || !res.data?.thread?.id) {
91
- throw new Error(res.message ?? "Could not open thread");
92
- }
93
- return res.data.thread;
94
- },
95
- onSuccess: (thread) => {
96
- void qc.invalidateQueries({ queryKey: messengerKeys.threads() });
97
- navigation.openThread(thread.id);
98
- }
99
- });
100
- }
6
+ var react = require('react');
101
7
 
102
- // src/i18nKeys.ts
103
- var MessengerI18n = {
104
- off: {
105
- key: "mobile.messenger.off",
106
- fallback: "Messaging is not enabled for this account."
107
- },
108
- inbox: { key: "mobile.messenger.inbox", fallback: "Chat" },
109
- chat: { key: "mobile.messenger.chat", fallback: "Chat" },
110
- messageCoach: {
111
- key: "mobile.messenger.messageCoach",
112
- fallback: "Message your coach"
113
- },
114
- empty: {
115
- key: "mobile.messenger.empty",
116
- fallback: "No conversations yet"
117
- },
118
- yourCoach: {
119
- key: "mobile.messenger.yourCoach",
120
- fallback: "Your coach"
121
- },
122
- photo: { key: "mobile.messenger.photo", fallback: "Photo" },
123
- noMessages: {
124
- key: "mobile.messenger.noMessages",
125
- fallback: "No messages yet"
126
- },
127
- startConversation: {
128
- key: "mobile.messenger.startConversation",
129
- fallback: "Say hello \u2014 send the first message."
130
- },
131
- typeMessage: {
132
- key: "mobile.messenger.typeMessage",
133
- fallback: "Type a message\u2026"
134
- },
135
- client: { key: "mobile.trainer.client", fallback: "Client" },
136
- back: { key: "common.back", fallback: "Back" }
137
- };
138
8
  function FeatureOff() {
139
- const { t, theme, navigation, onFeatureOff } = useMessengerConfig();
9
+ const { t, theme, navigation, onFeatureOff } = chunk42TCO5DV_cjs.useMessengerConfig();
140
10
  if (onFeatureOff) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: onFeatureOff() });
141
11
  const { colors, accentColor } = theme;
142
12
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -150,14 +20,14 @@ function FeatureOff() {
150
20
  padding: 24
151
21
  },
152
22
  children: [
153
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: colors.textMuted, textAlign: "center" }, children: t(MessengerI18n.off.key, MessengerI18n.off.fallback) }),
154
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: navigation.goBack, style: { marginTop: 16 }, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: accentColor }, children: t(MessengerI18n.back.key, MessengerI18n.back.fallback) }) })
23
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: colors.textMuted, textAlign: "center" }, children: t(chunk42TCO5DV_cjs.MessengerI18n.off.key, chunk42TCO5DV_cjs.MessengerI18n.off.fallback) }),
24
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: navigation.goBack, style: { marginTop: 16 }, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: accentColor }, children: t(chunk42TCO5DV_cjs.MessengerI18n.back.key, chunk42TCO5DV_cjs.MessengerI18n.back.fallback) }) })
155
25
  ]
156
26
  }
157
27
  );
158
28
  }
159
29
  function ThreadRow({ thread }) {
160
- const { user, t, isRtl, theme, navigation } = useMessengerConfig();
30
+ const { user, t, isRtl, theme, navigation } = chunk42TCO5DV_cjs.useMessengerConfig();
161
31
  const { colors, accentColor, fonts } = theme;
162
32
  const unread = Number(thread.unread_count ?? 0);
163
33
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -195,9 +65,9 @@ function ThreadRow({ thread }) {
195
65
  fontWeight: "600",
196
66
  fontSize: 16
197
67
  },
198
- children: user?.role === "admin" ? thread.client_name ?? t(MessengerI18n.client.key, MessengerI18n.client.fallback) : t(
199
- MessengerI18n.yourCoach.key,
200
- MessengerI18n.yourCoach.fallback
68
+ children: user?.role === "admin" ? thread.client_name ?? t(chunk42TCO5DV_cjs.MessengerI18n.client.key, chunk42TCO5DV_cjs.MessengerI18n.client.fallback) : t(
69
+ chunk42TCO5DV_cjs.MessengerI18n.yourCoach.key,
70
+ chunk42TCO5DV_cjs.MessengerI18n.yourCoach.fallback
201
71
  )
202
72
  }
203
73
  ),
@@ -211,9 +81,9 @@ function ThreadRow({ thread }) {
211
81
  marginTop: 4
212
82
  },
213
83
  numberOfLines: 1,
214
- children: thread.last_body || (thread.last_image_url ? t(MessengerI18n.photo.key, MessengerI18n.photo.fallback) : t(
215
- MessengerI18n.noMessages.key,
216
- MessengerI18n.noMessages.fallback
84
+ children: thread.last_body || (thread.last_image_url ? t(chunk42TCO5DV_cjs.MessengerI18n.photo.key, chunk42TCO5DV_cjs.MessengerI18n.photo.fallback) : t(
85
+ chunk42TCO5DV_cjs.MessengerI18n.noMessages.key,
86
+ chunk42TCO5DV_cjs.MessengerI18n.noMessages.fallback
217
87
  ))
218
88
  }
219
89
  )
@@ -253,10 +123,10 @@ function ThreadRow({ thread }) {
253
123
  );
254
124
  }
255
125
  function InboxScreen() {
256
- const { enabled, user, t, isRtl, theme, navigation } = useMessengerConfig();
126
+ const { enabled, user, t, isRtl, theme, navigation } = chunk42TCO5DV_cjs.useMessengerConfig();
257
127
  const { colors, accentColor, fonts } = theme;
258
- const threadsQuery = useThreads();
259
- const openThread2 = useOpenThread();
128
+ const threadsQuery = chunk42TCO5DV_cjs.useThreads();
129
+ const openThread = chunk42TCO5DV_cjs.useOpenThread();
260
130
  if (!enabled) return /* @__PURE__ */ jsxRuntime.jsx(FeatureOff, {});
261
131
  const threads = threadsQuery.data ?? [];
262
132
  const loading = threadsQuery.isLoading && threads.length === 0;
@@ -284,7 +154,7 @@ function InboxScreen() {
284
154
  fontWeight: "700",
285
155
  flex: 1
286
156
  },
287
- children: t(MessengerI18n.inbox.key, MessengerI18n.inbox.fallback)
157
+ children: t(chunk42TCO5DV_cjs.MessengerI18n.inbox.key, chunk42TCO5DV_cjs.MessengerI18n.inbox.fallback)
288
158
  }
289
159
  )
290
160
  ]
@@ -306,8 +176,8 @@ function InboxScreen() {
306
176
  user?.role === "client" && threads.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(
307
177
  reactNative.TouchableOpacity,
308
178
  {
309
- onPress: () => openThread2.mutate(void 0),
310
- disabled: openThread2.isPending,
179
+ onPress: () => openThread.mutate(void 0),
180
+ disabled: openThread.isPending,
311
181
  style: {
312
182
  marginBottom: 14,
313
183
  paddingVertical: 14,
@@ -315,7 +185,7 @@ function InboxScreen() {
315
185
  backgroundColor: accentColor,
316
186
  alignItems: "center"
317
187
  },
318
- children: openThread2.isPending ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: "#FFF" }) : /* @__PURE__ */ jsxRuntime.jsx(
188
+ children: openThread.isPending ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: "#FFF" }) : /* @__PURE__ */ jsxRuntime.jsx(
319
189
  reactNative.Text,
320
190
  {
321
191
  style: {
@@ -324,8 +194,8 @@ function InboxScreen() {
324
194
  fontWeight: "600"
325
195
  },
326
196
  children: t(
327
- MessengerI18n.messageCoach.key,
328
- MessengerI18n.messageCoach.fallback
197
+ chunk42TCO5DV_cjs.MessengerI18n.messageCoach.key,
198
+ chunk42TCO5DV_cjs.MessengerI18n.messageCoach.fallback
329
199
  )
330
200
  }
331
201
  )
@@ -353,7 +223,7 @@ function InboxScreen() {
353
223
  fontFamily: fonts.body,
354
224
  textAlign: "center"
355
225
  },
356
- children: t(MessengerI18n.empty.key, MessengerI18n.empty.fallback)
226
+ children: t(chunk42TCO5DV_cjs.MessengerI18n.empty.key, chunk42TCO5DV_cjs.MessengerI18n.empty.fallback)
357
227
  }
358
228
  )
359
229
  ]
@@ -364,50 +234,8 @@ function InboxScreen() {
364
234
  )
365
235
  ] });
366
236
  }
367
- var POLL_MS = 18e3;
368
- function useThread(threadId, options) {
369
- const { http, enabled: featureOn } = useMessengerConfig();
370
- const enabled = featureOn && Number.isFinite(threadId) && threadId > 0;
371
- const poll = true;
372
- return reactQuery.useQuery({
373
- queryKey: messengerKeys.thread(threadId),
374
- queryFn: async () => {
375
- const res = await getThread(http, threadId);
376
- if (!res.success) {
377
- throw new Error(res.message ?? "Failed to load thread");
378
- }
379
- return res.data;
380
- },
381
- enabled,
382
- refetchInterval: enabled && poll ? POLL_MS : false
383
- });
384
- }
385
- function useSendMessage(threadId) {
386
- const { http } = useMessengerConfig();
387
- const qc = reactQuery.useQueryClient();
388
- return reactQuery.useMutation({
389
- mutationFn: async (input) => {
390
- const res = await sendMessage(http, threadId, input.body, input.image);
391
- if (!res.success || !res.data?.message) {
392
- throw new Error(res.message ?? "Send failed");
393
- }
394
- return res.data.message;
395
- },
396
- onSuccess: (message) => {
397
- qc.setQueryData(
398
- messengerKeys.thread(threadId),
399
- (prev) => {
400
- if (!prev) return prev;
401
- if (prev.messages.some((m) => m.id === message.id)) return prev;
402
- return { ...prev, messages: [...prev.messages, message] };
403
- }
404
- );
405
- void qc.invalidateQueries({ queryKey: messengerKeys.threads() });
406
- }
407
- });
408
- }
409
237
  function MessageBubble({ message }) {
410
- const { user, isRtl, theme } = useMessengerConfig();
238
+ const { user, isRtl, theme } = chunk42TCO5DV_cjs.useMessengerConfig();
411
239
  const { colors, accentColor, fonts } = theme;
412
240
  const mine = message.sender_user_id === user?.id;
413
241
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -454,7 +282,7 @@ function Composer({
454
282
  sending,
455
283
  onSend
456
284
  }) {
457
- const { t, isRtl, theme, pickImage } = useMessengerConfig();
285
+ const { t, isRtl, theme, pickImage } = chunk42TCO5DV_cjs.useMessengerConfig();
458
286
  const { colors, accentColor, fonts } = theme;
459
287
  const [body, setBody] = react.useState("");
460
288
  async function onPick() {
@@ -491,8 +319,8 @@ function Composer({
491
319
  value: body,
492
320
  onChangeText: setBody,
493
321
  placeholder: t(
494
- MessengerI18n.typeMessage.key,
495
- MessengerI18n.typeMessage.fallback
322
+ chunk42TCO5DV_cjs.MessengerI18n.typeMessage.key,
323
+ chunk42TCO5DV_cjs.MessengerI18n.typeMessage.fallback
496
324
  ),
497
325
  placeholderTextColor: colors.textMuted,
498
326
  multiline: true,
@@ -542,7 +370,7 @@ function Composer({
542
370
  );
543
371
  }
544
372
  function FeatureOff2() {
545
- const { t, theme, onFeatureOff } = useMessengerConfig();
373
+ const { t, theme, onFeatureOff } = chunk42TCO5DV_cjs.useMessengerConfig();
546
374
  if (onFeatureOff) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: onFeatureOff() });
547
375
  return /* @__PURE__ */ jsxRuntime.jsx(
548
376
  reactNative.View,
@@ -553,16 +381,16 @@ function FeatureOff2() {
553
381
  alignItems: "center",
554
382
  justifyContent: "center"
555
383
  },
556
- children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.textMuted }, children: t(MessengerI18n.off.key, MessengerI18n.off.fallback) })
384
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: theme.colors.textMuted }, children: t(chunk42TCO5DV_cjs.MessengerI18n.off.key, chunk42TCO5DV_cjs.MessengerI18n.off.fallback) })
557
385
  }
558
386
  );
559
387
  }
560
388
  function ThreadScreen({ threadId }) {
561
- const { enabled, t, isRtl, theme, navigation } = useMessengerConfig();
389
+ const { enabled, t, isRtl, theme, navigation } = chunk42TCO5DV_cjs.useMessengerConfig();
562
390
  const { colors, accentColor, fonts } = theme;
563
391
  const listRef = react.useRef(null);
564
- const threadQuery = useThread(threadId);
565
- const sendMutation = useSendMessage(threadId);
392
+ const threadQuery = chunk42TCO5DV_cjs.useThread(threadId);
393
+ const sendMutation = chunk42TCO5DV_cjs.useSendMessage(threadId);
566
394
  if (!enabled) return /* @__PURE__ */ jsxRuntime.jsx(FeatureOff2, {});
567
395
  const messages = threadQuery.data?.messages ?? [];
568
396
  const loading = threadQuery.isLoading && messages.length === 0;
@@ -603,7 +431,7 @@ function ThreadScreen({ threadId }) {
603
431
  fontWeight: "700",
604
432
  flex: 1
605
433
  },
606
- children: t(MessengerI18n.chat.key, MessengerI18n.chat.fallback)
434
+ children: t(chunk42TCO5DV_cjs.MessengerI18n.chat.key, chunk42TCO5DV_cjs.MessengerI18n.chat.fallback)
607
435
  }
608
436
  )
609
437
  ]
@@ -627,8 +455,8 @@ function ThreadScreen({ threadId }) {
627
455
  fontFamily: fonts.body
628
456
  },
629
457
  children: t(
630
- MessengerI18n.startConversation.key,
631
- MessengerI18n.startConversation.fallback
458
+ chunk42TCO5DV_cjs.MessengerI18n.startConversation.key,
459
+ chunk42TCO5DV_cjs.MessengerI18n.startConversation.fallback
632
460
  )
633
461
  }
634
462
  ),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/provider.tsx","../../src/api.ts","../../src/queryKeys.ts","../../src/hooks/useThreads.ts","../../src/hooks/useOpenThread.ts","../../src/i18nKeys.ts","../../src/native/InboxScreen.tsx","../../src/hooks/useThread.ts","../../src/hooks/useSendMessage.ts","../../src/native/MessageBubble.tsx","../../src/native/Composer.tsx","../../src/native/ThreadScreen.tsx"],"names":["createContext","useContext","useQuery","useQueryClient","useMutation","jsx","Fragment","jsxs","View","Text","TouchableOpacity","openThread","ScrollView","RefreshControl","ActivityIndicator","Image","useState","Platform","TextInput","FeatureOff","useRef","KeyboardAvoidingView","FlatList"],"mappings":"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","file":"index.cjs","sourcesContent":["import React, { createContext, useContext, type ReactNode } from \"react\";\nimport type { MessengerConfig } from \"./types\";\n\nconst MessengerContext = createContext<MessengerConfig | null>(null);\n\nexport function MessengerProvider({\n config,\n children,\n}: {\n config: MessengerConfig;\n children: ReactNode;\n}) {\n return (\n <MessengerContext.Provider value={config}>\n {children}\n </MessengerContext.Provider>\n );\n}\n\nexport function useMessengerConfig(): MessengerConfig {\n const ctx = useContext(MessengerContext);\n if (!ctx) {\n throw new Error(\n \"@gymlium/messenger: useMessengerConfig must be used within MessengerProvider\"\n );\n }\n return ctx;\n}\n\n/** Safe variant for optional host chrome (returns null outside provider). */\nexport function useOptionalMessengerConfig(): MessengerConfig | null {\n return useContext(MessengerContext);\n}\n","import type {\n ApiResult,\n ChatMessage,\n MessageThread,\n MessengerHttp,\n PickedImage,\n} from \"./types\";\n\nexport async function listThreads(\n http: MessengerHttp\n): Promise<ApiResult<MessageThread[]>> {\n const res = await http.getJson<{ threads: MessageThread[] }>(\n \"/api/messages/threads\"\n );\n return { ...res, data: res.data?.threads ?? [] };\n}\n\nexport async function openThread(\n http: MessengerHttp,\n clientUserId?: number\n): Promise<ApiResult<{ thread: MessageThread }>> {\n return http.postJson<{ thread: MessageThread }>(\"/api/messages/threads\", {\n ...(clientUserId ? { client_user_id: clientUserId } : {}),\n });\n}\n\nexport async function getThread(\n http: MessengerHttp,\n threadId: number,\n limit = 50,\n beforeId?: number\n): Promise<ApiResult<{ thread: MessageThread; messages: ChatMessage[] }>> {\n const params = new URLSearchParams({ limit: String(limit) });\n if (beforeId != null) params.set(\"before_id\", String(beforeId));\n return http.getJson(`/api/messages/threads/${threadId}?${params.toString()}`);\n}\n\nexport async function sendMessage(\n http: MessengerHttp,\n threadId: number,\n body: string,\n image?: PickedImage | null\n): Promise<ApiResult<{ message: ChatMessage }>> {\n const path = `/api/messages/threads/${threadId}/messages`;\n if (image?.uri || image?.file) {\n const form = new FormData();\n if (body.trim()) form.append(\"body\", body.trim());\n const filename =\n image.name ??\n image.uri?.split(\"/\").pop() ??\n \"photo.jpg\";\n const match = /\\.(\\w+)$/.exec(filename);\n const type =\n image.type ?? (match ? `image/${match[1]}` : \"image/jpeg\");\n\n if (image.file) {\n form.append(\"image\", image.file, filename);\n } else if (image.uri.startsWith(\"blob:\") || image.uri.startsWith(\"data:\")) {\n const blob = await fetch(image.uri).then((r) => r.blob());\n form.append(\"image\", blob, filename);\n } else {\n // React Native FormData file shape\n form.append(\"image\", {\n uri: image.uri,\n name: filename,\n type,\n } as unknown as Blob);\n }\n return http.postForm<{ message: ChatMessage }>(path, form);\n }\n return http.postJson<{ message: ChatMessage }>(path, { body });\n}\n\nexport async function markThreadRead(\n http: MessengerHttp,\n threadId: number\n): Promise<ApiResult<{ success: boolean }>> {\n return http.patchJson(`/api/messages/threads/${threadId}/read`, {});\n}\n\nexport function sumUnread(threads: MessageThread[]): number {\n return threads.reduce((sum, th) => sum + Number(th.unread_count ?? 0), 0);\n}\n","export const messengerKeys = {\n all: [\"messenger\"] as const,\n threads: () => [...messengerKeys.all, \"threads\"] as const,\n thread: (id: number) => [...messengerKeys.all, \"thread\", id] as const,\n};\n","import { useQuery } from \"@tanstack/react-query\";\nimport { listThreads } from \"../api\";\nimport { messengerKeys } from \"../queryKeys\";\nimport { useMessengerConfig } from \"../provider\";\n\nexport function useThreads(options?: { enabled?: boolean }) {\n const { http, enabled: featureOn } = useMessengerConfig();\n const enabled = (options?.enabled ?? true) && featureOn;\n\n return useQuery({\n queryKey: messengerKeys.threads(),\n queryFn: async () => {\n const res = await listThreads(http);\n if (!res.success) {\n throw new Error(res.message ?? \"Failed to load threads\");\n }\n return res.data;\n },\n enabled,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { openThread } from \"../api\";\nimport { messengerKeys } from \"../queryKeys\";\nimport { useMessengerConfig } from \"../provider\";\nimport type { MessageThread } from \"../types\";\n\nexport function useOpenThread() {\n const { http, navigation } = useMessengerConfig();\n const qc = useQueryClient();\n\n return useMutation({\n mutationFn: async (clientUserId?: number) => {\n const res = await openThread(http, clientUserId);\n if (!res.success || !res.data?.thread?.id) {\n throw new Error(res.message ?? \"Could not open thread\");\n }\n return res.data.thread as MessageThread;\n },\n onSuccess: (thread: MessageThread) => {\n void qc.invalidateQueries({ queryKey: messengerKeys.threads() });\n navigation.openThread(thread.id);\n },\n });\n}\n","/** Stable i18n keys + English fallbacks used by the package UI. */\nexport const MessengerI18n = {\n off: {\n key: \"mobile.messenger.off\",\n fallback: \"Messaging is not enabled for this account.\",\n },\n inbox: { key: \"mobile.messenger.inbox\", fallback: \"Chat\" },\n chat: { key: \"mobile.messenger.chat\", fallback: \"Chat\" },\n /** Dock / list title — prefer over inbox for web UI copy. */\n messages: { key: \"mobile.messenger.messages\", fallback: \"Chat\" },\n messagesHint: {\n key: \"mobile.messenger.messagesHint\",\n fallback: \"Message your coach anytime\",\n },\n messageCoach: {\n key: \"mobile.messenger.messageCoach\",\n fallback: \"Message your coach\",\n },\n empty: {\n key: \"mobile.messenger.empty\",\n fallback: \"No conversations yet\",\n },\n yourCoach: {\n key: \"mobile.messenger.yourCoach\",\n fallback: \"Your coach\",\n },\n photo: { key: \"mobile.messenger.photo\", fallback: \"Photo\" },\n noMessages: {\n key: \"mobile.messenger.noMessages\",\n fallback: \"No messages yet\",\n },\n startConversation: {\n key: \"mobile.messenger.startConversation\",\n fallback: \"Say hello — send the first message.\",\n },\n typeMessage: {\n key: \"mobile.messenger.typeMessage\",\n fallback: \"Type a message…\",\n },\n client: { key: \"mobile.trainer.client\", fallback: \"Client\" },\n back: { key: \"common.back\", fallback: \"Back\" },\n} as const;\n","import React from \"react\";\nimport {\n View,\n Text,\n TouchableOpacity,\n ActivityIndicator,\n ScrollView,\n RefreshControl,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { useThreads } from \"../hooks/useThreads\";\nimport { useOpenThread } from \"../hooks/useOpenThread\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { MessageThread } from \"../types\";\n\nfunction FeatureOff() {\n const { t, theme, navigation, onFeatureOff } = useMessengerConfig();\n if (onFeatureOff) return <>{onFeatureOff()}</>;\n const { colors, accentColor } = theme;\n return (\n <View\n style={{\n flex: 1,\n backgroundColor: colors.background,\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 24,\n }}\n >\n <Text style={{ color: colors.textMuted, textAlign: \"center\" }}>\n {t(MessengerI18n.off.key, MessengerI18n.off.fallback)}\n </Text>\n <TouchableOpacity onPress={navigation.goBack} style={{ marginTop: 16 }}>\n <Text style={{ color: accentColor }}>\n {t(MessengerI18n.back.key, MessengerI18n.back.fallback)}\n </Text>\n </TouchableOpacity>\n </View>\n );\n}\n\nfunction ThreadRow({ thread }: { thread: MessageThread }) {\n const { user, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const unread = Number(thread.unread_count ?? 0);\n\n return (\n <TouchableOpacity\n onPress={() => navigation.openThread(thread.id)}\n activeOpacity={0.8}\n >\n <View\n style={{\n marginBottom: 10,\n padding: 14,\n borderRadius: 14,\n backgroundColor: colors.surface,\n borderWidth: 1,\n borderColor: colors.border,\n }}\n >\n <View\n style={{\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <View style={{ flex: 1 }}>\n <Text\n style={{\n color: colors.text,\n fontFamily: fonts.displaySemiBold,\n fontWeight: \"600\",\n fontSize: 16,\n }}\n >\n {user?.role === \"admin\"\n ? thread.client_name ??\n t(MessengerI18n.client.key, MessengerI18n.client.fallback)\n : t(\n MessengerI18n.yourCoach.key,\n MessengerI18n.yourCoach.fallback\n )}\n </Text>\n <Text\n style={{\n color: colors.textSecondary,\n fontFamily: fonts.body,\n fontSize: 13,\n marginTop: 4,\n }}\n numberOfLines={1}\n >\n {thread.last_body ||\n (thread.last_image_url\n ? t(MessengerI18n.photo.key, MessengerI18n.photo.fallback)\n : t(\n MessengerI18n.noMessages.key,\n MessengerI18n.noMessages.fallback\n ))}\n </Text>\n </View>\n {unread > 0 && (\n <View\n style={{\n minWidth: 22,\n height: 22,\n borderRadius: 11,\n backgroundColor: accentColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingHorizontal: 6,\n }}\n >\n <Text\n style={{\n color: \"#FFF\",\n fontSize: 11,\n fontFamily: fonts.bodySemiBold,\n fontWeight: \"600\",\n }}\n >\n {unread}\n </Text>\n </View>\n )}\n </View>\n </View>\n </TouchableOpacity>\n );\n}\n\nexport function InboxScreen() {\n const { enabled, user, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const threadsQuery = useThreads();\n const openThread = useOpenThread();\n\n if (!enabled) return <FeatureOff />;\n\n const threads = threadsQuery.data ?? [];\n const loading = threadsQuery.isLoading && threads.length === 0;\n\n return (\n <View style={{ flex: 1, backgroundColor: colors.background }}>\n <View\n style={{\n paddingTop: 56,\n paddingHorizontal: 16,\n paddingBottom: 12,\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <TouchableOpacity onPress={navigation.goBack} hitSlop={12}>\n <Text style={{ fontSize: 22, color: colors.text }}>\n {isRtl ? \"→\" : \"←\"}\n </Text>\n </TouchableOpacity>\n <Text\n style={{\n color: colors.text,\n fontSize: 22,\n fontFamily: fonts.displayBold,\n fontWeight: \"700\",\n flex: 1,\n }}\n >\n {t(MessengerI18n.inbox.key, MessengerI18n.inbox.fallback)}\n </Text>\n </View>\n\n <ScrollView\n contentContainerStyle={{ paddingHorizontal: 16, paddingBottom: 32 }}\n refreshControl={\n <RefreshControl\n refreshing={threadsQuery.isRefetching}\n onRefresh={() => void threadsQuery.refetch()}\n tintColor={accentColor}\n />\n }\n >\n {user?.role === \"client\" && threads.length === 0 && (\n <TouchableOpacity\n onPress={() => openThread.mutate(undefined)}\n disabled={openThread.isPending}\n style={{\n marginBottom: 14,\n paddingVertical: 14,\n borderRadius: 12,\n backgroundColor: accentColor,\n alignItems: \"center\",\n }}\n >\n {openThread.isPending ? (\n <ActivityIndicator color=\"#FFF\" />\n ) : (\n <Text\n style={{\n color: \"#FFF\",\n fontFamily: fonts.bodySemiBold,\n fontWeight: \"600\",\n }}\n >\n {t(\n MessengerI18n.messageCoach.key,\n MessengerI18n.messageCoach.fallback\n )}\n </Text>\n )}\n </TouchableOpacity>\n )}\n\n {loading ? (\n <ActivityIndicator color={accentColor} style={{ marginTop: 40 }} />\n ) : threads.length === 0 ? (\n <View\n style={{\n alignItems: \"center\",\n paddingVertical: 40,\n borderRadius: 14,\n backgroundColor: colors.surface,\n borderWidth: 1,\n borderColor: colors.border,\n }}\n >\n <Text style={{ fontSize: 28, color: colors.textMuted }}>···</Text>\n <Text\n style={{\n color: colors.textMuted,\n marginTop: 12,\n fontFamily: fonts.body,\n textAlign: \"center\",\n }}\n >\n {t(MessengerI18n.empty.key, MessengerI18n.empty.fallback)}\n </Text>\n </View>\n ) : (\n threads.map((th: MessageThread) => (\n <ThreadRow key={th.id} thread={th} />\n ))\n )}\n </ScrollView>\n </View>\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { getThread } from \"../api\";\nimport { messengerKeys } from \"../queryKeys\";\nimport { useMessengerConfig } from \"../provider\";\n\nconst POLL_MS = 18_000;\n\nexport function useThread(\n threadId: number,\n options?: { enabled?: boolean; poll?: boolean }\n) {\n const { http, enabled: featureOn } = useMessengerConfig();\n const enabled =\n (options?.enabled ?? true) && featureOn && Number.isFinite(threadId) && threadId > 0;\n const poll = options?.poll ?? true;\n\n return useQuery({\n queryKey: messengerKeys.thread(threadId),\n queryFn: async () => {\n const res = await getThread(http, threadId);\n if (!res.success) {\n throw new Error(res.message ?? \"Failed to load thread\");\n }\n return res.data;\n },\n enabled,\n refetchInterval: enabled && poll ? POLL_MS : false,\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { sendMessage } from \"../api\";\nimport { messengerKeys } from \"../queryKeys\";\nimport { useMessengerConfig } from \"../provider\";\nimport type { ChatMessage, PickedImage } from \"../types\";\n\nexport function useSendMessage(threadId: number) {\n const { http } = useMessengerConfig();\n const qc = useQueryClient();\n\n return useMutation({\n mutationFn: async (input: { body: string; image?: PickedImage | null }) => {\n const res = await sendMessage(http, threadId, input.body, input.image);\n if (!res.success || !res.data?.message) {\n throw new Error(res.message ?? \"Send failed\");\n }\n return res.data.message as ChatMessage;\n },\n onSuccess: (message: ChatMessage) => {\n qc.setQueryData(\n messengerKeys.thread(threadId),\n (prev: { thread: unknown; messages: ChatMessage[] } | undefined) => {\n if (!prev) return prev;\n if (prev.messages.some((m) => m.id === message.id)) return prev;\n return { ...prev, messages: [...prev.messages, message] };\n }\n );\n void qc.invalidateQueries({ queryKey: messengerKeys.threads() });\n },\n });\n}\n","import React from \"react\";\nimport { View, Text, Image } from \"react-native\";\nimport type { ChatMessage } from \"../types\";\nimport { useMessengerConfig } from \"../provider\";\n\nexport function MessageBubble({ message }: { message: ChatMessage }) {\n const { user, isRtl, theme } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const mine = message.sender_user_id === user?.id;\n\n return (\n <View\n style={{\n alignSelf: mine\n ? isRtl\n ? \"flex-start\"\n : \"flex-end\"\n : isRtl\n ? \"flex-end\"\n : \"flex-start\",\n maxWidth: \"80%\",\n marginBottom: 10,\n backgroundColor: mine ? accentColor : colors.surfaceSecondary,\n borderRadius: 16,\n paddingHorizontal: 12,\n paddingVertical: 10,\n }}\n >\n {message.image_url ? (\n <Image\n source={{ uri: message.image_url }}\n style={{\n width: 180,\n height: 180,\n borderRadius: 10,\n marginBottom: message.body ? 8 : 0,\n }}\n />\n ) : null}\n {message.body ? (\n <Text\n style={{\n color: mine ? \"#FFF\" : colors.text,\n fontFamily: fonts.body,\n fontSize: 15,\n }}\n >\n {message.body}\n </Text>\n ) : null}\n </View>\n );\n}\n","import React, { useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ActivityIndicator,\n Platform,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { PickedImage } from \"../types\";\n\nexport function Composer({\n sending,\n onSend,\n}: {\n sending: boolean;\n onSend: (body: string, image?: PickedImage | null) => void | Promise<void>;\n}) {\n const { t, isRtl, theme, pickImage } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const [body, setBody] = useState(\"\");\n\n async function onPick() {\n const image = await pickImage();\n if (image) {\n await onSend(body, image);\n setBody(\"\");\n }\n }\n\n async function onPressSend() {\n if (!body.trim() || sending) return;\n const text = body;\n await onSend(text, null);\n setBody(\"\");\n }\n\n return (\n <View\n style={{\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"flex-end\",\n gap: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n borderTopWidth: 1,\n borderTopColor: colors.border,\n paddingBottom: Platform.OS === \"ios\" ? 28 : 12,\n }}\n >\n <TouchableOpacity onPress={onPick} hitSlop={8} disabled={sending}>\n <Text style={{ fontSize: 22, color: accentColor }}>▣</Text>\n </TouchableOpacity>\n <TextInput\n value={body}\n onChangeText={setBody}\n placeholder={t(\n MessengerI18n.typeMessage.key,\n MessengerI18n.typeMessage.fallback\n )}\n placeholderTextColor={colors.textMuted}\n multiline\n style={{\n flex: 1,\n maxHeight: 100,\n borderWidth: 1,\n borderColor: colors.border,\n borderRadius: 16,\n paddingHorizontal: 14,\n paddingVertical: 10,\n color: colors.text,\n fontFamily: fonts.body,\n textAlign: isRtl ? \"right\" : \"left\",\n backgroundColor: colors.surface,\n }}\n />\n <TouchableOpacity\n onPress={onPressSend}\n disabled={sending || !body.trim()}\n style={{\n width: 40,\n height: 40,\n borderRadius: 20,\n backgroundColor: body.trim()\n ? accentColor\n : colors.surfaceSecondary,\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {sending ? (\n <ActivityIndicator color=\"#FFF\" size=\"small\" />\n ) : (\n <Text\n style={{\n color: body.trim() ? \"#FFF\" : colors.textMuted,\n fontSize: 16,\n fontWeight: \"700\",\n }}\n >\n ➤\n </Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n","import React, { useRef } from \"react\";\nimport {\n View,\n Text,\n TouchableOpacity,\n ActivityIndicator,\n FlatList,\n KeyboardAvoidingView,\n Platform,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { useThread } from \"../hooks/useThread\";\nimport { useSendMessage } from \"../hooks/useSendMessage\";\nimport { MessageBubble } from \"./MessageBubble\";\nimport { Composer } from \"./Composer\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { ChatMessage, PickedImage } from \"../types\";\n\nfunction FeatureOff() {\n const { t, theme, onFeatureOff } = useMessengerConfig();\n if (onFeatureOff) return <>{onFeatureOff()}</>;\n return (\n <View\n style={{\n flex: 1,\n backgroundColor: theme.colors.background,\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <Text style={{ color: theme.colors.textMuted }}>\n {t(MessengerI18n.off.key, MessengerI18n.off.fallback)}\n </Text>\n </View>\n );\n}\n\nexport function ThreadScreen({ threadId }: { threadId: number }) {\n const { enabled, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const listRef = useRef<FlatList<ChatMessage> | null>(null);\n const threadQuery = useThread(threadId);\n const sendMutation = useSendMessage(threadId);\n\n if (!enabled) return <FeatureOff />;\n\n const messages = threadQuery.data?.messages ?? [];\n const loading = threadQuery.isLoading && messages.length === 0;\n\n async function handleSend(body: string, image?: PickedImage | null) {\n if ((!body.trim() && !image) || sendMutation.isPending) return;\n await sendMutation.mutateAsync({ body, image });\n setTimeout(() => listRef.current?.scrollToEnd({ animated: true }), 100);\n }\n\n return (\n <KeyboardAvoidingView\n style={{ flex: 1, backgroundColor: colors.background }}\n behavior={Platform.OS === \"ios\" ? \"padding\" : undefined}\n keyboardVerticalOffset={0}\n >\n <View\n style={{\n paddingTop: 56,\n paddingHorizontal: 16,\n paddingBottom: 12,\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.border,\n }}\n >\n <TouchableOpacity onPress={navigation.goBack} hitSlop={12}>\n <Text style={{ fontSize: 22, color: colors.text }}>\n {isRtl ? \"→\" : \"←\"}\n </Text>\n </TouchableOpacity>\n <Text\n style={{\n color: colors.text,\n fontSize: 18,\n fontFamily: fonts.displayBold,\n fontWeight: \"700\",\n flex: 1,\n }}\n >\n {t(MessengerI18n.chat.key, MessengerI18n.chat.fallback)}\n </Text>\n </View>\n\n {loading ? (\n <ActivityIndicator color={accentColor} style={{ marginTop: 40 }} />\n ) : (\n <FlatList\n ref={listRef}\n data={messages}\n keyExtractor={(m: ChatMessage) => String(m.id)}\n contentContainerStyle={{ padding: 16, paddingBottom: 8 }}\n onContentSizeChange={() =>\n listRef.current?.scrollToEnd({ animated: false })\n }\n ListEmptyComponent={\n <Text\n style={{\n color: colors.textMuted,\n textAlign: \"center\",\n marginTop: 40,\n fontFamily: fonts.body,\n }}\n >\n {t(\n MessengerI18n.startConversation.key,\n MessengerI18n.startConversation.fallback\n )}\n </Text>\n }\n renderItem={({ item }: { item: ChatMessage }) => (\n <MessageBubble message={item} />\n )}\n />\n )}\n\n <Composer sending={sendMutation.isPending} onSend={handleSend} />\n </KeyboardAvoidingView>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/native/InboxScreen.tsx","../../src/native/MessageBubble.tsx","../../src/native/Composer.tsx","../../src/native/ThreadScreen.tsx"],"names":["useMessengerConfig","jsx","Fragment","jsxs","View","Text","MessengerI18n","TouchableOpacity","useThreads","useOpenThread","ScrollView","RefreshControl","ActivityIndicator","Image","useState","Platform","TextInput","FeatureOff","useRef","useThread","useSendMessage","KeyboardAvoidingView","FlatList"],"mappings":"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","file":"index.cjs","sourcesContent":["import React from \"react\";\nimport {\n View,\n Text,\n TouchableOpacity,\n ActivityIndicator,\n ScrollView,\n RefreshControl,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { useThreads } from \"../hooks/useThreads\";\nimport { useOpenThread } from \"../hooks/useOpenThread\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { MessageThread } from \"../types\";\n\nfunction FeatureOff() {\n const { t, theme, navigation, onFeatureOff } = useMessengerConfig();\n if (onFeatureOff) return <>{onFeatureOff()}</>;\n const { colors, accentColor } = theme;\n return (\n <View\n style={{\n flex: 1,\n backgroundColor: colors.background,\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 24,\n }}\n >\n <Text style={{ color: colors.textMuted, textAlign: \"center\" }}>\n {t(MessengerI18n.off.key, MessengerI18n.off.fallback)}\n </Text>\n <TouchableOpacity onPress={navigation.goBack} style={{ marginTop: 16 }}>\n <Text style={{ color: accentColor }}>\n {t(MessengerI18n.back.key, MessengerI18n.back.fallback)}\n </Text>\n </TouchableOpacity>\n </View>\n );\n}\n\nfunction ThreadRow({ thread }: { thread: MessageThread }) {\n const { user, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const unread = Number(thread.unread_count ?? 0);\n\n return (\n <TouchableOpacity\n onPress={() => navigation.openThread(thread.id)}\n activeOpacity={0.8}\n >\n <View\n style={{\n marginBottom: 10,\n padding: 14,\n borderRadius: 14,\n backgroundColor: colors.surface,\n borderWidth: 1,\n borderColor: colors.border,\n }}\n >\n <View\n style={{\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <View style={{ flex: 1 }}>\n <Text\n style={{\n color: colors.text,\n fontFamily: fonts.displaySemiBold,\n fontWeight: \"600\",\n fontSize: 16,\n }}\n >\n {user?.role === \"admin\"\n ? thread.client_name ??\n t(MessengerI18n.client.key, MessengerI18n.client.fallback)\n : t(\n MessengerI18n.yourCoach.key,\n MessengerI18n.yourCoach.fallback\n )}\n </Text>\n <Text\n style={{\n color: colors.textSecondary,\n fontFamily: fonts.body,\n fontSize: 13,\n marginTop: 4,\n }}\n numberOfLines={1}\n >\n {thread.last_body ||\n (thread.last_image_url\n ? t(MessengerI18n.photo.key, MessengerI18n.photo.fallback)\n : t(\n MessengerI18n.noMessages.key,\n MessengerI18n.noMessages.fallback\n ))}\n </Text>\n </View>\n {unread > 0 && (\n <View\n style={{\n minWidth: 22,\n height: 22,\n borderRadius: 11,\n backgroundColor: accentColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingHorizontal: 6,\n }}\n >\n <Text\n style={{\n color: \"#FFF\",\n fontSize: 11,\n fontFamily: fonts.bodySemiBold,\n fontWeight: \"600\",\n }}\n >\n {unread}\n </Text>\n </View>\n )}\n </View>\n </View>\n </TouchableOpacity>\n );\n}\n\nexport function InboxScreen() {\n const { enabled, user, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const threadsQuery = useThreads();\n const openThread = useOpenThread();\n\n if (!enabled) return <FeatureOff />;\n\n const threads = threadsQuery.data ?? [];\n const loading = threadsQuery.isLoading && threads.length === 0;\n\n return (\n <View style={{ flex: 1, backgroundColor: colors.background }}>\n <View\n style={{\n paddingTop: 56,\n paddingHorizontal: 16,\n paddingBottom: 12,\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <TouchableOpacity onPress={navigation.goBack} hitSlop={12}>\n <Text style={{ fontSize: 22, color: colors.text }}>\n {isRtl ? \"→\" : \"←\"}\n </Text>\n </TouchableOpacity>\n <Text\n style={{\n color: colors.text,\n fontSize: 22,\n fontFamily: fonts.displayBold,\n fontWeight: \"700\",\n flex: 1,\n }}\n >\n {t(MessengerI18n.inbox.key, MessengerI18n.inbox.fallback)}\n </Text>\n </View>\n\n <ScrollView\n contentContainerStyle={{ paddingHorizontal: 16, paddingBottom: 32 }}\n refreshControl={\n <RefreshControl\n refreshing={threadsQuery.isRefetching}\n onRefresh={() => void threadsQuery.refetch()}\n tintColor={accentColor}\n />\n }\n >\n {user?.role === \"client\" && threads.length === 0 && (\n <TouchableOpacity\n onPress={() => openThread.mutate(undefined)}\n disabled={openThread.isPending}\n style={{\n marginBottom: 14,\n paddingVertical: 14,\n borderRadius: 12,\n backgroundColor: accentColor,\n alignItems: \"center\",\n }}\n >\n {openThread.isPending ? (\n <ActivityIndicator color=\"#FFF\" />\n ) : (\n <Text\n style={{\n color: \"#FFF\",\n fontFamily: fonts.bodySemiBold,\n fontWeight: \"600\",\n }}\n >\n {t(\n MessengerI18n.messageCoach.key,\n MessengerI18n.messageCoach.fallback\n )}\n </Text>\n )}\n </TouchableOpacity>\n )}\n\n {loading ? (\n <ActivityIndicator color={accentColor} style={{ marginTop: 40 }} />\n ) : threads.length === 0 ? (\n <View\n style={{\n alignItems: \"center\",\n paddingVertical: 40,\n borderRadius: 14,\n backgroundColor: colors.surface,\n borderWidth: 1,\n borderColor: colors.border,\n }}\n >\n <Text style={{ fontSize: 28, color: colors.textMuted }}>···</Text>\n <Text\n style={{\n color: colors.textMuted,\n marginTop: 12,\n fontFamily: fonts.body,\n textAlign: \"center\",\n }}\n >\n {t(MessengerI18n.empty.key, MessengerI18n.empty.fallback)}\n </Text>\n </View>\n ) : (\n threads.map((th: MessageThread) => (\n <ThreadRow key={th.id} thread={th} />\n ))\n )}\n </ScrollView>\n </View>\n );\n}\n","import React from \"react\";\nimport { View, Text, Image } from \"react-native\";\nimport type { ChatMessage } from \"../types\";\nimport { useMessengerConfig } from \"../provider\";\n\nexport function MessageBubble({ message }: { message: ChatMessage }) {\n const { user, isRtl, theme } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const mine = message.sender_user_id === user?.id;\n\n return (\n <View\n style={{\n alignSelf: mine\n ? isRtl\n ? \"flex-start\"\n : \"flex-end\"\n : isRtl\n ? \"flex-end\"\n : \"flex-start\",\n maxWidth: \"80%\",\n marginBottom: 10,\n backgroundColor: mine ? accentColor : colors.surfaceSecondary,\n borderRadius: 16,\n paddingHorizontal: 12,\n paddingVertical: 10,\n }}\n >\n {message.image_url ? (\n <Image\n source={{ uri: message.image_url }}\n style={{\n width: 180,\n height: 180,\n borderRadius: 10,\n marginBottom: message.body ? 8 : 0,\n }}\n />\n ) : null}\n {message.body ? (\n <Text\n style={{\n color: mine ? \"#FFF\" : colors.text,\n fontFamily: fonts.body,\n fontSize: 15,\n }}\n >\n {message.body}\n </Text>\n ) : null}\n </View>\n );\n}\n","import React, { useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ActivityIndicator,\n Platform,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { PickedImage } from \"../types\";\n\nexport function Composer({\n sending,\n onSend,\n}: {\n sending: boolean;\n onSend: (body: string, image?: PickedImage | null) => void | Promise<void>;\n}) {\n const { t, isRtl, theme, pickImage } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const [body, setBody] = useState(\"\");\n\n async function onPick() {\n const image = await pickImage();\n if (image) {\n await onSend(body, image);\n setBody(\"\");\n }\n }\n\n async function onPressSend() {\n if (!body.trim() || sending) return;\n const text = body;\n await onSend(text, null);\n setBody(\"\");\n }\n\n return (\n <View\n style={{\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"flex-end\",\n gap: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n borderTopWidth: 1,\n borderTopColor: colors.border,\n paddingBottom: Platform.OS === \"ios\" ? 28 : 12,\n }}\n >\n <TouchableOpacity onPress={onPick} hitSlop={8} disabled={sending}>\n <Text style={{ fontSize: 22, color: accentColor }}>▣</Text>\n </TouchableOpacity>\n <TextInput\n value={body}\n onChangeText={setBody}\n placeholder={t(\n MessengerI18n.typeMessage.key,\n MessengerI18n.typeMessage.fallback\n )}\n placeholderTextColor={colors.textMuted}\n multiline\n style={{\n flex: 1,\n maxHeight: 100,\n borderWidth: 1,\n borderColor: colors.border,\n borderRadius: 16,\n paddingHorizontal: 14,\n paddingVertical: 10,\n color: colors.text,\n fontFamily: fonts.body,\n textAlign: isRtl ? \"right\" : \"left\",\n backgroundColor: colors.surface,\n }}\n />\n <TouchableOpacity\n onPress={onPressSend}\n disabled={sending || !body.trim()}\n style={{\n width: 40,\n height: 40,\n borderRadius: 20,\n backgroundColor: body.trim()\n ? accentColor\n : colors.surfaceSecondary,\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {sending ? (\n <ActivityIndicator color=\"#FFF\" size=\"small\" />\n ) : (\n <Text\n style={{\n color: body.trim() ? \"#FFF\" : colors.textMuted,\n fontSize: 16,\n fontWeight: \"700\",\n }}\n >\n ➤\n </Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n","import React, { useRef } from \"react\";\nimport {\n View,\n Text,\n TouchableOpacity,\n ActivityIndicator,\n FlatList,\n KeyboardAvoidingView,\n Platform,\n} from \"react-native\";\nimport { useMessengerConfig } from \"../provider\";\nimport { useThread } from \"../hooks/useThread\";\nimport { useSendMessage } from \"../hooks/useSendMessage\";\nimport { MessageBubble } from \"./MessageBubble\";\nimport { Composer } from \"./Composer\";\nimport { MessengerI18n } from \"../i18nKeys\";\nimport type { ChatMessage, PickedImage } from \"../types\";\n\nfunction FeatureOff() {\n const { t, theme, onFeatureOff } = useMessengerConfig();\n if (onFeatureOff) return <>{onFeatureOff()}</>;\n return (\n <View\n style={{\n flex: 1,\n backgroundColor: theme.colors.background,\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <Text style={{ color: theme.colors.textMuted }}>\n {t(MessengerI18n.off.key, MessengerI18n.off.fallback)}\n </Text>\n </View>\n );\n}\n\nexport function ThreadScreen({ threadId }: { threadId: number }) {\n const { enabled, t, isRtl, theme, navigation } = useMessengerConfig();\n const { colors, accentColor, fonts } = theme;\n const listRef = useRef<FlatList<ChatMessage> | null>(null);\n const threadQuery = useThread(threadId);\n const sendMutation = useSendMessage(threadId);\n\n if (!enabled) return <FeatureOff />;\n\n const messages = threadQuery.data?.messages ?? [];\n const loading = threadQuery.isLoading && messages.length === 0;\n\n async function handleSend(body: string, image?: PickedImage | null) {\n if ((!body.trim() && !image) || sendMutation.isPending) return;\n await sendMutation.mutateAsync({ body, image });\n setTimeout(() => listRef.current?.scrollToEnd({ animated: true }), 100);\n }\n\n return (\n <KeyboardAvoidingView\n style={{ flex: 1, backgroundColor: colors.background }}\n behavior={Platform.OS === \"ios\" ? \"padding\" : undefined}\n keyboardVerticalOffset={0}\n >\n <View\n style={{\n paddingTop: 56,\n paddingHorizontal: 16,\n paddingBottom: 12,\n flexDirection: isRtl ? \"row-reverse\" : \"row\",\n alignItems: \"center\",\n gap: 12,\n borderBottomWidth: 1,\n borderBottomColor: colors.border,\n }}\n >\n <TouchableOpacity onPress={navigation.goBack} hitSlop={12}>\n <Text style={{ fontSize: 22, color: colors.text }}>\n {isRtl ? \"→\" : \"←\"}\n </Text>\n </TouchableOpacity>\n <Text\n style={{\n color: colors.text,\n fontSize: 18,\n fontFamily: fonts.displayBold,\n fontWeight: \"700\",\n flex: 1,\n }}\n >\n {t(MessengerI18n.chat.key, MessengerI18n.chat.fallback)}\n </Text>\n </View>\n\n {loading ? (\n <ActivityIndicator color={accentColor} style={{ marginTop: 40 }} />\n ) : (\n <FlatList\n ref={listRef}\n data={messages}\n keyExtractor={(m: ChatMessage) => String(m.id)}\n contentContainerStyle={{ padding: 16, paddingBottom: 8 }}\n onContentSizeChange={() =>\n listRef.current?.scrollToEnd({ animated: false })\n }\n ListEmptyComponent={\n <Text\n style={{\n color: colors.textMuted,\n textAlign: \"center\",\n marginTop: 40,\n fontFamily: fonts.body,\n }}\n >\n {t(\n MessengerI18n.startConversation.key,\n MessengerI18n.startConversation.fallback\n )}\n </Text>\n }\n renderItem={({ item }: { item: ChatMessage }) => (\n <MessageBubble message={item} />\n )}\n />\n )}\n\n <Composer sending={sendMutation.isPending} onSend={handleSend} />\n </KeyboardAvoidingView>\n );\n}\n"]}