@melony/react 0.1.25 → 0.1.27
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 +4 -2
- package/dist/index.cjs +460 -401
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -46
- package/dist/index.d.ts +47 -46
- package/dist/index.js +456 -399
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4,15 +4,15 @@ var React11 = require('react');
|
|
|
4
4
|
var react = require('nuqs/adapters/react');
|
|
5
5
|
var reactQuery = require('@tanstack/react-query');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
-
var client = require('melony/client');
|
|
8
|
-
var nuqs = require('nuqs');
|
|
9
|
-
var clsx = require('clsx');
|
|
10
|
-
var tailwindMerge = require('tailwind-merge');
|
|
11
7
|
var button = require('@base-ui/react/button');
|
|
12
8
|
var classVarianceAuthority = require('class-variance-authority');
|
|
9
|
+
var clsx = require('clsx');
|
|
10
|
+
var tailwindMerge = require('tailwind-merge');
|
|
11
|
+
var ICONS = require('@tabler/icons-react');
|
|
12
|
+
var client = require('melony/client');
|
|
13
|
+
var nuqs = require('nuqs');
|
|
13
14
|
var mergeProps = require('@base-ui/react/merge-props');
|
|
14
15
|
var useRender = require('@base-ui/react/use-render');
|
|
15
|
-
var ICONS = require('@tabler/icons-react');
|
|
16
16
|
var menu = require('@base-ui/react/menu');
|
|
17
17
|
var separator = require('@base-ui/react/separator');
|
|
18
18
|
var dialog = require('@base-ui/react/dialog');
|
|
@@ -188,49 +188,215 @@ var MelonyClientProvider = ({
|
|
|
188
188
|
}
|
|
189
189
|
) }) });
|
|
190
190
|
};
|
|
191
|
+
function cn(...inputs) {
|
|
192
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
193
|
+
}
|
|
194
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
195
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
|
|
196
|
+
{
|
|
197
|
+
variants: {
|
|
198
|
+
variant: {
|
|
199
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
200
|
+
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
201
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
202
|
+
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
203
|
+
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
204
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
205
|
+
},
|
|
206
|
+
size: {
|
|
207
|
+
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
208
|
+
xs: "h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
|
|
209
|
+
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
210
|
+
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
211
|
+
icon: "size-9",
|
|
212
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
213
|
+
"icon-sm": "size-8",
|
|
214
|
+
"icon-lg": "size-10"
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
defaultVariants: {
|
|
218
|
+
variant: "default",
|
|
219
|
+
size: "default"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
function Button({
|
|
224
|
+
className,
|
|
225
|
+
variant = "default",
|
|
226
|
+
size = "default",
|
|
227
|
+
...props
|
|
228
|
+
}) {
|
|
229
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
230
|
+
button.Button,
|
|
231
|
+
{
|
|
232
|
+
"data-slot": "button",
|
|
233
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
234
|
+
...props
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
var useAuth = () => {
|
|
239
|
+
const context = React11.useContext(AuthContext);
|
|
240
|
+
if (context === void 0) {
|
|
241
|
+
throw new Error("useAuth must be used within an AuthProvider");
|
|
242
|
+
}
|
|
243
|
+
return context;
|
|
244
|
+
};
|
|
245
|
+
function WelcomeScreen({
|
|
246
|
+
title = "Welcome to Melony",
|
|
247
|
+
description = "The most powerful AI agent framework for building modern applications. Connect your tools, build your brain, and ship faster.",
|
|
248
|
+
features = [
|
|
249
|
+
{
|
|
250
|
+
title: "Context Aware",
|
|
251
|
+
description: "Built-in state management for complex LLM flows."
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
title: "Extensible",
|
|
255
|
+
description: "Plugin architecture for easy integrations."
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
title: "Real-time",
|
|
259
|
+
description: "Streaming responses and live state updates."
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
title: "Tool-ready",
|
|
263
|
+
description: "Ready-to-use actions for common tasks."
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
className,
|
|
267
|
+
onLoginClick,
|
|
268
|
+
termsUrl = "#",
|
|
269
|
+
privacyUrl = "#",
|
|
270
|
+
imageUrl,
|
|
271
|
+
imageAlt = "Product screenshot"
|
|
272
|
+
}) {
|
|
273
|
+
const { login, isLoading } = useAuth();
|
|
274
|
+
const handleLogin = () => {
|
|
275
|
+
if (onLoginClick) {
|
|
276
|
+
onLoginClick();
|
|
277
|
+
} else {
|
|
278
|
+
login();
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
282
|
+
"div",
|
|
283
|
+
{
|
|
284
|
+
className: cn(
|
|
285
|
+
"flex min-h-[600px] h-full w-full flex-col md:flex-row bg-background overflow-hidden",
|
|
286
|
+
className
|
|
287
|
+
),
|
|
288
|
+
children: [
|
|
289
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-8/12 flex-col bg-sidebar text-foreground relative overflow-hidden", children: [
|
|
290
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-24 -left-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
291
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -bottom-24 -right-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
292
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden relative z-10 flex flex-col p-8 md:p-12 lg:p-20", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-xl mx-auto w-full my-auto", children: [
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mb-6 text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-foreground", children: title }),
|
|
294
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-12 text-lg text-muted-foreground md:text-xl leading-relaxed", children: description }),
|
|
295
|
+
imageUrl && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-12 relative group", children: [
|
|
296
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -inset-1 bg-gradient-to-r from-primary/20 to-primary/10 rounded-xl blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200" }),
|
|
297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
298
|
+
"img",
|
|
299
|
+
{
|
|
300
|
+
src: imageUrl,
|
|
301
|
+
alt: imageAlt,
|
|
302
|
+
className: "relative rounded-xl border border-border/50 shadow-2xl transition-transform duration-500 hover:scale-[1.02] w-full"
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
] }),
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2", children: features.map((feature, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
307
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-bold text-lg text-foreground", children: feature.title }),
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: feature.description })
|
|
309
|
+
] }, i)) })
|
|
310
|
+
] }) })
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-4/12 flex-col overflow-y-auto p-8 md:p-12 lg:p-20 bg-background transition-colors duration-300", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-sm space-y-8 my-auto mx-auto", children: [
|
|
313
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 text-center md:text-left", children: [
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: "Get Started" }),
|
|
315
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-lg", children: "Sign in to your account to continue" })
|
|
316
|
+
] }),
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
319
|
+
Button,
|
|
320
|
+
{
|
|
321
|
+
size: "lg",
|
|
322
|
+
variant: "outline",
|
|
323
|
+
className: "w-full h-16 text-lg shadow-sm hover:shadow-md transition-all flex items-center justify-center gap-3 border-2 font-medium bg-background text-foreground hover:bg-accent",
|
|
324
|
+
onClick: handleLogin,
|
|
325
|
+
disabled: isLoading,
|
|
326
|
+
children: [
|
|
327
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconBrandGoogle, { className: "size-6" }),
|
|
328
|
+
isLoading ? "Signing in..." : "Continue with Google"
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
),
|
|
332
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative py-4", children: [
|
|
333
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-full border-t border-border" }) }),
|
|
334
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-background px-3 text-muted-foreground tracking-widest font-medium", children: "Secure access" }) })
|
|
335
|
+
] })
|
|
336
|
+
] }),
|
|
337
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground leading-relaxed text-center md:text-left", children: [
|
|
338
|
+
"By continuing, you agree to our ",
|
|
339
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", { className: "hidden md:block" }),
|
|
340
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
341
|
+
"a",
|
|
342
|
+
{
|
|
343
|
+
href: termsUrl,
|
|
344
|
+
target: "_blank",
|
|
345
|
+
rel: "noopener noreferrer",
|
|
346
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
347
|
+
children: "Terms of Service"
|
|
348
|
+
}
|
|
349
|
+
),
|
|
350
|
+
" ",
|
|
351
|
+
"and",
|
|
352
|
+
" ",
|
|
353
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
354
|
+
"a",
|
|
355
|
+
{
|
|
356
|
+
href: privacyUrl,
|
|
357
|
+
target: "_blank",
|
|
358
|
+
rel: "noopener noreferrer",
|
|
359
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
360
|
+
children: "Privacy Policy"
|
|
361
|
+
}
|
|
362
|
+
),
|
|
363
|
+
"."
|
|
364
|
+
] })
|
|
365
|
+
] }) })
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
}
|
|
191
370
|
var AuthContext = React11.createContext(
|
|
192
371
|
void 0
|
|
193
372
|
);
|
|
194
373
|
var AuthProvider = ({
|
|
195
374
|
children,
|
|
196
|
-
service
|
|
375
|
+
service,
|
|
376
|
+
welcomeScreenProps
|
|
197
377
|
}) => {
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
} finally {
|
|
209
|
-
setIsLoading(false);
|
|
378
|
+
const queryClient = reactQuery.useQueryClient();
|
|
379
|
+
const { data: user, isLoading } = reactQuery.useQuery({
|
|
380
|
+
queryKey: ["auth-user", service],
|
|
381
|
+
queryFn: () => service.getMe(),
|
|
382
|
+
retry: false
|
|
383
|
+
});
|
|
384
|
+
const logoutMutation = reactQuery.useMutation({
|
|
385
|
+
mutationFn: () => service.logout(),
|
|
386
|
+
onSuccess: () => {
|
|
387
|
+
queryClient.setQueryData(["auth-user", service], null);
|
|
210
388
|
}
|
|
211
|
-
}
|
|
212
|
-
React11.useEffect(() => {
|
|
213
|
-
fetchMe();
|
|
214
|
-
}, [fetchMe]);
|
|
389
|
+
});
|
|
215
390
|
const login = React11.useCallback(() => {
|
|
216
391
|
service.login();
|
|
217
392
|
}, [service]);
|
|
218
393
|
const logout = React11.useCallback(async () => {
|
|
219
394
|
try {
|
|
220
|
-
await
|
|
221
|
-
setUser(null);
|
|
395
|
+
await logoutMutation.mutateAsync();
|
|
222
396
|
} catch (error) {
|
|
223
397
|
console.error("Failed to logout:", error);
|
|
224
398
|
}
|
|
225
|
-
}, [
|
|
226
|
-
const value = {
|
|
227
|
-
user,
|
|
228
|
-
isAuthenticated: !!user,
|
|
229
|
-
isLoading,
|
|
230
|
-
login,
|
|
231
|
-
logout,
|
|
232
|
-
getToken: service.getToken
|
|
233
|
-
};
|
|
399
|
+
}, [logoutMutation]);
|
|
234
400
|
if (isLoading) {
|
|
235
401
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
236
402
|
"div",
|
|
@@ -249,7 +415,15 @@ var AuthProvider = ({
|
|
|
249
415
|
}
|
|
250
416
|
);
|
|
251
417
|
}
|
|
252
|
-
|
|
418
|
+
const value = {
|
|
419
|
+
user: user || null,
|
|
420
|
+
isAuthenticated: !!user,
|
|
421
|
+
isLoading,
|
|
422
|
+
login,
|
|
423
|
+
logout,
|
|
424
|
+
getToken: service.getToken
|
|
425
|
+
};
|
|
426
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children: !value.isAuthenticated && welcomeScreenProps ? /* @__PURE__ */ jsxRuntime.jsx(WelcomeScreen, { ...welcomeScreenProps }) : children });
|
|
253
427
|
};
|
|
254
428
|
var ThreadContext = React11.createContext(
|
|
255
429
|
void 0
|
|
@@ -346,6 +520,103 @@ var ThreadProvider = ({
|
|
|
346
520
|
);
|
|
347
521
|
return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
|
|
348
522
|
};
|
|
523
|
+
function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
|
|
524
|
+
const [screenSize, setScreenSize] = React11.useState(() => {
|
|
525
|
+
if (typeof window === "undefined") {
|
|
526
|
+
return {
|
|
527
|
+
width: 1024,
|
|
528
|
+
height: 768,
|
|
529
|
+
isMobile: false,
|
|
530
|
+
isTablet: false,
|
|
531
|
+
isDesktop: true
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
const width = window.innerWidth;
|
|
535
|
+
return {
|
|
536
|
+
width,
|
|
537
|
+
height: window.innerHeight,
|
|
538
|
+
isMobile: width < mobileBreakpoint,
|
|
539
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
540
|
+
isDesktop: width >= tabletBreakpoint
|
|
541
|
+
};
|
|
542
|
+
});
|
|
543
|
+
React11.useEffect(() => {
|
|
544
|
+
if (typeof window === "undefined") return;
|
|
545
|
+
const updateScreenSize = () => {
|
|
546
|
+
const width = window.innerWidth;
|
|
547
|
+
const height = window.innerHeight;
|
|
548
|
+
setScreenSize({
|
|
549
|
+
width,
|
|
550
|
+
height,
|
|
551
|
+
isMobile: width < mobileBreakpoint,
|
|
552
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
553
|
+
isDesktop: width >= tabletBreakpoint
|
|
554
|
+
});
|
|
555
|
+
};
|
|
556
|
+
updateScreenSize();
|
|
557
|
+
window.addEventListener("resize", updateScreenSize);
|
|
558
|
+
return () => {
|
|
559
|
+
window.removeEventListener("resize", updateScreenSize);
|
|
560
|
+
};
|
|
561
|
+
}, [mobileBreakpoint, tabletBreakpoint]);
|
|
562
|
+
return screenSize;
|
|
563
|
+
}
|
|
564
|
+
var SidebarContext = React11.createContext(
|
|
565
|
+
void 0
|
|
566
|
+
);
|
|
567
|
+
function useSidebar() {
|
|
568
|
+
const context = React11.useContext(SidebarContext);
|
|
569
|
+
if (context === void 0) {
|
|
570
|
+
throw new Error("useSidebar must be used within a SidebarProvider");
|
|
571
|
+
}
|
|
572
|
+
return context;
|
|
573
|
+
}
|
|
574
|
+
function SidebarProvider({
|
|
575
|
+
children,
|
|
576
|
+
defaultLeftCollapsed,
|
|
577
|
+
defaultRightCollapsed
|
|
578
|
+
}) {
|
|
579
|
+
const { isMobile, isTablet } = useScreenSize();
|
|
580
|
+
const isSmallScreen = isMobile || isTablet;
|
|
581
|
+
const [leftCollapsed, setLeftCollapsed] = React11.useState(() => {
|
|
582
|
+
if (defaultLeftCollapsed !== void 0) return defaultLeftCollapsed;
|
|
583
|
+
if (typeof window !== "undefined") {
|
|
584
|
+
return window.innerWidth < 1024;
|
|
585
|
+
}
|
|
586
|
+
return false;
|
|
587
|
+
});
|
|
588
|
+
const [rightCollapsed, setRightCollapsed] = React11.useState(() => {
|
|
589
|
+
if (defaultRightCollapsed !== void 0) return defaultRightCollapsed;
|
|
590
|
+
if (typeof window !== "undefined") {
|
|
591
|
+
return window.innerWidth < 1024;
|
|
592
|
+
}
|
|
593
|
+
return false;
|
|
594
|
+
});
|
|
595
|
+
React11.useEffect(() => {
|
|
596
|
+
if (isSmallScreen) {
|
|
597
|
+
setLeftCollapsed(true);
|
|
598
|
+
setRightCollapsed(true);
|
|
599
|
+
}
|
|
600
|
+
}, [isSmallScreen]);
|
|
601
|
+
const handleLeftToggle = React11.useCallback((collapsed) => {
|
|
602
|
+
setLeftCollapsed(collapsed);
|
|
603
|
+
}, []);
|
|
604
|
+
const handleRightToggle = React11.useCallback((collapsed) => {
|
|
605
|
+
setRightCollapsed(collapsed);
|
|
606
|
+
}, []);
|
|
607
|
+
const contextValue = React11.useMemo(
|
|
608
|
+
() => ({
|
|
609
|
+
leftCollapsed,
|
|
610
|
+
rightCollapsed,
|
|
611
|
+
setLeftCollapsed: handleLeftToggle,
|
|
612
|
+
setRightCollapsed: handleRightToggle,
|
|
613
|
+
leftCollapsible: true,
|
|
614
|
+
rightCollapsible: true
|
|
615
|
+
}),
|
|
616
|
+
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
617
|
+
);
|
|
618
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: contextValue, children });
|
|
619
|
+
}
|
|
349
620
|
var ThemeContext = React11.createContext(void 0);
|
|
350
621
|
function ThemeProvider({ children }) {
|
|
351
622
|
const [theme, setThemeState] = React11.useState("system");
|
|
@@ -419,13 +690,6 @@ var useMelony = (options) => {
|
|
|
419
690
|
}, [client, initialEvents, reset]);
|
|
420
691
|
return context;
|
|
421
692
|
};
|
|
422
|
-
var useAuth = () => {
|
|
423
|
-
const context = React11.useContext(AuthContext);
|
|
424
|
-
if (context === void 0) {
|
|
425
|
-
throw new Error("useAuth must be used within an AuthProvider");
|
|
426
|
-
}
|
|
427
|
-
return context;
|
|
428
|
-
};
|
|
429
693
|
var useThreads = () => {
|
|
430
694
|
const context = React11.useContext(ThreadContext);
|
|
431
695
|
if (context === void 0) {
|
|
@@ -433,94 +697,6 @@ var useThreads = () => {
|
|
|
433
697
|
}
|
|
434
698
|
return context;
|
|
435
699
|
};
|
|
436
|
-
function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
|
|
437
|
-
const [screenSize, setScreenSize] = React11.useState(() => {
|
|
438
|
-
if (typeof window === "undefined") {
|
|
439
|
-
return {
|
|
440
|
-
width: 1024,
|
|
441
|
-
height: 768,
|
|
442
|
-
isMobile: false,
|
|
443
|
-
isTablet: false,
|
|
444
|
-
isDesktop: true
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
const width = window.innerWidth;
|
|
448
|
-
return {
|
|
449
|
-
width,
|
|
450
|
-
height: window.innerHeight,
|
|
451
|
-
isMobile: width < mobileBreakpoint,
|
|
452
|
-
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
453
|
-
isDesktop: width >= tabletBreakpoint
|
|
454
|
-
};
|
|
455
|
-
});
|
|
456
|
-
React11.useEffect(() => {
|
|
457
|
-
if (typeof window === "undefined") return;
|
|
458
|
-
const updateScreenSize = () => {
|
|
459
|
-
const width = window.innerWidth;
|
|
460
|
-
const height = window.innerHeight;
|
|
461
|
-
setScreenSize({
|
|
462
|
-
width,
|
|
463
|
-
height,
|
|
464
|
-
isMobile: width < mobileBreakpoint,
|
|
465
|
-
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
466
|
-
isDesktop: width >= tabletBreakpoint
|
|
467
|
-
});
|
|
468
|
-
};
|
|
469
|
-
updateScreenSize();
|
|
470
|
-
window.addEventListener("resize", updateScreenSize);
|
|
471
|
-
return () => {
|
|
472
|
-
window.removeEventListener("resize", updateScreenSize);
|
|
473
|
-
};
|
|
474
|
-
}, [mobileBreakpoint, tabletBreakpoint]);
|
|
475
|
-
return screenSize;
|
|
476
|
-
}
|
|
477
|
-
function cn(...inputs) {
|
|
478
|
-
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
479
|
-
}
|
|
480
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
481
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
|
|
482
|
-
{
|
|
483
|
-
variants: {
|
|
484
|
-
variant: {
|
|
485
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
486
|
-
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
487
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
488
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
489
|
-
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
490
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
491
|
-
},
|
|
492
|
-
size: {
|
|
493
|
-
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
494
|
-
xs: "h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
|
|
495
|
-
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
496
|
-
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
497
|
-
icon: "size-9",
|
|
498
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
499
|
-
"icon-sm": "size-8",
|
|
500
|
-
"icon-lg": "size-10"
|
|
501
|
-
}
|
|
502
|
-
},
|
|
503
|
-
defaultVariants: {
|
|
504
|
-
variant: "default",
|
|
505
|
-
size: "default"
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
);
|
|
509
|
-
function Button({
|
|
510
|
-
className,
|
|
511
|
-
variant = "default",
|
|
512
|
-
size = "default",
|
|
513
|
-
...props
|
|
514
|
-
}) {
|
|
515
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
516
|
-
button.Button,
|
|
517
|
-
{
|
|
518
|
-
"data-slot": "button",
|
|
519
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
520
|
-
...props
|
|
521
|
-
}
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
700
|
function Textarea({ className, ...props }) {
|
|
525
701
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
526
702
|
"textarea",
|
|
@@ -710,7 +886,22 @@ function Composer({
|
|
|
710
886
|
() => new Set(defaultSelectedIds)
|
|
711
887
|
);
|
|
712
888
|
const [attachedFiles, setAttachedFiles] = React11__namespace.default.useState([]);
|
|
889
|
+
const [previews, setPreviews] = React11__namespace.default.useState([]);
|
|
713
890
|
const fileInputRef = React11__namespace.default.useRef(null);
|
|
891
|
+
React11__namespace.default.useEffect(() => {
|
|
892
|
+
const newPreviews = attachedFiles.map((file) => ({
|
|
893
|
+
name: file.name,
|
|
894
|
+
type: file.type,
|
|
895
|
+
size: file.size,
|
|
896
|
+
url: file.type.startsWith("image/") ? URL.createObjectURL(file) : ""
|
|
897
|
+
}));
|
|
898
|
+
setPreviews(newPreviews);
|
|
899
|
+
return () => {
|
|
900
|
+
newPreviews.forEach((p) => {
|
|
901
|
+
if (p.url) URL.revokeObjectURL(p.url);
|
|
902
|
+
});
|
|
903
|
+
};
|
|
904
|
+
}, [attachedFiles]);
|
|
714
905
|
const toggleOption = (id, groupOptions, type = "multiple") => {
|
|
715
906
|
const next = new Set(selectedOptions);
|
|
716
907
|
if (type === "single") {
|
|
@@ -756,11 +947,6 @@ function Composer({
|
|
|
756
947
|
const handleRemoveFile = (index) => {
|
|
757
948
|
setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
|
|
758
949
|
};
|
|
759
|
-
const formatFileSize = (bytes) => {
|
|
760
|
-
if (bytes < 1024) return bytes + " B";
|
|
761
|
-
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
|
|
762
|
-
return (bytes / (1024 * 1024)).toFixed(1) + " MB";
|
|
763
|
-
};
|
|
764
950
|
const handleInternalSubmit = async () => {
|
|
765
951
|
const state = {};
|
|
766
952
|
options.forEach((group) => {
|
|
@@ -826,13 +1012,56 @@ function Composer({
|
|
|
826
1012
|
handleInternalSubmit().catch(console.error);
|
|
827
1013
|
}
|
|
828
1014
|
};
|
|
1015
|
+
const handlePaste = (e) => {
|
|
1016
|
+
if (!enabled) return;
|
|
1017
|
+
const items = Array.from(e.clipboardData.items);
|
|
1018
|
+
const files = items.map((item) => item.getAsFile()).filter((file) => file !== null);
|
|
1019
|
+
if (files.length > 0) {
|
|
1020
|
+
const remainingSlots = maxFiles - attachedFiles.length;
|
|
1021
|
+
const validFiles = files.filter((f) => f.size <= maxFileSize);
|
|
1022
|
+
const filesToAdd = validFiles.slice(0, remainingSlots);
|
|
1023
|
+
if (filesToAdd.length > 0) {
|
|
1024
|
+
setAttachedFiles((prev) => [...prev, ...filesToAdd]);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
829
1028
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col w-full border-input border-[1.5px] rounded-3xl bg-background shadow-sm focus-within:border-ring transition-all p-2", children: [
|
|
1029
|
+
previews.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-3 p-2 px-3 pb-3", children: previews.map((preview, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1030
|
+
"div",
|
|
1031
|
+
{
|
|
1032
|
+
className: "group relative flex flex-col items-center justify-center w-20 h-20 rounded-xl border bg-muted/30 overflow-hidden shadow-sm",
|
|
1033
|
+
children: [
|
|
1034
|
+
preview.type.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1035
|
+
"img",
|
|
1036
|
+
{
|
|
1037
|
+
src: preview.url,
|
|
1038
|
+
alt: preview.name,
|
|
1039
|
+
className: "w-full h-full object-cover"
|
|
1040
|
+
}
|
|
1041
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center p-2 text-center", children: [
|
|
1042
|
+
preview.type.includes("text") || preview.type.includes("pdf") ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconFileText, { className: "h-8 w-8 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconFile, { className: "h-8 w-8 text-muted-foreground" }),
|
|
1043
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] truncate w-full px-1 mt-1 text-muted-foreground", children: preview.name })
|
|
1044
|
+
] }),
|
|
1045
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1046
|
+
"button",
|
|
1047
|
+
{
|
|
1048
|
+
type: "button",
|
|
1049
|
+
onClick: () => handleRemoveFile(index),
|
|
1050
|
+
className: "absolute top-1 right-1 p-1 rounded-full bg-foreground/10 hover:bg-foreground/20 backdrop-blur-md opacity-0 group-hover:opacity-100 transition-opacity",
|
|
1051
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-3 w-3" })
|
|
1052
|
+
}
|
|
1053
|
+
)
|
|
1054
|
+
]
|
|
1055
|
+
},
|
|
1056
|
+
index
|
|
1057
|
+
)) }),
|
|
830
1058
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
831
1059
|
Textarea,
|
|
832
1060
|
{
|
|
833
1061
|
value,
|
|
834
1062
|
onChange: (e) => onChange(e.target.value),
|
|
835
1063
|
onKeyDown: handleKeyDown,
|
|
1064
|
+
onPaste: handlePaste,
|
|
836
1065
|
placeholder,
|
|
837
1066
|
className: "min-h-[44px] max-h-[200px] border-none bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 py-2 text-[15px] resize-none",
|
|
838
1067
|
autoFocus
|
|
@@ -853,100 +1082,22 @@ function Composer({
|
|
|
853
1082
|
disabled: isLoading || attachedFiles.length >= maxFiles
|
|
854
1083
|
}
|
|
855
1084
|
),
|
|
856
|
-
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
857
1086
|
Button,
|
|
858
1087
|
{
|
|
859
1088
|
type: "button",
|
|
860
1089
|
variant: "ghost",
|
|
861
1090
|
size: "sm",
|
|
862
1091
|
onClick: () => fileInputRef.current?.click(),
|
|
863
|
-
disabled: isLoading,
|
|
1092
|
+
disabled: isLoading || attachedFiles.length >= maxFiles,
|
|
864
1093
|
className: "text-muted-foreground",
|
|
865
1094
|
title: "Attach file",
|
|
866
|
-
children:
|
|
1095
|
+
children: [
|
|
1096
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPaperclip, { className: "h-4 w-4" }),
|
|
1097
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "ml-1 h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
|
|
1098
|
+
]
|
|
867
1099
|
}
|
|
868
|
-
)
|
|
869
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
870
|
-
DropdownMenuTrigger,
|
|
871
|
-
{
|
|
872
|
-
render: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
873
|
-
Button,
|
|
874
|
-
{
|
|
875
|
-
type: "button",
|
|
876
|
-
variant: "ghost",
|
|
877
|
-
size: "sm",
|
|
878
|
-
className: "text-muted-foreground gap-2",
|
|
879
|
-
title: `${attachedFiles.length} files attached`,
|
|
880
|
-
children: [
|
|
881
|
-
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPaperclip, { className: "h-4 w-4" }),
|
|
882
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
|
|
883
|
-
]
|
|
884
|
-
}
|
|
885
|
-
)
|
|
886
|
-
}
|
|
887
|
-
),
|
|
888
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [
|
|
889
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
|
|
890
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuLabel, { children: [
|
|
891
|
-
"Attached Files (",
|
|
892
|
-
attachedFiles.length,
|
|
893
|
-
"/",
|
|
894
|
-
maxFiles,
|
|
895
|
-
")"
|
|
896
|
-
] }),
|
|
897
|
-
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
898
|
-
attachedFiles.map((file, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
899
|
-
DropdownMenuItem,
|
|
900
|
-
{
|
|
901
|
-
className: "flex items-center justify-between group",
|
|
902
|
-
onSelect: (e) => e.preventDefault(),
|
|
903
|
-
children: [
|
|
904
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
905
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
906
|
-
"span",
|
|
907
|
-
{
|
|
908
|
-
className: "truncate text-sm",
|
|
909
|
-
title: file.name,
|
|
910
|
-
children: file.name
|
|
911
|
-
}
|
|
912
|
-
),
|
|
913
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatFileSize(file.size) })
|
|
914
|
-
] }),
|
|
915
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
916
|
-
Button,
|
|
917
|
-
{
|
|
918
|
-
type: "button",
|
|
919
|
-
variant: "ghost",
|
|
920
|
-
size: "icon",
|
|
921
|
-
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
922
|
-
onClick: () => handleRemoveFile(index),
|
|
923
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-3 w-3" })
|
|
924
|
-
}
|
|
925
|
-
)
|
|
926
|
-
]
|
|
927
|
-
},
|
|
928
|
-
index
|
|
929
|
-
))
|
|
930
|
-
] }),
|
|
931
|
-
attachedFiles.length < maxFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
932
|
-
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
933
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
934
|
-
DropdownMenuItem,
|
|
935
|
-
{
|
|
936
|
-
onSelect: (e) => {
|
|
937
|
-
e.preventDefault();
|
|
938
|
-
fileInputRef.current?.click();
|
|
939
|
-
},
|
|
940
|
-
className: "text-primary focus:text-primary",
|
|
941
|
-
children: [
|
|
942
|
-
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "mr-2 h-4 w-4" }),
|
|
943
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add more files" })
|
|
944
|
-
]
|
|
945
|
-
}
|
|
946
|
-
)
|
|
947
|
-
] })
|
|
948
|
-
] })
|
|
949
|
-
] })
|
|
1100
|
+
)
|
|
950
1101
|
] }),
|
|
951
1102
|
options.map((group) => {
|
|
952
1103
|
const selectedInGroup = group.options.filter(
|
|
@@ -2741,55 +2892,31 @@ var ThreadList = ({
|
|
|
2741
2892
|
emptyState,
|
|
2742
2893
|
onThreadSelect
|
|
2743
2894
|
}) => {
|
|
2744
|
-
const {
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
}
|
|
2895
|
+
const { threads, activeThreadId, selectThread, deleteThread, isLoading } = useThreads();
|
|
2896
|
+
const sortedThreads = React11__namespace.useMemo(() => {
|
|
2897
|
+
return [...threads].sort((a, b) => {
|
|
2898
|
+
const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
|
2899
|
+
const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
2900
|
+
return dateB - dateA;
|
|
2901
|
+
});
|
|
2902
|
+
}, [threads]);
|
|
2752
2903
|
const handleThreadClick = (threadId) => {
|
|
2753
2904
|
if (threadId !== activeThreadId) {
|
|
2754
2905
|
selectThread(threadId);
|
|
2755
2906
|
}
|
|
2756
2907
|
onThreadSelect?.(threadId);
|
|
2757
2908
|
};
|
|
2758
|
-
const handleDelete = async (
|
|
2759
|
-
e.stopPropagation();
|
|
2909
|
+
const handleDelete = async (threadId) => {
|
|
2760
2910
|
try {
|
|
2761
2911
|
await deleteThread(threadId);
|
|
2762
2912
|
} catch (error) {
|
|
2763
2913
|
console.error("Failed to delete thread:", error);
|
|
2764
2914
|
}
|
|
2765
2915
|
};
|
|
2766
|
-
const handleNewThread = async () => {
|
|
2767
|
-
try {
|
|
2768
|
-
await createThread();
|
|
2769
|
-
} catch (error) {
|
|
2770
|
-
console.error("Failed to create thread:", error);
|
|
2771
|
-
}
|
|
2772
|
-
};
|
|
2773
|
-
const formatDate = (date) => {
|
|
2774
|
-
if (!date) return "";
|
|
2775
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
2776
|
-
if (isNaN(d.getTime())) return "";
|
|
2777
|
-
const now = /* @__PURE__ */ new Date();
|
|
2778
|
-
const diffMs = now.getTime() - d.getTime();
|
|
2779
|
-
const diffMins = Math.floor(diffMs / 6e4);
|
|
2780
|
-
const diffHours = Math.floor(diffMs / 36e5);
|
|
2781
|
-
const diffDays = Math.floor(diffMs / 864e5);
|
|
2782
|
-
if (diffMins < 1) return "Just now";
|
|
2783
|
-
if (diffMins < 60) return `${diffMins}m ago`;
|
|
2784
|
-
if (diffHours < 24) return `${diffHours}h ago`;
|
|
2785
|
-
if (diffDays < 7) return `${diffDays}d ago`;
|
|
2786
|
-
return d.toLocaleDateString();
|
|
2787
|
-
};
|
|
2788
2916
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col h-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
2789
2917
|
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMessage, { className: "size-8 mx-auto opacity-50" }),
|
|
2790
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No threads yet" })
|
|
2791
|
-
|
|
2792
|
-
] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
|
|
2918
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No threads yet" })
|
|
2919
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 space-y-1", children: sortedThreads.map((thread) => {
|
|
2793
2920
|
const isActive = thread.id === activeThreadId;
|
|
2794
2921
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2795
2922
|
"div",
|
|
@@ -2797,33 +2924,51 @@ var ThreadList = ({
|
|
|
2797
2924
|
onClick: () => handleThreadClick(thread.id),
|
|
2798
2925
|
className: cn(
|
|
2799
2926
|
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2800
|
-
isActive ? "bg-muted" : "hover:bg-muted"
|
|
2927
|
+
isActive ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground"
|
|
2801
2928
|
),
|
|
2802
2929
|
children: [
|
|
2803
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2930
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium truncate", children: thread.title || `Thread ${thread.id.slice(0, 8)}` }) }),
|
|
2931
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex items-center opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
2932
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2933
|
+
DropdownMenuTrigger,
|
|
2934
|
+
{
|
|
2935
|
+
render: (props) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2936
|
+
Button,
|
|
2937
|
+
{
|
|
2938
|
+
variant: "ghost",
|
|
2939
|
+
size: "icon-xs",
|
|
2940
|
+
...props,
|
|
2941
|
+
onClick: (e) => {
|
|
2942
|
+
e.stopPropagation();
|
|
2943
|
+
props.onClick?.(e);
|
|
2944
|
+
},
|
|
2945
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconDotsVertical, { className: "size-3.5" })
|
|
2946
|
+
}
|
|
2947
|
+
)
|
|
2948
|
+
}
|
|
2949
|
+
),
|
|
2950
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-32", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2951
|
+
DropdownMenuItem,
|
|
2952
|
+
{
|
|
2953
|
+
variant: "destructive",
|
|
2954
|
+
onClick: (e) => {
|
|
2955
|
+
e.stopPropagation();
|
|
2956
|
+
handleDelete(thread.id);
|
|
2957
|
+
},
|
|
2958
|
+
children: [
|
|
2959
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconTrash, { className: "size-4 mr-2" }),
|
|
2960
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delete" })
|
|
2961
|
+
]
|
|
2962
|
+
}
|
|
2963
|
+
) })
|
|
2964
|
+
] }) })
|
|
2820
2965
|
]
|
|
2821
2966
|
},
|
|
2822
2967
|
thread.id
|
|
2823
2968
|
);
|
|
2824
2969
|
}) }) }) });
|
|
2825
2970
|
};
|
|
2826
|
-
function
|
|
2971
|
+
function PopupChat({
|
|
2827
2972
|
title = "Chat",
|
|
2828
2973
|
placeholder = "Message the AI",
|
|
2829
2974
|
starterPrompts,
|
|
@@ -2927,136 +3072,46 @@ function ChatPopup({
|
|
|
2927
3072
|
)
|
|
2928
3073
|
] });
|
|
2929
3074
|
}
|
|
2930
|
-
function
|
|
3075
|
+
function Sidebar({ side, children, className }) {
|
|
3076
|
+
const { leftCollapsed, rightCollapsed } = useSidebar();
|
|
3077
|
+
const collapsed = side === "left" ? leftCollapsed : rightCollapsed;
|
|
3078
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3079
|
+
"div",
|
|
3080
|
+
{
|
|
3081
|
+
className: cn(
|
|
3082
|
+
"flex-shrink-0 border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3083
|
+
side === "left" ? "border-r" : "border-l",
|
|
3084
|
+
collapsed ? "w-0 border-r-0 border-l-0 min-w-0" : "",
|
|
3085
|
+
!collapsed && className
|
|
3086
|
+
),
|
|
3087
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children })
|
|
3088
|
+
}
|
|
3089
|
+
);
|
|
3090
|
+
}
|
|
3091
|
+
function FullChat({
|
|
2931
3092
|
title = "Chat",
|
|
2932
|
-
placeholder
|
|
3093
|
+
placeholder,
|
|
2933
3094
|
starterPrompts,
|
|
2934
3095
|
options,
|
|
2935
3096
|
className,
|
|
2936
3097
|
headerProps,
|
|
3098
|
+
autoFocus = false,
|
|
2937
3099
|
defaultSelectedIds
|
|
2938
3100
|
}) {
|
|
2939
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full
|
|
2940
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
2941
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3101
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
|
|
3102
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
3103
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden flex relative", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2942
3104
|
Thread,
|
|
2943
3105
|
{
|
|
2944
3106
|
placeholder,
|
|
2945
3107
|
starterPrompts,
|
|
2946
3108
|
options,
|
|
2947
|
-
|
|
3109
|
+
autoFocus,
|
|
2948
3110
|
defaultSelectedIds
|
|
2949
3111
|
}
|
|
2950
|
-
) })
|
|
3112
|
+
) }) })
|
|
2951
3113
|
] });
|
|
2952
3114
|
}
|
|
2953
|
-
var ChatSidebarContext = React11.createContext(
|
|
2954
|
-
void 0
|
|
2955
|
-
);
|
|
2956
|
-
function useChatSidebar() {
|
|
2957
|
-
const context = React11.useContext(ChatSidebarContext);
|
|
2958
|
-
if (context === void 0) {
|
|
2959
|
-
throw new Error("useChatSidebar must be used within a ChatSidebarProvider");
|
|
2960
|
-
}
|
|
2961
|
-
return context;
|
|
2962
|
-
}
|
|
2963
|
-
function ChatFull({
|
|
2964
|
-
title = "Chat",
|
|
2965
|
-
placeholder = "Message the AI",
|
|
2966
|
-
starterPrompts,
|
|
2967
|
-
options,
|
|
2968
|
-
className,
|
|
2969
|
-
headerProps,
|
|
2970
|
-
leftSidebar,
|
|
2971
|
-
rightSidebar,
|
|
2972
|
-
leftSidebarClassName,
|
|
2973
|
-
rightSidebarClassName,
|
|
2974
|
-
autoFocus = false,
|
|
2975
|
-
defaultSelectedIds
|
|
2976
|
-
}) {
|
|
2977
|
-
const { isMobile, isTablet } = useScreenSize();
|
|
2978
|
-
const isSmallScreen = isMobile || isTablet;
|
|
2979
|
-
const [internalLeftCollapsed, setInternalLeftCollapsed] = React11.useState(() => {
|
|
2980
|
-
if (typeof window !== "undefined") {
|
|
2981
|
-
return window.innerWidth < 1024;
|
|
2982
|
-
}
|
|
2983
|
-
return false;
|
|
2984
|
-
});
|
|
2985
|
-
const [internalRightCollapsed, setInternalRightCollapsed] = React11.useState(() => {
|
|
2986
|
-
if (typeof window !== "undefined") {
|
|
2987
|
-
return window.innerWidth < 1024;
|
|
2988
|
-
}
|
|
2989
|
-
return false;
|
|
2990
|
-
});
|
|
2991
|
-
React11.useEffect(() => {
|
|
2992
|
-
if (isSmallScreen) {
|
|
2993
|
-
setInternalLeftCollapsed(true);
|
|
2994
|
-
setInternalRightCollapsed(true);
|
|
2995
|
-
}
|
|
2996
|
-
}, [isSmallScreen]);
|
|
2997
|
-
const leftCollapsed = internalLeftCollapsed;
|
|
2998
|
-
const rightCollapsed = internalRightCollapsed;
|
|
2999
|
-
const handleLeftToggle = React11.useCallback((collapsed) => {
|
|
3000
|
-
setInternalLeftCollapsed(collapsed);
|
|
3001
|
-
}, []);
|
|
3002
|
-
const handleRightToggle = React11.useCallback((collapsed) => {
|
|
3003
|
-
setInternalRightCollapsed(collapsed);
|
|
3004
|
-
}, []);
|
|
3005
|
-
const contextValue = React11.useMemo(
|
|
3006
|
-
() => ({
|
|
3007
|
-
leftCollapsed,
|
|
3008
|
-
rightCollapsed,
|
|
3009
|
-
setLeftCollapsed: handleLeftToggle,
|
|
3010
|
-
setRightCollapsed: handleRightToggle,
|
|
3011
|
-
leftCollapsible: true,
|
|
3012
|
-
rightCollapsible: true
|
|
3013
|
-
}),
|
|
3014
|
-
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
3015
|
-
);
|
|
3016
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3017
|
-
"div",
|
|
3018
|
-
{
|
|
3019
|
-
className: cn("flex flex-col h-full w-full bg-background", className),
|
|
3020
|
-
children: [
|
|
3021
|
-
title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
3022
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
|
|
3023
|
-
leftSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3024
|
-
"div",
|
|
3025
|
-
{
|
|
3026
|
-
className: cn(
|
|
3027
|
-
"flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3028
|
-
leftCollapsed ? "w-0 border-r-0 min-w-0" : "",
|
|
3029
|
-
!leftCollapsed && leftSidebarClassName
|
|
3030
|
-
),
|
|
3031
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
|
|
3032
|
-
}
|
|
3033
|
-
),
|
|
3034
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3035
|
-
Thread,
|
|
3036
|
-
{
|
|
3037
|
-
placeholder,
|
|
3038
|
-
starterPrompts,
|
|
3039
|
-
options,
|
|
3040
|
-
autoFocus,
|
|
3041
|
-
defaultSelectedIds
|
|
3042
|
-
}
|
|
3043
|
-
) }),
|
|
3044
|
-
rightSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3045
|
-
"div",
|
|
3046
|
-
{
|
|
3047
|
-
className: cn(
|
|
3048
|
-
"flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3049
|
-
rightCollapsed ? "w-0 border-l-0 min-w-0" : "",
|
|
3050
|
-
!rightCollapsed && rightSidebarClassName
|
|
3051
|
-
),
|
|
3052
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
|
|
3053
|
-
}
|
|
3054
|
-
)
|
|
3055
|
-
] })
|
|
3056
|
-
]
|
|
3057
|
-
}
|
|
3058
|
-
) });
|
|
3059
|
-
}
|
|
3060
3115
|
function SidebarToggle({ side, className }) {
|
|
3061
3116
|
const {
|
|
3062
3117
|
leftCollapsed,
|
|
@@ -3065,13 +3120,14 @@ function SidebarToggle({ side, className }) {
|
|
|
3065
3120
|
setRightCollapsed,
|
|
3066
3121
|
leftCollapsible,
|
|
3067
3122
|
rightCollapsible
|
|
3068
|
-
} =
|
|
3123
|
+
} = useSidebar();
|
|
3069
3124
|
if (side === "left") {
|
|
3070
3125
|
if (!leftCollapsible) return null;
|
|
3071
3126
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3072
3127
|
Button,
|
|
3073
3128
|
{
|
|
3074
3129
|
variant: "ghost",
|
|
3130
|
+
size: "icon",
|
|
3075
3131
|
onClick: () => setLeftCollapsed(!leftCollapsed),
|
|
3076
3132
|
"aria-label": leftCollapsed ? "Expand left sidebar" : "Collapse left sidebar",
|
|
3077
3133
|
className: cn("", className),
|
|
@@ -3085,6 +3141,7 @@ function SidebarToggle({ side, className }) {
|
|
|
3085
3141
|
Button,
|
|
3086
3142
|
{
|
|
3087
3143
|
variant: "ghost",
|
|
3144
|
+
size: "icon",
|
|
3088
3145
|
onClick: () => setRightCollapsed(!rightCollapsed),
|
|
3089
3146
|
"aria-label": rightCollapsed ? "Expand right sidebar" : "Collapse right sidebar",
|
|
3090
3147
|
className: cn("", className),
|
|
@@ -3352,7 +3409,7 @@ var ThreadPopover = ({
|
|
|
3352
3409
|
var CreateThreadButton = ({
|
|
3353
3410
|
className,
|
|
3354
3411
|
variant = "ghost",
|
|
3355
|
-
size = "
|
|
3412
|
+
size = "default",
|
|
3356
3413
|
children,
|
|
3357
3414
|
onThreadCreated
|
|
3358
3415
|
}) => {
|
|
@@ -3383,7 +3440,7 @@ var CreateThreadButton = ({
|
|
|
3383
3440
|
// Don't trigger in contenteditable elements
|
|
3384
3441
|
}
|
|
3385
3442
|
);
|
|
3386
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3443
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3387
3444
|
Button,
|
|
3388
3445
|
{
|
|
3389
3446
|
variant,
|
|
@@ -3391,7 +3448,10 @@ var CreateThreadButton = ({
|
|
|
3391
3448
|
onClick: handleCreateThread,
|
|
3392
3449
|
disabled: isCreating,
|
|
3393
3450
|
className: cn(className),
|
|
3394
|
-
children:
|
|
3451
|
+
children: [
|
|
3452
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "size-4" }),
|
|
3453
|
+
"New chat"
|
|
3454
|
+
]
|
|
3395
3455
|
}
|
|
3396
3456
|
);
|
|
3397
3457
|
};
|
|
@@ -3585,17 +3645,14 @@ var AccountDialog = ({
|
|
|
3585
3645
|
] });
|
|
3586
3646
|
}
|
|
3587
3647
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3588
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3648
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3589
3649
|
Button,
|
|
3590
3650
|
{
|
|
3591
3651
|
variant,
|
|
3592
3652
|
size,
|
|
3593
3653
|
onClick: () => setOpen(true),
|
|
3594
3654
|
className,
|
|
3595
|
-
children:
|
|
3596
|
-
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconBrandGoogle, { className: "mr-2 size-4" }),
|
|
3597
|
-
"Sign in with Google"
|
|
3598
|
-
]
|
|
3655
|
+
children: "Sign in"
|
|
3599
3656
|
}
|
|
3600
3657
|
),
|
|
3601
3658
|
/* @__PURE__ */ jsxRuntime.jsx(AlertDialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogContent, { className: "sm:max-w-md", children: [
|
|
@@ -3667,17 +3724,14 @@ exports.Box = Box;
|
|
|
3667
3724
|
exports.Button = Button2;
|
|
3668
3725
|
exports.Card = Card2;
|
|
3669
3726
|
exports.Chart = Chart;
|
|
3670
|
-
exports.ChatFull = ChatFull;
|
|
3671
3727
|
exports.ChatHeader = ChatHeader;
|
|
3672
|
-
exports.ChatPopup = ChatPopup;
|
|
3673
|
-
exports.ChatSidebar = ChatSidebar;
|
|
3674
|
-
exports.ChatSidebarContext = ChatSidebarContext;
|
|
3675
3728
|
exports.Checkbox = Checkbox;
|
|
3676
3729
|
exports.Col = Col;
|
|
3677
3730
|
exports.Composer = Composer;
|
|
3678
3731
|
exports.CreateThreadButton = CreateThreadButton;
|
|
3679
3732
|
exports.Divider = Divider;
|
|
3680
3733
|
exports.Form = Form;
|
|
3734
|
+
exports.FullChat = FullChat;
|
|
3681
3735
|
exports.Heading = Heading;
|
|
3682
3736
|
exports.Image = Image;
|
|
3683
3737
|
exports.Input = Input2;
|
|
@@ -3686,9 +3740,13 @@ exports.List = List;
|
|
|
3686
3740
|
exports.ListItem = ListItem;
|
|
3687
3741
|
exports.MelonyClientProvider = MelonyClientProvider;
|
|
3688
3742
|
exports.MelonyContext = MelonyContext;
|
|
3743
|
+
exports.PopupChat = PopupChat;
|
|
3689
3744
|
exports.RadioGroup = RadioGroup;
|
|
3690
3745
|
exports.Row = Row;
|
|
3691
3746
|
exports.Select = Select2;
|
|
3747
|
+
exports.Sidebar = Sidebar;
|
|
3748
|
+
exports.SidebarContext = SidebarContext;
|
|
3749
|
+
exports.SidebarProvider = SidebarProvider;
|
|
3692
3750
|
exports.SidebarToggle = SidebarToggle;
|
|
3693
3751
|
exports.Spacer = Spacer;
|
|
3694
3752
|
exports.Text = Text;
|
|
@@ -3701,11 +3759,12 @@ exports.ThreadList = ThreadList;
|
|
|
3701
3759
|
exports.ThreadPopover = ThreadPopover;
|
|
3702
3760
|
exports.ThreadProvider = ThreadProvider;
|
|
3703
3761
|
exports.UIRenderer = UIRenderer;
|
|
3762
|
+
exports.WelcomeScreen = WelcomeScreen;
|
|
3704
3763
|
exports.groupEventsToMessages = groupEventsToMessages;
|
|
3705
3764
|
exports.useAuth = useAuth;
|
|
3706
|
-
exports.useChatSidebar = useChatSidebar;
|
|
3707
3765
|
exports.useMelony = useMelony;
|
|
3708
3766
|
exports.useScreenSize = useScreenSize;
|
|
3767
|
+
exports.useSidebar = useSidebar;
|
|
3709
3768
|
exports.useTheme = useTheme;
|
|
3710
3769
|
exports.useThreads = useThreads;
|
|
3711
3770
|
//# sourceMappingURL=index.cjs.map
|