@ttt-productions/chat-react 0.12.15 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/hooks/useChatMessages.d.ts.map +1 -1
- package/dist/hooks/useChatMessages.js +0 -1
- package/dist/hooks/useChatMessages.js.map +1 -1
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/realtime/channel-client.d.ts +6 -13
- package/dist/realtime/channel-client.d.ts.map +1 -1
- package/dist/realtime/channel-client.js +7 -56
- package/dist/realtime/channel-client.js.map +1 -1
- package/dist/realtime/diagnostics.d.ts +0 -2
- package/dist/realtime/diagnostics.d.ts.map +1 -1
- package/dist/realtime/diagnostics.js +7 -5
- package/dist/realtime/diagnostics.js.map +1 -1
- package/dist/realtime/map.d.ts +4 -7
- package/dist/realtime/map.d.ts.map +1 -1
- package/dist/realtime/map.js +4 -41
- package/dist/realtime/map.js.map +1 -1
- package/dist/realtime/wire.d.ts +5 -5
- package/dist/realtime/wire.d.ts.map +1 -1
- package/dist/realtime/wire.js.map +1 -1
- package/dist/types.d.ts +0 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/ChatShell.d.ts +2 -4
- package/dist/ui/ChatShell.d.ts.map +1 -1
- package/dist/ui/ChatShell.js +9 -14
- package/dist/ui/ChatShell.js.map +1 -1
- package/dist/ui/Composer.d.ts +5 -28
- package/dist/ui/Composer.d.ts.map +1 -1
- package/dist/ui/Composer.js +8 -104
- package/dist/ui/Composer.js.map +1 -1
- package/dist/ui/MessageItemDefault.d.ts +0 -5
- package/dist/ui/MessageItemDefault.d.ts.map +1 -1
- package/dist/ui/MessageItemDefault.js +6 -75
- package/dist/ui/MessageItemDefault.js.map +1 -1
- package/dist/ui/MessageList.d.ts +0 -3
- package/dist/ui/MessageList.d.ts.map +1 -1
- package/dist/ui/MessageList.js +2 -2
- package/dist/ui/MessageList.js.map +1 -1
- package/package.json +3 -6
- package/src/styles/chat.css +0 -139
- package/dist/context/ChatAttachmentMediaContext.d.ts +0 -37
- package/dist/context/ChatAttachmentMediaContext.d.ts.map +0 -1
- package/dist/context/ChatAttachmentMediaContext.js +0 -17
- package/dist/context/ChatAttachmentMediaContext.js.map +0 -1
- package/dist/context/ChatAttachmentUrlContext.d.ts +0 -25
- package/dist/context/ChatAttachmentUrlContext.d.ts.map +0 -1
- package/dist/context/ChatAttachmentUrlContext.js +0 -21
- package/dist/context/ChatAttachmentUrlContext.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttt-productions/chat-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Chat React UI, hooks, and Firebase-client adapter for TTT Productions apps (realtime newest window + infinite older pagination)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -60,14 +60,11 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@ttt-productions/chat-core": "^0.
|
|
64
|
-
"@ttt-productions/chat-schemas": "^0.
|
|
63
|
+
"@ttt-productions/chat-core": "^0.11.0",
|
|
64
|
+
"@ttt-productions/chat-schemas": "^0.10.0",
|
|
65
65
|
"@ttt-productions/realtime-core": "^0.1.3",
|
|
66
|
-
"@ttt-productions/media-schemas": "^0.14.3",
|
|
67
66
|
"@ttt-productions/ui-core": "^0.11.10",
|
|
68
|
-
"@ttt-productions/file-input": "^0.11.6",
|
|
69
67
|
"@ttt-productions/upload-ui": "^0.7.5",
|
|
70
|
-
"@ttt-productions/media-viewer": "^0.10.6",
|
|
71
68
|
"@ttt-productions/mobile-core": "^0.9.1",
|
|
72
69
|
"@ttt-productions/firebase-helpers": "^0.12.3"
|
|
73
70
|
},
|
package/src/styles/chat.css
CHANGED
|
@@ -96,121 +96,6 @@
|
|
|
96
96
|
max-width: 280px;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/* --- Attachment states --- */
|
|
100
|
-
|
|
101
|
-
/* Pending / URL-settling placeholder. Parchment-safe: a lightly tinted surface
|
|
102
|
-
with a subtle tokenized border (NOT the old opaque muted slab, which read as a
|
|
103
|
-
dark rectangle on the parchment chat canvas). It is a small inline status row —
|
|
104
|
-
deliberately NOT a media-sized box, so it never implies the file is viewable.
|
|
105
|
-
All colors are theme tokens; a restrained shimmer conveys "in progress". */
|
|
106
|
-
.chat-attachment-pending {
|
|
107
|
-
position: relative;
|
|
108
|
-
overflow: hidden;
|
|
109
|
-
display: flex;
|
|
110
|
-
align-items: center;
|
|
111
|
-
gap: 0.5rem;
|
|
112
|
-
padding: 0.5rem 0.75rem;
|
|
113
|
-
border-radius: 0.375rem;
|
|
114
|
-
background-color: hsl(var(--muted) / 0.2);
|
|
115
|
-
border: 1px solid hsl(var(--border) / 0.6);
|
|
116
|
-
color: hsl(var(--muted-foreground));
|
|
117
|
-
font-size: 0.75rem;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/* Restrained left-to-right shimmer over the tinted surface. Tokenized, low-opacity,
|
|
121
|
-
and disabled under prefers-reduced-motion. The spinner remains the primary cue. */
|
|
122
|
-
.chat-attachment-pending::after {
|
|
123
|
-
content: "";
|
|
124
|
-
position: absolute;
|
|
125
|
-
inset: 0;
|
|
126
|
-
background: linear-gradient(
|
|
127
|
-
90deg,
|
|
128
|
-
transparent 0%,
|
|
129
|
-
hsl(var(--muted-foreground) / 0.06) 50%,
|
|
130
|
-
transparent 100%
|
|
131
|
-
);
|
|
132
|
-
transform: translateX(-100%);
|
|
133
|
-
animation: chat-attachment-shimmer 1.8s ease-in-out infinite;
|
|
134
|
-
pointer-events: none;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
@keyframes chat-attachment-shimmer {
|
|
138
|
-
100% {
|
|
139
|
-
transform: translateX(100%);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
@media (prefers-reduced-motion: reduce) {
|
|
144
|
-
.chat-attachment-pending::after {
|
|
145
|
-
animation: none;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.chat-attachment-media {
|
|
150
|
-
max-width: 320px;
|
|
151
|
-
border-radius: 0.375rem;
|
|
152
|
-
overflow: hidden;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.chat-attachment-text-link {
|
|
156
|
-
display: inline-flex;
|
|
157
|
-
align-items: center;
|
|
158
|
-
gap: 0.375rem;
|
|
159
|
-
padding: 0.375rem 0.625rem;
|
|
160
|
-
border-radius: 0.375rem;
|
|
161
|
-
background-color: hsl(var(--muted));
|
|
162
|
-
color: hsl(var(--primary));
|
|
163
|
-
font-size: 0.8125rem;
|
|
164
|
-
text-decoration: none;
|
|
165
|
-
transition: opacity 0.15s;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
.chat-attachment-text-link:hover {
|
|
169
|
-
opacity: 0.8;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/* Terminal-failure placeholder. A restrained, tokenized surface — a subtle border
|
|
173
|
-
and faint muted tint, NOT a destructive-red block (the failure is localized to
|
|
174
|
-
this attachment, so it must not make the whole bubble read as an error). */
|
|
175
|
-
.chat-attachment-rejected {
|
|
176
|
-
display: flex;
|
|
177
|
-
align-items: flex-start;
|
|
178
|
-
gap: 0.5rem;
|
|
179
|
-
padding: 0.5rem 0.75rem;
|
|
180
|
-
border-radius: 0.375rem;
|
|
181
|
-
background-color: hsl(var(--muted) / 0.35);
|
|
182
|
-
border: 1px solid hsl(var(--border));
|
|
183
|
-
color: hsl(var(--muted-foreground));
|
|
184
|
-
font-size: 0.75rem;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.chat-attachment-rejected-icon {
|
|
188
|
-
margin-top: 0.05rem;
|
|
189
|
-
color: hsl(var(--muted-foreground));
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.chat-attachment-rejected-body {
|
|
193
|
-
display: flex;
|
|
194
|
-
flex-direction: column;
|
|
195
|
-
gap: 0.05rem;
|
|
196
|
-
min-width: 0;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.chat-attachment-rejected-reason {
|
|
200
|
-
opacity: 0.85;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.chat-attachment-retry {
|
|
204
|
-
margin-left: auto;
|
|
205
|
-
flex-shrink: 0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.chat-attachment-status-label {
|
|
209
|
-
margin-left: auto;
|
|
210
|
-
opacity: 0.7;
|
|
211
|
-
font-style: italic;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
99
|
/* --- Composer --- */
|
|
215
100
|
.chat-composer {
|
|
216
101
|
display: flex;
|
|
@@ -219,30 +104,6 @@
|
|
|
219
104
|
width: 100%;
|
|
220
105
|
}
|
|
221
106
|
|
|
222
|
-
.chat-composer-file-preview {
|
|
223
|
-
display: flex;
|
|
224
|
-
align-items: center;
|
|
225
|
-
gap: 0.5rem;
|
|
226
|
-
padding: 0.375rem 0.5rem;
|
|
227
|
-
border-radius: 0.375rem;
|
|
228
|
-
background-color: hsl(var(--muted));
|
|
229
|
-
font-size: 0.8125rem;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
.chat-composer-file-name {
|
|
233
|
-
flex: 1;
|
|
234
|
-
min-width: 0;
|
|
235
|
-
overflow: hidden;
|
|
236
|
-
text-overflow: ellipsis;
|
|
237
|
-
white-space: nowrap;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
.chat-composer-upload-status {
|
|
241
|
-
display: flex;
|
|
242
|
-
align-items: center;
|
|
243
|
-
gap: 0.375rem;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
107
|
/* Mention system — default chip styling. Consumers override via custom
|
|
247
108
|
renderMention or by targeting .chat-mention-chip directly. */
|
|
248
109
|
.chat-mention-chip {
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import type { MediaPreviewProps, MediaViewerType } from "@ttt-productions/media-viewer";
|
|
3
|
-
import type { ChatAttachment } from "@ttt-productions/chat-core";
|
|
4
|
-
/**
|
|
5
|
-
* The media kinds chat actually renders through the injected component. Chat only ever
|
|
6
|
-
* mounts it for image/video/audio attachments; text/markdown render as the package's own
|
|
7
|
-
* download link and never reach this slot. Computed as the intersection of chat-core's
|
|
8
|
-
* `ChatAttachment['type']` and media-viewer's `MediaViewerType`, so it stays in the chat +
|
|
9
|
-
* media-viewer domains with no ttt-core dependency (ARCH-201) and tracks either union
|
|
10
|
-
* automatically if a kind is added or removed.
|
|
11
|
-
*/
|
|
12
|
-
export type ChatAttachmentMediaKind = Extract<ChatAttachment["type"], MediaViewerType>;
|
|
13
|
-
/**
|
|
14
|
-
* The component chat attachments render their media through. Defaults to the bare
|
|
15
|
-
* media-viewer `MediaViewer` when no provider is present; the consuming app injects its own
|
|
16
|
-
* wrapper (recovery adapter, diagnostics, telemetry — whatever the app's one display path
|
|
17
|
-
* adds) so chat media rides the SAME display pipeline as every other surface. chat-react
|
|
18
|
-
* stays app-agnostic: it renders whatever component it is handed with plain MediaPreview
|
|
19
|
-
* props — except `type`, which is REQUIRED and narrowed to the kind chat provides, so the
|
|
20
|
-
* consuming wrapper never has to narrow an all-optional classification (no dead
|
|
21
|
-
* mime/name/'other' branch).
|
|
22
|
-
*/
|
|
23
|
-
export type ChatAttachmentMediaComponent = React.ComponentType<Omit<MediaPreviewProps, "type"> & {
|
|
24
|
-
type: ChatAttachmentMediaKind;
|
|
25
|
-
}>;
|
|
26
|
-
export type ChatAttachmentMediaProviderProps = {
|
|
27
|
-
mediaComponent: ChatAttachmentMediaComponent;
|
|
28
|
-
children: React.ReactNode;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Optional (unlike ChatAttachmentUrlProvider, which is required): without it,
|
|
32
|
-
* attachments render through the package's own MediaViewer exactly as before.
|
|
33
|
-
*/
|
|
34
|
-
export declare function ChatAttachmentMediaProvider(props: ChatAttachmentMediaProviderProps): React.JSX.Element;
|
|
35
|
-
/** Nullable hook — consumers fall back to the package MediaViewer. */
|
|
36
|
-
export declare function useChatAttachmentMediaComponent(): ChatAttachmentMediaComponent | null;
|
|
37
|
-
//# sourceMappingURL=ChatAttachmentMediaContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAttachmentMediaContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatAttachmentMediaContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC;AAEvF;;;;;;;;;GASG;AACH,MAAM,MAAM,4BAA4B,GAAG,KAAK,CAAC,aAAa,CAC5D,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,CACpE,CAAC;AAIF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,cAAc,EAAE,4BAA4B,CAAC;IAC7C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,gCAAgC,qBAOlF;AAED,sEAAsE;AACtE,wBAAgB,+BAA+B,IAAI,4BAA4B,GAAG,IAAI,CAErF"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
const ChatAttachmentMediaContext = React.createContext(null);
|
|
5
|
-
/**
|
|
6
|
-
* Optional (unlike ChatAttachmentUrlProvider, which is required): without it,
|
|
7
|
-
* attachments render through the package's own MediaViewer exactly as before.
|
|
8
|
-
*/
|
|
9
|
-
export function ChatAttachmentMediaProvider(props) {
|
|
10
|
-
const { mediaComponent, children } = props;
|
|
11
|
-
return (_jsx(ChatAttachmentMediaContext.Provider, { value: mediaComponent, children: children }));
|
|
12
|
-
}
|
|
13
|
-
/** Nullable hook — consumers fall back to the package MediaViewer. */
|
|
14
|
-
export function useChatAttachmentMediaComponent() {
|
|
15
|
-
return React.useContext(ChatAttachmentMediaContext);
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=ChatAttachmentMediaContext.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAttachmentMediaContext.js","sourceRoot":"","sources":["../../src/context/ChatAttachmentMediaContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA4B/B,MAAM,0BAA0B,GAAG,KAAK,CAAC,aAAa,CAAsC,IAAI,CAAC,CAAC;AAOlG;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAuC;IACjF,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3C,OAAO,CACL,KAAC,0BAA0B,CAAC,QAAQ,IAAC,KAAK,EAAE,cAAc,YACvD,QAAQ,GAC2B,CACvC,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,+BAA+B;IAC7C,OAAO,KAAK,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;AACtD,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport type { MediaPreviewProps, MediaViewerType } from \"@ttt-productions/media-viewer\";\nimport type { ChatAttachment } from \"@ttt-productions/chat-core\";\n\n/**\n * The media kinds chat actually renders through the injected component. Chat only ever\n * mounts it for image/video/audio attachments; text/markdown render as the package's own\n * download link and never reach this slot. Computed as the intersection of chat-core's\n * `ChatAttachment['type']` and media-viewer's `MediaViewerType`, so it stays in the chat +\n * media-viewer domains with no ttt-core dependency (ARCH-201) and tracks either union\n * automatically if a kind is added or removed.\n */\nexport type ChatAttachmentMediaKind = Extract<ChatAttachment[\"type\"], MediaViewerType>;\n\n/**\n * The component chat attachments render their media through. Defaults to the bare\n * media-viewer `MediaViewer` when no provider is present; the consuming app injects its own\n * wrapper (recovery adapter, diagnostics, telemetry — whatever the app's one display path\n * adds) so chat media rides the SAME display pipeline as every other surface. chat-react\n * stays app-agnostic: it renders whatever component it is handed with plain MediaPreview\n * props — except `type`, which is REQUIRED and narrowed to the kind chat provides, so the\n * consuming wrapper never has to narrow an all-optional classification (no dead\n * mime/name/'other' branch).\n */\nexport type ChatAttachmentMediaComponent = React.ComponentType<\n Omit<MediaPreviewProps, \"type\"> & { type: ChatAttachmentMediaKind }\n>;\n\nconst ChatAttachmentMediaContext = React.createContext<ChatAttachmentMediaComponent | null>(null);\n\nexport type ChatAttachmentMediaProviderProps = {\n mediaComponent: ChatAttachmentMediaComponent;\n children: React.ReactNode;\n};\n\n/**\n * Optional (unlike ChatAttachmentUrlProvider, which is required): without it,\n * attachments render through the package's own MediaViewer exactly as before.\n */\nexport function ChatAttachmentMediaProvider(props: ChatAttachmentMediaProviderProps) {\n const { mediaComponent, children } = props;\n return (\n <ChatAttachmentMediaContext.Provider value={mediaComponent}>\n {children}\n </ChatAttachmentMediaContext.Provider>\n );\n}\n\n/** Nullable hook — consumers fall back to the package MediaViewer. */\nexport function useChatAttachmentMediaComponent(): ChatAttachmentMediaComponent | null {\n return React.useContext(ChatAttachmentMediaContext);\n}\n"]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import type { ChatAttachment } from "@ttt-productions/chat-core";
|
|
3
|
-
/**
|
|
4
|
-
* Resolves a READY chat attachment to a display URL at render time. The
|
|
5
|
-
* attachment doc stores only `mediaAssetId` (never a URL); the consuming app
|
|
6
|
-
* injects a resolver that builds the protected-gateway URL (or an emulator
|
|
7
|
-
* URL) from `attachment.mediaAssetId` + its variant scheme. chat-react stays
|
|
8
|
-
* app-agnostic — it never knows about gateways, hosts, or Firebase.
|
|
9
|
-
*
|
|
10
|
-
* Return null when no URL can be built yet (e.g. missing assetId) — the
|
|
11
|
-
* renderer shows nothing for that attachment body.
|
|
12
|
-
*/
|
|
13
|
-
export type ChatAttachmentUrlResolver = (attachment: ChatAttachment) => string | null;
|
|
14
|
-
export type ChatAttachmentUrlProviderProps = {
|
|
15
|
-
resolveAttachmentUrl: ChatAttachmentUrlResolver;
|
|
16
|
-
children: React.ReactNode;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Wraps any chat tree that renders attachments. Required alongside
|
|
20
|
-
* <ChatNameResolverProvider> for trees rendering <ChatShell>/<MessageList>.
|
|
21
|
-
*/
|
|
22
|
-
export declare function ChatAttachmentUrlProvider(props: ChatAttachmentUrlProviderProps): React.JSX.Element;
|
|
23
|
-
/** Strict hook — throws if no provider is wrapped (missing setup must surface). */
|
|
24
|
-
export declare function useChatAttachmentUrlResolver(): ChatAttachmentUrlResolver;
|
|
25
|
-
//# sourceMappingURL=ChatAttachmentUrlContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAttachmentUrlContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatAttachmentUrlContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,UAAU,EAAE,cAAc,KAAK,MAAM,GAAG,IAAI,CAAC;AAItF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,8BAA8B,qBAO9E;AAED,mFAAmF;AACnF,wBAAgB,4BAA4B,IAAI,yBAAyB,CAQxE"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
const ChatAttachmentUrlContext = React.createContext(null);
|
|
5
|
-
/**
|
|
6
|
-
* Wraps any chat tree that renders attachments. Required alongside
|
|
7
|
-
* <ChatNameResolverProvider> for trees rendering <ChatShell>/<MessageList>.
|
|
8
|
-
*/
|
|
9
|
-
export function ChatAttachmentUrlProvider(props) {
|
|
10
|
-
const { resolveAttachmentUrl, children } = props;
|
|
11
|
-
return (_jsx(ChatAttachmentUrlContext.Provider, { value: resolveAttachmentUrl, children: children }));
|
|
12
|
-
}
|
|
13
|
-
/** Strict hook — throws if no provider is wrapped (missing setup must surface). */
|
|
14
|
-
export function useChatAttachmentUrlResolver() {
|
|
15
|
-
const resolver = React.useContext(ChatAttachmentUrlContext);
|
|
16
|
-
if (!resolver) {
|
|
17
|
-
throw new Error("[chat-react] ChatAttachmentUrlProvider is required. Wrap your ChatShell tree with <ChatAttachmentUrlProvider>.");
|
|
18
|
-
}
|
|
19
|
-
return resolver;
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=ChatAttachmentUrlContext.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAttachmentUrlContext.js","sourceRoot":"","sources":["../../src/context/ChatAttachmentUrlContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,MAAM,wBAAwB,GAAG,KAAK,CAAC,aAAa,CAAmC,IAAI,CAAC,CAAC;AAO7F;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAqC;IAC7E,MAAM,EAAE,oBAAoB,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACjD,OAAO,CACL,KAAC,wBAAwB,CAAC,QAAQ,IAAC,KAAK,EAAE,oBAAoB,YAC3D,QAAQ,GACyB,CACrC,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,4BAA4B;IAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport type { ChatAttachment } from \"@ttt-productions/chat-core\";\n\n/**\n * Resolves a READY chat attachment to a display URL at render time. The\n * attachment doc stores only `mediaAssetId` (never a URL); the consuming app\n * injects a resolver that builds the protected-gateway URL (or an emulator\n * URL) from `attachment.mediaAssetId` + its variant scheme. chat-react stays\n * app-agnostic — it never knows about gateways, hosts, or Firebase.\n *\n * Return null when no URL can be built yet (e.g. missing assetId) — the\n * renderer shows nothing for that attachment body.\n */\nexport type ChatAttachmentUrlResolver = (attachment: ChatAttachment) => string | null;\n\nconst ChatAttachmentUrlContext = React.createContext<ChatAttachmentUrlResolver | null>(null);\n\nexport type ChatAttachmentUrlProviderProps = {\n resolveAttachmentUrl: ChatAttachmentUrlResolver;\n children: React.ReactNode;\n};\n\n/**\n * Wraps any chat tree that renders attachments. Required alongside\n * <ChatNameResolverProvider> for trees rendering <ChatShell>/<MessageList>.\n */\nexport function ChatAttachmentUrlProvider(props: ChatAttachmentUrlProviderProps) {\n const { resolveAttachmentUrl, children } = props;\n return (\n <ChatAttachmentUrlContext.Provider value={resolveAttachmentUrl}>\n {children}\n </ChatAttachmentUrlContext.Provider>\n );\n}\n\n/** Strict hook — throws if no provider is wrapped (missing setup must surface). */\nexport function useChatAttachmentUrlResolver(): ChatAttachmentUrlResolver {\n const resolver = React.useContext(ChatAttachmentUrlContext);\n if (!resolver) {\n throw new Error(\n \"[chat-react] ChatAttachmentUrlProvider is required. Wrap your ChatShell tree with <ChatAttachmentUrlProvider>.\"\n );\n }\n return resolver;\n}\n"]}
|