@samirify/messenger 0.1.1 → 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,138 +1,8 @@
1
+ import { useMessengerConfig, useThreads, useOpenThread, MessengerI18n, useThread, useSendMessage } from '../chunk-O5XNJHGZ.js';
1
2
  import { View, TouchableOpacity, Text, ScrollView, ActivityIndicator, RefreshControl, Image, TextInput, Platform, KeyboardAvoidingView, FlatList } from 'react-native';
2
- import { createContext, useState, useRef, useContext } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
4
+ import { useState, useRef } from 'react';
5
5
 
6
- // src/native/InboxScreen.tsx
7
- var MessengerContext = createContext(null);
8
- function useMessengerConfig() {
9
- const ctx = useContext(MessengerContext);
10
- if (!ctx) {
11
- throw new Error(
12
- "@gymlium/messenger: useMessengerConfig must be used within MessengerProvider"
13
- );
14
- }
15
- return ctx;
16
- }
17
-
18
- // src/api.ts
19
- async function listThreads(http) {
20
- const res = await http.getJson(
21
- "/api/messages/threads"
22
- );
23
- return { ...res, data: res.data?.threads ?? [] };
24
- }
25
- async function openThread(http, clientUserId) {
26
- return http.postJson("/api/messages/threads", {
27
- ...clientUserId ? { client_user_id: clientUserId } : {}
28
- });
29
- }
30
- async function getThread(http, threadId, limit = 50, beforeId) {
31
- const params = new URLSearchParams({ limit: String(limit) });
32
- return http.getJson(`/api/messages/threads/${threadId}?${params.toString()}`);
33
- }
34
- async function sendMessage(http, threadId, body, image) {
35
- const path = `/api/messages/threads/${threadId}/messages`;
36
- if (image?.uri || image?.file) {
37
- const form = new FormData();
38
- if (body.trim()) form.append("body", body.trim());
39
- const filename = image.name ?? image.uri?.split("/").pop() ?? "photo.jpg";
40
- const match = /\.(\w+)$/.exec(filename);
41
- const type = image.type ?? (match ? `image/${match[1]}` : "image/jpeg");
42
- if (image.file) {
43
- form.append("image", image.file, filename);
44
- } else if (image.uri.startsWith("blob:") || image.uri.startsWith("data:")) {
45
- const blob = await fetch(image.uri).then((r) => r.blob());
46
- form.append("image", blob, filename);
47
- } else {
48
- form.append("image", {
49
- uri: image.uri,
50
- name: filename,
51
- type
52
- });
53
- }
54
- return http.postForm(path, form);
55
- }
56
- return http.postJson(path, { body });
57
- }
58
-
59
- // src/queryKeys.ts
60
- var messengerKeys = {
61
- all: ["messenger"],
62
- threads: () => [...messengerKeys.all, "threads"],
63
- thread: (id) => [...messengerKeys.all, "thread", id]
64
- };
65
-
66
- // src/hooks/useThreads.ts
67
- function useThreads(options) {
68
- const { http, enabled: featureOn } = useMessengerConfig();
69
- const enabled = featureOn;
70
- return useQuery({
71
- queryKey: messengerKeys.threads(),
72
- queryFn: async () => {
73
- const res = await listThreads(http);
74
- if (!res.success) {
75
- throw new Error(res.message ?? "Failed to load threads");
76
- }
77
- return res.data;
78
- },
79
- enabled
80
- });
81
- }
82
- function useOpenThread() {
83
- const { http, navigation } = useMessengerConfig();
84
- const qc = useQueryClient();
85
- return useMutation({
86
- mutationFn: async (clientUserId) => {
87
- const res = await openThread(http, clientUserId);
88
- if (!res.success || !res.data?.thread?.id) {
89
- throw new Error(res.message ?? "Could not open thread");
90
- }
91
- return res.data.thread;
92
- },
93
- onSuccess: (thread) => {
94
- void qc.invalidateQueries({ queryKey: messengerKeys.threads() });
95
- navigation.openThread(thread.id);
96
- }
97
- });
98
- }
99
-
100
- // src/i18nKeys.ts
101
- var MessengerI18n = {
102
- off: {
103
- key: "mobile.messenger.off",
104
- fallback: "Messaging is not enabled for this account."
105
- },
106
- inbox: { key: "mobile.messenger.inbox", fallback: "Chat" },
107
- chat: { key: "mobile.messenger.chat", fallback: "Chat" },
108
- messageCoach: {
109
- key: "mobile.messenger.messageCoach",
110
- fallback: "Message your coach"
111
- },
112
- empty: {
113
- key: "mobile.messenger.empty",
114
- fallback: "No conversations yet"
115
- },
116
- yourCoach: {
117
- key: "mobile.messenger.yourCoach",
118
- fallback: "Your coach"
119
- },
120
- photo: { key: "mobile.messenger.photo", fallback: "Photo" },
121
- noMessages: {
122
- key: "mobile.messenger.noMessages",
123
- fallback: "No messages yet"
124
- },
125
- startConversation: {
126
- key: "mobile.messenger.startConversation",
127
- fallback: "Say hello \u2014 send the first message."
128
- },
129
- typeMessage: {
130
- key: "mobile.messenger.typeMessage",
131
- fallback: "Type a message\u2026"
132
- },
133
- client: { key: "mobile.trainer.client", fallback: "Client" },
134
- back: { key: "common.back", fallback: "Back" }
135
- };
136
6
  function FeatureOff() {
137
7
  const { t, theme, navigation, onFeatureOff } = useMessengerConfig();
138
8
  if (onFeatureOff) return /* @__PURE__ */ jsx(Fragment, { children: onFeatureOff() });
@@ -254,7 +124,7 @@ function InboxScreen() {
254
124
  const { enabled, user, t, isRtl, theme, navigation } = useMessengerConfig();
255
125
  const { colors, accentColor, fonts } = theme;
256
126
  const threadsQuery = useThreads();
257
- const openThread2 = useOpenThread();
127
+ const openThread = useOpenThread();
258
128
  if (!enabled) return /* @__PURE__ */ jsx(FeatureOff, {});
259
129
  const threads = threadsQuery.data ?? [];
260
130
  const loading = threadsQuery.isLoading && threads.length === 0;
@@ -304,8 +174,8 @@ function InboxScreen() {
304
174
  user?.role === "client" && threads.length === 0 && /* @__PURE__ */ jsx(
305
175
  TouchableOpacity,
306
176
  {
307
- onPress: () => openThread2.mutate(void 0),
308
- disabled: openThread2.isPending,
177
+ onPress: () => openThread.mutate(void 0),
178
+ disabled: openThread.isPending,
309
179
  style: {
310
180
  marginBottom: 14,
311
181
  paddingVertical: 14,
@@ -313,7 +183,7 @@ function InboxScreen() {
313
183
  backgroundColor: accentColor,
314
184
  alignItems: "center"
315
185
  },
316
- children: openThread2.isPending ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#FFF" }) : /* @__PURE__ */ jsx(
186
+ children: openThread.isPending ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#FFF" }) : /* @__PURE__ */ jsx(
317
187
  Text,
318
188
  {
319
189
  style: {
@@ -362,48 +232,6 @@ function InboxScreen() {
362
232
  )
363
233
  ] });
364
234
  }
365
- var POLL_MS = 18e3;
366
- function useThread(threadId, options) {
367
- const { http, enabled: featureOn } = useMessengerConfig();
368
- const enabled = featureOn && Number.isFinite(threadId) && threadId > 0;
369
- const poll = true;
370
- return useQuery({
371
- queryKey: messengerKeys.thread(threadId),
372
- queryFn: async () => {
373
- const res = await getThread(http, threadId);
374
- if (!res.success) {
375
- throw new Error(res.message ?? "Failed to load thread");
376
- }
377
- return res.data;
378
- },
379
- enabled,
380
- refetchInterval: enabled && poll ? POLL_MS : false
381
- });
382
- }
383
- function useSendMessage(threadId) {
384
- const { http } = useMessengerConfig();
385
- const qc = useQueryClient();
386
- return useMutation({
387
- mutationFn: async (input) => {
388
- const res = await sendMessage(http, threadId, input.body, input.image);
389
- if (!res.success || !res.data?.message) {
390
- throw new Error(res.message ?? "Send failed");
391
- }
392
- return res.data.message;
393
- },
394
- onSuccess: (message) => {
395
- qc.setQueryData(
396
- messengerKeys.thread(threadId),
397
- (prev) => {
398
- if (!prev) return prev;
399
- if (prev.messages.some((m) => m.id === message.id)) return prev;
400
- return { ...prev, messages: [...prev.messages, message] };
401
- }
402
- );
403
- void qc.invalidateQueries({ queryKey: messengerKeys.threads() });
404
- }
405
- });
406
- }
407
235
  function MessageBubble({ message }) {
408
236
  const { user, isRtl, theme } = useMessengerConfig();
409
237
  const { colors, accentColor, fonts } = theme;
@@ -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":["jsx","openThread","useQuery","useQueryClient","useMutation","jsxs","View","Text","TouchableOpacity","ActivityIndicator","FeatureOff","Fragment","Platform"],"mappings":"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","file":"index.js","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":["jsxs","View","jsx","Text","TouchableOpacity","ActivityIndicator","FeatureOff","Fragment","Platform"],"mappings":"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","file":"index.js","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"]}
@@ -0,0 +1,26 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { b as MessengerConfig } from './types-B7dU_l7c.cjs';
3
+
4
+ declare function MessengerProvider({ config, children, }: {
5
+ config: MessengerConfig;
6
+ children: ReactNode;
7
+ }): React.JSX.Element;
8
+ declare function useMessengerConfig(): MessengerConfig;
9
+ /** Safe variant for optional host chrome (returns null outside provider). */
10
+ declare function useOptionalMessengerConfig(): MessengerConfig | null;
11
+
12
+ interface MessengerUiState {
13
+ open: boolean;
14
+ threadId: number | null;
15
+ openInbox: () => void;
16
+ openThread: (threadId: number) => void;
17
+ close: () => void;
18
+ setOpen: (open: boolean) => void;
19
+ }
20
+ declare function MessengerUiProvider({ children }: {
21
+ children: ReactNode;
22
+ }): React.JSX.Element;
23
+ declare function useMessengerUi(): MessengerUiState;
24
+ declare function useOptionalMessengerUi(): MessengerUiState | null;
25
+
26
+ export { MessengerProvider as M, MessengerUiProvider as a, useMessengerUi as b, useOptionalMessengerConfig as c, useOptionalMessengerUi as d, useMessengerConfig as u };
@@ -0,0 +1,26 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { b as MessengerConfig } from './types-B7dU_l7c.js';
3
+
4
+ declare function MessengerProvider({ config, children, }: {
5
+ config: MessengerConfig;
6
+ children: ReactNode;
7
+ }): React.JSX.Element;
8
+ declare function useMessengerConfig(): MessengerConfig;
9
+ /** Safe variant for optional host chrome (returns null outside provider). */
10
+ declare function useOptionalMessengerConfig(): MessengerConfig | null;
11
+
12
+ interface MessengerUiState {
13
+ open: boolean;
14
+ threadId: number | null;
15
+ openInbox: () => void;
16
+ openThread: (threadId: number) => void;
17
+ close: () => void;
18
+ setOpen: (open: boolean) => void;
19
+ }
20
+ declare function MessengerUiProvider({ children }: {
21
+ children: ReactNode;
22
+ }): React.JSX.Element;
23
+ declare function useMessengerUi(): MessengerUiState;
24
+ declare function useOptionalMessengerUi(): MessengerUiState | null;
25
+
26
+ export { MessengerProvider as M, MessengerUiProvider as a, useMessengerUi as b, useOptionalMessengerConfig as c, useOptionalMessengerUi as d, useMessengerConfig as u };