@melony/react 0.1.26 → 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/dist/index.cjs +533 -629
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -71
- package/dist/index.d.ts +47 -71
- package/dist/index.js +487 -584
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React11 from 'react';
|
|
2
|
+
import React11__default, { createContext, useState, useContext, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
3
3
|
import { NuqsAdapter } from 'nuqs/adapters/react';
|
|
4
4
|
import { QueryClient, QueryClientProvider, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
-
import { generateId } from 'melony/client';
|
|
7
|
-
import { useQueryState, parseAsString } from 'nuqs';
|
|
8
|
-
import { clsx } from 'clsx';
|
|
9
|
-
import { twMerge } from 'tailwind-merge';
|
|
10
6
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
11
7
|
import { cva } from 'class-variance-authority';
|
|
8
|
+
import { clsx } from 'clsx';
|
|
9
|
+
import { twMerge } from 'tailwind-merge';
|
|
10
|
+
import * as ICONS from '@tabler/icons-react';
|
|
11
|
+
import { IconBrandGoogle, IconFileText, IconFile, IconX, IconPaperclip, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconDotsVertical, IconTrash, IconHistory, IconPlus, IconArrowLeft, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
12
|
+
import { generateId } from 'melony/client';
|
|
13
|
+
import { useQueryState, parseAsString } from 'nuqs';
|
|
12
14
|
import { mergeProps } from '@base-ui/react/merge-props';
|
|
13
15
|
import { useRender } from '@base-ui/react/use-render';
|
|
14
|
-
import * as ICONS from '@tabler/icons-react';
|
|
15
|
-
import { IconPaperclip, IconX, IconPlus, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconDotsVertical, IconTrash, IconHistory, IconArrowLeft, IconBrandGoogle, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
16
16
|
import { Menu } from '@base-ui/react/menu';
|
|
17
17
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
18
18
|
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
@@ -167,49 +167,215 @@ var MelonyClientProvider = ({
|
|
|
167
167
|
}
|
|
168
168
|
) }) });
|
|
169
169
|
};
|
|
170
|
+
function cn(...inputs) {
|
|
171
|
+
return twMerge(clsx(inputs));
|
|
172
|
+
}
|
|
173
|
+
var buttonVariants = cva(
|
|
174
|
+
"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",
|
|
175
|
+
{
|
|
176
|
+
variants: {
|
|
177
|
+
variant: {
|
|
178
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
179
|
+
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
180
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
181
|
+
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
182
|
+
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",
|
|
183
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
184
|
+
},
|
|
185
|
+
size: {
|
|
186
|
+
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
187
|
+
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",
|
|
188
|
+
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
189
|
+
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
190
|
+
icon: "size-9",
|
|
191
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
192
|
+
"icon-sm": "size-8",
|
|
193
|
+
"icon-lg": "size-10"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
defaultVariants: {
|
|
197
|
+
variant: "default",
|
|
198
|
+
size: "default"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
function Button({
|
|
203
|
+
className,
|
|
204
|
+
variant = "default",
|
|
205
|
+
size = "default",
|
|
206
|
+
...props
|
|
207
|
+
}) {
|
|
208
|
+
return /* @__PURE__ */ jsx(
|
|
209
|
+
Button$1,
|
|
210
|
+
{
|
|
211
|
+
"data-slot": "button",
|
|
212
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
213
|
+
...props
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
var useAuth = () => {
|
|
218
|
+
const context = useContext(AuthContext);
|
|
219
|
+
if (context === void 0) {
|
|
220
|
+
throw new Error("useAuth must be used within an AuthProvider");
|
|
221
|
+
}
|
|
222
|
+
return context;
|
|
223
|
+
};
|
|
224
|
+
function WelcomeScreen({
|
|
225
|
+
title = "Welcome to Melony",
|
|
226
|
+
description = "The most powerful AI agent framework for building modern applications. Connect your tools, build your brain, and ship faster.",
|
|
227
|
+
features = [
|
|
228
|
+
{
|
|
229
|
+
title: "Context Aware",
|
|
230
|
+
description: "Built-in state management for complex LLM flows."
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
title: "Extensible",
|
|
234
|
+
description: "Plugin architecture for easy integrations."
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
title: "Real-time",
|
|
238
|
+
description: "Streaming responses and live state updates."
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
title: "Tool-ready",
|
|
242
|
+
description: "Ready-to-use actions for common tasks."
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
className,
|
|
246
|
+
onLoginClick,
|
|
247
|
+
termsUrl = "#",
|
|
248
|
+
privacyUrl = "#",
|
|
249
|
+
imageUrl,
|
|
250
|
+
imageAlt = "Product screenshot"
|
|
251
|
+
}) {
|
|
252
|
+
const { login, isLoading } = useAuth();
|
|
253
|
+
const handleLogin = () => {
|
|
254
|
+
if (onLoginClick) {
|
|
255
|
+
onLoginClick();
|
|
256
|
+
} else {
|
|
257
|
+
login();
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
return /* @__PURE__ */ jsxs(
|
|
261
|
+
"div",
|
|
262
|
+
{
|
|
263
|
+
className: cn(
|
|
264
|
+
"flex min-h-[600px] h-full w-full flex-col md:flex-row bg-background overflow-hidden",
|
|
265
|
+
className
|
|
266
|
+
),
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-8/12 flex-col bg-sidebar text-foreground relative overflow-hidden", children: [
|
|
269
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -top-24 -left-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
270
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -bottom-24 -right-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
271
|
+
/* @__PURE__ */ 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__ */ jsxs("div", { className: "max-w-xl mx-auto w-full my-auto", children: [
|
|
272
|
+
/* @__PURE__ */ jsx("h1", { className: "mb-6 text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-foreground", children: title }),
|
|
273
|
+
/* @__PURE__ */ jsx("p", { className: "mb-12 text-lg text-muted-foreground md:text-xl leading-relaxed", children: description }),
|
|
274
|
+
imageUrl && /* @__PURE__ */ jsxs("div", { className: "mb-12 relative group", children: [
|
|
275
|
+
/* @__PURE__ */ 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" }),
|
|
276
|
+
/* @__PURE__ */ jsx(
|
|
277
|
+
"img",
|
|
278
|
+
{
|
|
279
|
+
src: imageUrl,
|
|
280
|
+
alt: imageAlt,
|
|
281
|
+
className: "relative rounded-xl border border-border/50 shadow-2xl transition-transform duration-500 hover:scale-[1.02] w-full"
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
] }),
|
|
285
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2", children: features.map((feature, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
286
|
+
/* @__PURE__ */ jsx("h3", { className: "font-bold text-lg text-foreground", children: feature.title }),
|
|
287
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: feature.description })
|
|
288
|
+
] }, i)) })
|
|
289
|
+
] }) })
|
|
290
|
+
] }),
|
|
291
|
+
/* @__PURE__ */ 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__ */ jsxs("div", { className: "w-full max-w-sm space-y-8 my-auto mx-auto", children: [
|
|
292
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3 text-center md:text-left", children: [
|
|
293
|
+
/* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: "Get Started" }),
|
|
294
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-lg", children: "Sign in to your account to continue" })
|
|
295
|
+
] }),
|
|
296
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
297
|
+
/* @__PURE__ */ jsxs(
|
|
298
|
+
Button,
|
|
299
|
+
{
|
|
300
|
+
size: "lg",
|
|
301
|
+
variant: "outline",
|
|
302
|
+
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",
|
|
303
|
+
onClick: handleLogin,
|
|
304
|
+
disabled: isLoading,
|
|
305
|
+
children: [
|
|
306
|
+
/* @__PURE__ */ jsx(IconBrandGoogle, { className: "size-6" }),
|
|
307
|
+
isLoading ? "Signing in..." : "Continue with Google"
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
),
|
|
311
|
+
/* @__PURE__ */ jsxs("div", { className: "relative py-4", children: [
|
|
312
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "w-full border-t border-border" }) }),
|
|
313
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-3 text-muted-foreground tracking-widest font-medium", children: "Secure access" }) })
|
|
314
|
+
] })
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground leading-relaxed text-center md:text-left", children: [
|
|
317
|
+
"By continuing, you agree to our ",
|
|
318
|
+
/* @__PURE__ */ jsx("br", { className: "hidden md:block" }),
|
|
319
|
+
/* @__PURE__ */ jsx(
|
|
320
|
+
"a",
|
|
321
|
+
{
|
|
322
|
+
href: termsUrl,
|
|
323
|
+
target: "_blank",
|
|
324
|
+
rel: "noopener noreferrer",
|
|
325
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
326
|
+
children: "Terms of Service"
|
|
327
|
+
}
|
|
328
|
+
),
|
|
329
|
+
" ",
|
|
330
|
+
"and",
|
|
331
|
+
" ",
|
|
332
|
+
/* @__PURE__ */ jsx(
|
|
333
|
+
"a",
|
|
334
|
+
{
|
|
335
|
+
href: privacyUrl,
|
|
336
|
+
target: "_blank",
|
|
337
|
+
rel: "noopener noreferrer",
|
|
338
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
339
|
+
children: "Privacy Policy"
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
"."
|
|
343
|
+
] })
|
|
344
|
+
] }) })
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
}
|
|
170
349
|
var AuthContext = createContext(
|
|
171
350
|
void 0
|
|
172
351
|
);
|
|
173
352
|
var AuthProvider = ({
|
|
174
353
|
children,
|
|
175
|
-
service
|
|
354
|
+
service,
|
|
355
|
+
welcomeScreenProps
|
|
176
356
|
}) => {
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
} finally {
|
|
188
|
-
setIsLoading(false);
|
|
357
|
+
const queryClient = useQueryClient();
|
|
358
|
+
const { data: user, isLoading } = useQuery({
|
|
359
|
+
queryKey: ["auth-user", service],
|
|
360
|
+
queryFn: () => service.getMe(),
|
|
361
|
+
retry: false
|
|
362
|
+
});
|
|
363
|
+
const logoutMutation = useMutation({
|
|
364
|
+
mutationFn: () => service.logout(),
|
|
365
|
+
onSuccess: () => {
|
|
366
|
+
queryClient.setQueryData(["auth-user", service], null);
|
|
189
367
|
}
|
|
190
|
-
}
|
|
191
|
-
useEffect(() => {
|
|
192
|
-
fetchMe();
|
|
193
|
-
}, [fetchMe]);
|
|
368
|
+
});
|
|
194
369
|
const login = useCallback(() => {
|
|
195
370
|
service.login();
|
|
196
371
|
}, [service]);
|
|
197
372
|
const logout = useCallback(async () => {
|
|
198
373
|
try {
|
|
199
|
-
await
|
|
200
|
-
setUser(null);
|
|
374
|
+
await logoutMutation.mutateAsync();
|
|
201
375
|
} catch (error) {
|
|
202
376
|
console.error("Failed to logout:", error);
|
|
203
377
|
}
|
|
204
|
-
}, [
|
|
205
|
-
const value = {
|
|
206
|
-
user,
|
|
207
|
-
isAuthenticated: !!user,
|
|
208
|
-
isLoading,
|
|
209
|
-
login,
|
|
210
|
-
logout,
|
|
211
|
-
getToken: service.getToken
|
|
212
|
-
};
|
|
378
|
+
}, [logoutMutation]);
|
|
213
379
|
if (isLoading) {
|
|
214
380
|
return /* @__PURE__ */ jsx(
|
|
215
381
|
"div",
|
|
@@ -228,7 +394,15 @@ var AuthProvider = ({
|
|
|
228
394
|
}
|
|
229
395
|
);
|
|
230
396
|
}
|
|
231
|
-
|
|
397
|
+
const value = {
|
|
398
|
+
user: user || null,
|
|
399
|
+
isAuthenticated: !!user,
|
|
400
|
+
isLoading,
|
|
401
|
+
login,
|
|
402
|
+
logout,
|
|
403
|
+
getToken: service.getToken
|
|
404
|
+
};
|
|
405
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children: !value.isAuthenticated && welcomeScreenProps ? /* @__PURE__ */ jsx(WelcomeScreen, { ...welcomeScreenProps }) : children });
|
|
232
406
|
};
|
|
233
407
|
var ThreadContext = createContext(
|
|
234
408
|
void 0
|
|
@@ -325,6 +499,103 @@ var ThreadProvider = ({
|
|
|
325
499
|
);
|
|
326
500
|
return /* @__PURE__ */ jsx(ThreadContext.Provider, { value, children });
|
|
327
501
|
};
|
|
502
|
+
function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
|
|
503
|
+
const [screenSize, setScreenSize] = useState(() => {
|
|
504
|
+
if (typeof window === "undefined") {
|
|
505
|
+
return {
|
|
506
|
+
width: 1024,
|
|
507
|
+
height: 768,
|
|
508
|
+
isMobile: false,
|
|
509
|
+
isTablet: false,
|
|
510
|
+
isDesktop: true
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
const width = window.innerWidth;
|
|
514
|
+
return {
|
|
515
|
+
width,
|
|
516
|
+
height: window.innerHeight,
|
|
517
|
+
isMobile: width < mobileBreakpoint,
|
|
518
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
519
|
+
isDesktop: width >= tabletBreakpoint
|
|
520
|
+
};
|
|
521
|
+
});
|
|
522
|
+
useEffect(() => {
|
|
523
|
+
if (typeof window === "undefined") return;
|
|
524
|
+
const updateScreenSize = () => {
|
|
525
|
+
const width = window.innerWidth;
|
|
526
|
+
const height = window.innerHeight;
|
|
527
|
+
setScreenSize({
|
|
528
|
+
width,
|
|
529
|
+
height,
|
|
530
|
+
isMobile: width < mobileBreakpoint,
|
|
531
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
532
|
+
isDesktop: width >= tabletBreakpoint
|
|
533
|
+
});
|
|
534
|
+
};
|
|
535
|
+
updateScreenSize();
|
|
536
|
+
window.addEventListener("resize", updateScreenSize);
|
|
537
|
+
return () => {
|
|
538
|
+
window.removeEventListener("resize", updateScreenSize);
|
|
539
|
+
};
|
|
540
|
+
}, [mobileBreakpoint, tabletBreakpoint]);
|
|
541
|
+
return screenSize;
|
|
542
|
+
}
|
|
543
|
+
var SidebarContext = createContext(
|
|
544
|
+
void 0
|
|
545
|
+
);
|
|
546
|
+
function useSidebar() {
|
|
547
|
+
const context = useContext(SidebarContext);
|
|
548
|
+
if (context === void 0) {
|
|
549
|
+
throw new Error("useSidebar must be used within a SidebarProvider");
|
|
550
|
+
}
|
|
551
|
+
return context;
|
|
552
|
+
}
|
|
553
|
+
function SidebarProvider({
|
|
554
|
+
children,
|
|
555
|
+
defaultLeftCollapsed,
|
|
556
|
+
defaultRightCollapsed
|
|
557
|
+
}) {
|
|
558
|
+
const { isMobile, isTablet } = useScreenSize();
|
|
559
|
+
const isSmallScreen = isMobile || isTablet;
|
|
560
|
+
const [leftCollapsed, setLeftCollapsed] = useState(() => {
|
|
561
|
+
if (defaultLeftCollapsed !== void 0) return defaultLeftCollapsed;
|
|
562
|
+
if (typeof window !== "undefined") {
|
|
563
|
+
return window.innerWidth < 1024;
|
|
564
|
+
}
|
|
565
|
+
return false;
|
|
566
|
+
});
|
|
567
|
+
const [rightCollapsed, setRightCollapsed] = useState(() => {
|
|
568
|
+
if (defaultRightCollapsed !== void 0) return defaultRightCollapsed;
|
|
569
|
+
if (typeof window !== "undefined") {
|
|
570
|
+
return window.innerWidth < 1024;
|
|
571
|
+
}
|
|
572
|
+
return false;
|
|
573
|
+
});
|
|
574
|
+
useEffect(() => {
|
|
575
|
+
if (isSmallScreen) {
|
|
576
|
+
setLeftCollapsed(true);
|
|
577
|
+
setRightCollapsed(true);
|
|
578
|
+
}
|
|
579
|
+
}, [isSmallScreen]);
|
|
580
|
+
const handleLeftToggle = useCallback((collapsed) => {
|
|
581
|
+
setLeftCollapsed(collapsed);
|
|
582
|
+
}, []);
|
|
583
|
+
const handleRightToggle = useCallback((collapsed) => {
|
|
584
|
+
setRightCollapsed(collapsed);
|
|
585
|
+
}, []);
|
|
586
|
+
const contextValue = useMemo(
|
|
587
|
+
() => ({
|
|
588
|
+
leftCollapsed,
|
|
589
|
+
rightCollapsed,
|
|
590
|
+
setLeftCollapsed: handleLeftToggle,
|
|
591
|
+
setRightCollapsed: handleRightToggle,
|
|
592
|
+
leftCollapsible: true,
|
|
593
|
+
rightCollapsible: true
|
|
594
|
+
}),
|
|
595
|
+
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
596
|
+
);
|
|
597
|
+
return /* @__PURE__ */ jsx(SidebarContext.Provider, { value: contextValue, children });
|
|
598
|
+
}
|
|
328
599
|
var ThemeContext = createContext(void 0);
|
|
329
600
|
function ThemeProvider({ children }) {
|
|
330
601
|
const [theme, setThemeState] = useState("system");
|
|
@@ -398,13 +669,6 @@ var useMelony = (options) => {
|
|
|
398
669
|
}, [client, initialEvents, reset]);
|
|
399
670
|
return context;
|
|
400
671
|
};
|
|
401
|
-
var useAuth = () => {
|
|
402
|
-
const context = useContext(AuthContext);
|
|
403
|
-
if (context === void 0) {
|
|
404
|
-
throw new Error("useAuth must be used within an AuthProvider");
|
|
405
|
-
}
|
|
406
|
-
return context;
|
|
407
|
-
};
|
|
408
672
|
var useThreads = () => {
|
|
409
673
|
const context = useContext(ThreadContext);
|
|
410
674
|
if (context === void 0) {
|
|
@@ -412,94 +676,6 @@ var useThreads = () => {
|
|
|
412
676
|
}
|
|
413
677
|
return context;
|
|
414
678
|
};
|
|
415
|
-
function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
|
|
416
|
-
const [screenSize, setScreenSize] = useState(() => {
|
|
417
|
-
if (typeof window === "undefined") {
|
|
418
|
-
return {
|
|
419
|
-
width: 1024,
|
|
420
|
-
height: 768,
|
|
421
|
-
isMobile: false,
|
|
422
|
-
isTablet: false,
|
|
423
|
-
isDesktop: true
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
const width = window.innerWidth;
|
|
427
|
-
return {
|
|
428
|
-
width,
|
|
429
|
-
height: window.innerHeight,
|
|
430
|
-
isMobile: width < mobileBreakpoint,
|
|
431
|
-
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
432
|
-
isDesktop: width >= tabletBreakpoint
|
|
433
|
-
};
|
|
434
|
-
});
|
|
435
|
-
useEffect(() => {
|
|
436
|
-
if (typeof window === "undefined") return;
|
|
437
|
-
const updateScreenSize = () => {
|
|
438
|
-
const width = window.innerWidth;
|
|
439
|
-
const height = window.innerHeight;
|
|
440
|
-
setScreenSize({
|
|
441
|
-
width,
|
|
442
|
-
height,
|
|
443
|
-
isMobile: width < mobileBreakpoint,
|
|
444
|
-
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
445
|
-
isDesktop: width >= tabletBreakpoint
|
|
446
|
-
});
|
|
447
|
-
};
|
|
448
|
-
updateScreenSize();
|
|
449
|
-
window.addEventListener("resize", updateScreenSize);
|
|
450
|
-
return () => {
|
|
451
|
-
window.removeEventListener("resize", updateScreenSize);
|
|
452
|
-
};
|
|
453
|
-
}, [mobileBreakpoint, tabletBreakpoint]);
|
|
454
|
-
return screenSize;
|
|
455
|
-
}
|
|
456
|
-
function cn(...inputs) {
|
|
457
|
-
return twMerge(clsx(inputs));
|
|
458
|
-
}
|
|
459
|
-
var buttonVariants = cva(
|
|
460
|
-
"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",
|
|
461
|
-
{
|
|
462
|
-
variants: {
|
|
463
|
-
variant: {
|
|
464
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
465
|
-
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
466
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
467
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
468
|
-
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",
|
|
469
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
470
|
-
},
|
|
471
|
-
size: {
|
|
472
|
-
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
473
|
-
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",
|
|
474
|
-
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
475
|
-
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
476
|
-
icon: "size-9",
|
|
477
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
478
|
-
"icon-sm": "size-8",
|
|
479
|
-
"icon-lg": "size-10"
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
defaultVariants: {
|
|
483
|
-
variant: "default",
|
|
484
|
-
size: "default"
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
);
|
|
488
|
-
function Button({
|
|
489
|
-
className,
|
|
490
|
-
variant = "default",
|
|
491
|
-
size = "default",
|
|
492
|
-
...props
|
|
493
|
-
}) {
|
|
494
|
-
return /* @__PURE__ */ jsx(
|
|
495
|
-
Button$1,
|
|
496
|
-
{
|
|
497
|
-
"data-slot": "button",
|
|
498
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
499
|
-
...props
|
|
500
|
-
}
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
679
|
function Textarea({ className, ...props }) {
|
|
504
680
|
return /* @__PURE__ */ jsx(
|
|
505
681
|
"textarea",
|
|
@@ -685,11 +861,26 @@ function Composer({
|
|
|
685
861
|
const accept = fileAttachments?.accept;
|
|
686
862
|
const maxFiles = fileAttachments?.maxFiles ?? 10;
|
|
687
863
|
const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
|
|
688
|
-
const [selectedOptions, setSelectedOptions] =
|
|
864
|
+
const [selectedOptions, setSelectedOptions] = React11__default.useState(
|
|
689
865
|
() => new Set(defaultSelectedIds)
|
|
690
866
|
);
|
|
691
|
-
const [attachedFiles, setAttachedFiles] =
|
|
692
|
-
const
|
|
867
|
+
const [attachedFiles, setAttachedFiles] = React11__default.useState([]);
|
|
868
|
+
const [previews, setPreviews] = React11__default.useState([]);
|
|
869
|
+
const fileInputRef = React11__default.useRef(null);
|
|
870
|
+
React11__default.useEffect(() => {
|
|
871
|
+
const newPreviews = attachedFiles.map((file) => ({
|
|
872
|
+
name: file.name,
|
|
873
|
+
type: file.type,
|
|
874
|
+
size: file.size,
|
|
875
|
+
url: file.type.startsWith("image/") ? URL.createObjectURL(file) : ""
|
|
876
|
+
}));
|
|
877
|
+
setPreviews(newPreviews);
|
|
878
|
+
return () => {
|
|
879
|
+
newPreviews.forEach((p) => {
|
|
880
|
+
if (p.url) URL.revokeObjectURL(p.url);
|
|
881
|
+
});
|
|
882
|
+
};
|
|
883
|
+
}, [attachedFiles]);
|
|
693
884
|
const toggleOption = (id, groupOptions, type = "multiple") => {
|
|
694
885
|
const next = new Set(selectedOptions);
|
|
695
886
|
if (type === "single") {
|
|
@@ -735,11 +926,6 @@ function Composer({
|
|
|
735
926
|
const handleRemoveFile = (index) => {
|
|
736
927
|
setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
|
|
737
928
|
};
|
|
738
|
-
const formatFileSize = (bytes) => {
|
|
739
|
-
if (bytes < 1024) return bytes + " B";
|
|
740
|
-
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
|
|
741
|
-
return (bytes / (1024 * 1024)).toFixed(1) + " MB";
|
|
742
|
-
};
|
|
743
929
|
const handleInternalSubmit = async () => {
|
|
744
930
|
const state = {};
|
|
745
931
|
options.forEach((group) => {
|
|
@@ -805,13 +991,56 @@ function Composer({
|
|
|
805
991
|
handleInternalSubmit().catch(console.error);
|
|
806
992
|
}
|
|
807
993
|
};
|
|
994
|
+
const handlePaste = (e) => {
|
|
995
|
+
if (!enabled) return;
|
|
996
|
+
const items = Array.from(e.clipboardData.items);
|
|
997
|
+
const files = items.map((item) => item.getAsFile()).filter((file) => file !== null);
|
|
998
|
+
if (files.length > 0) {
|
|
999
|
+
const remainingSlots = maxFiles - attachedFiles.length;
|
|
1000
|
+
const validFiles = files.filter((f) => f.size <= maxFileSize);
|
|
1001
|
+
const filesToAdd = validFiles.slice(0, remainingSlots);
|
|
1002
|
+
if (filesToAdd.length > 0) {
|
|
1003
|
+
setAttachedFiles((prev) => [...prev, ...filesToAdd]);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
808
1007
|
return /* @__PURE__ */ jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ 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: [
|
|
1008
|
+
previews.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3 p-2 px-3 pb-3", children: previews.map((preview, index) => /* @__PURE__ */ jsxs(
|
|
1009
|
+
"div",
|
|
1010
|
+
{
|
|
1011
|
+
className: "group relative flex flex-col items-center justify-center w-20 h-20 rounded-xl border bg-muted/30 overflow-hidden shadow-sm",
|
|
1012
|
+
children: [
|
|
1013
|
+
preview.type.startsWith("image/") ? /* @__PURE__ */ jsx(
|
|
1014
|
+
"img",
|
|
1015
|
+
{
|
|
1016
|
+
src: preview.url,
|
|
1017
|
+
alt: preview.name,
|
|
1018
|
+
className: "w-full h-full object-cover"
|
|
1019
|
+
}
|
|
1020
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center p-2 text-center", children: [
|
|
1021
|
+
preview.type.includes("text") || preview.type.includes("pdf") ? /* @__PURE__ */ jsx(IconFileText, { className: "h-8 w-8 text-muted-foreground" }) : /* @__PURE__ */ jsx(IconFile, { className: "h-8 w-8 text-muted-foreground" }),
|
|
1022
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] truncate w-full px-1 mt-1 text-muted-foreground", children: preview.name })
|
|
1023
|
+
] }),
|
|
1024
|
+
/* @__PURE__ */ jsx(
|
|
1025
|
+
"button",
|
|
1026
|
+
{
|
|
1027
|
+
type: "button",
|
|
1028
|
+
onClick: () => handleRemoveFile(index),
|
|
1029
|
+
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",
|
|
1030
|
+
children: /* @__PURE__ */ jsx(IconX, { className: "h-3 w-3" })
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
]
|
|
1034
|
+
},
|
|
1035
|
+
index
|
|
1036
|
+
)) }),
|
|
809
1037
|
/* @__PURE__ */ jsx(
|
|
810
1038
|
Textarea,
|
|
811
1039
|
{
|
|
812
1040
|
value,
|
|
813
1041
|
onChange: (e) => onChange(e.target.value),
|
|
814
1042
|
onKeyDown: handleKeyDown,
|
|
1043
|
+
onPaste: handlePaste,
|
|
815
1044
|
placeholder,
|
|
816
1045
|
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",
|
|
817
1046
|
autoFocus
|
|
@@ -832,100 +1061,22 @@ function Composer({
|
|
|
832
1061
|
disabled: isLoading || attachedFiles.length >= maxFiles
|
|
833
1062
|
}
|
|
834
1063
|
),
|
|
835
|
-
|
|
1064
|
+
/* @__PURE__ */ jsxs(
|
|
836
1065
|
Button,
|
|
837
1066
|
{
|
|
838
1067
|
type: "button",
|
|
839
1068
|
variant: "ghost",
|
|
840
1069
|
size: "sm",
|
|
841
1070
|
onClick: () => fileInputRef.current?.click(),
|
|
842
|
-
disabled: isLoading,
|
|
1071
|
+
disabled: isLoading || attachedFiles.length >= maxFiles,
|
|
843
1072
|
className: "text-muted-foreground",
|
|
844
1073
|
title: "Attach file",
|
|
845
|
-
children:
|
|
1074
|
+
children: [
|
|
1075
|
+
/* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" }),
|
|
1076
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsx(Badge, { className: "ml-1 h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
|
|
1077
|
+
]
|
|
846
1078
|
}
|
|
847
|
-
)
|
|
848
|
-
/* @__PURE__ */ jsx(
|
|
849
|
-
DropdownMenuTrigger,
|
|
850
|
-
{
|
|
851
|
-
render: /* @__PURE__ */ jsxs(
|
|
852
|
-
Button,
|
|
853
|
-
{
|
|
854
|
-
type: "button",
|
|
855
|
-
variant: "ghost",
|
|
856
|
-
size: "sm",
|
|
857
|
-
className: "text-muted-foreground gap-2",
|
|
858
|
-
title: `${attachedFiles.length} files attached`,
|
|
859
|
-
children: [
|
|
860
|
-
/* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" }),
|
|
861
|
-
/* @__PURE__ */ jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
|
|
862
|
-
]
|
|
863
|
-
}
|
|
864
|
-
)
|
|
865
|
-
}
|
|
866
|
-
),
|
|
867
|
-
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [
|
|
868
|
-
/* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
|
|
869
|
-
/* @__PURE__ */ jsxs(DropdownMenuLabel, { children: [
|
|
870
|
-
"Attached Files (",
|
|
871
|
-
attachedFiles.length,
|
|
872
|
-
"/",
|
|
873
|
-
maxFiles,
|
|
874
|
-
")"
|
|
875
|
-
] }),
|
|
876
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
877
|
-
attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
|
|
878
|
-
DropdownMenuItem,
|
|
879
|
-
{
|
|
880
|
-
className: "flex items-center justify-between group",
|
|
881
|
-
onSelect: (e) => e.preventDefault(),
|
|
882
|
-
children: [
|
|
883
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
884
|
-
/* @__PURE__ */ jsx(
|
|
885
|
-
"span",
|
|
886
|
-
{
|
|
887
|
-
className: "truncate text-sm",
|
|
888
|
-
title: file.name,
|
|
889
|
-
children: file.name
|
|
890
|
-
}
|
|
891
|
-
),
|
|
892
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatFileSize(file.size) })
|
|
893
|
-
] }),
|
|
894
|
-
/* @__PURE__ */ jsx(
|
|
895
|
-
Button,
|
|
896
|
-
{
|
|
897
|
-
type: "button",
|
|
898
|
-
variant: "ghost",
|
|
899
|
-
size: "icon",
|
|
900
|
-
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
901
|
-
onClick: () => handleRemoveFile(index),
|
|
902
|
-
children: /* @__PURE__ */ jsx(IconX, { className: "h-3 w-3" })
|
|
903
|
-
}
|
|
904
|
-
)
|
|
905
|
-
]
|
|
906
|
-
},
|
|
907
|
-
index
|
|
908
|
-
))
|
|
909
|
-
] }),
|
|
910
|
-
attachedFiles.length < maxFiles && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
911
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
912
|
-
/* @__PURE__ */ jsxs(
|
|
913
|
-
DropdownMenuItem,
|
|
914
|
-
{
|
|
915
|
-
onSelect: (e) => {
|
|
916
|
-
e.preventDefault();
|
|
917
|
-
fileInputRef.current?.click();
|
|
918
|
-
},
|
|
919
|
-
className: "text-primary focus:text-primary",
|
|
920
|
-
children: [
|
|
921
|
-
/* @__PURE__ */ jsx(IconPlus, { className: "mr-2 h-4 w-4" }),
|
|
922
|
-
/* @__PURE__ */ jsx("span", { children: "Add more files" })
|
|
923
|
-
]
|
|
924
|
-
}
|
|
925
|
-
)
|
|
926
|
-
] })
|
|
927
|
-
] })
|
|
928
|
-
] })
|
|
1079
|
+
)
|
|
929
1080
|
] }),
|
|
930
1081
|
options.map((group) => {
|
|
931
1082
|
const selectedInGroup = group.options.filter(
|
|
@@ -2720,15 +2871,8 @@ var ThreadList = ({
|
|
|
2720
2871
|
emptyState,
|
|
2721
2872
|
onThreadSelect
|
|
2722
2873
|
}) => {
|
|
2723
|
-
const {
|
|
2724
|
-
|
|
2725
|
-
activeThreadId,
|
|
2726
|
-
selectThread,
|
|
2727
|
-
createThread,
|
|
2728
|
-
deleteThread,
|
|
2729
|
-
isLoading
|
|
2730
|
-
} = useThreads();
|
|
2731
|
-
const sortedThreads = React12.useMemo(() => {
|
|
2874
|
+
const { threads, activeThreadId, selectThread, deleteThread, isLoading } = useThreads();
|
|
2875
|
+
const sortedThreads = React11.useMemo(() => {
|
|
2732
2876
|
return [...threads].sort((a, b) => {
|
|
2733
2877
|
const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
|
2734
2878
|
const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
@@ -2745,87 +2889,65 @@ var ThreadList = ({
|
|
|
2745
2889
|
try {
|
|
2746
2890
|
await deleteThread(threadId);
|
|
2747
2891
|
} catch (error) {
|
|
2748
|
-
console.error("Failed to delete thread:", error);
|
|
2749
|
-
}
|
|
2750
|
-
};
|
|
2751
|
-
const handleNewThread = async () => {
|
|
2752
|
-
try {
|
|
2753
|
-
await createThread();
|
|
2754
|
-
} catch (error) {
|
|
2755
|
-
console.error("Failed to create thread:", error);
|
|
2892
|
+
console.error("Failed to delete thread:", error);
|
|
2756
2893
|
}
|
|
2757
2894
|
};
|
|
2758
|
-
return /* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */ jsx(
|
|
2760
|
-
|
|
2895
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col h-full", className), children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2896
|
+
/* @__PURE__ */ jsx(IconMessage, { className: "size-8 mx-auto opacity-50" }),
|
|
2897
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" })
|
|
2898
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: sortedThreads.map((thread) => {
|
|
2899
|
+
const isActive = thread.id === activeThreadId;
|
|
2900
|
+
return /* @__PURE__ */ jsxs(
|
|
2901
|
+
"div",
|
|
2761
2902
|
{
|
|
2762
|
-
|
|
2763
|
-
className:
|
|
2764
|
-
|
|
2903
|
+
onClick: () => handleThreadClick(thread.id),
|
|
2904
|
+
className: cn(
|
|
2905
|
+
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2906
|
+
isActive ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground"
|
|
2907
|
+
),
|
|
2765
2908
|
children: [
|
|
2766
|
-
/* @__PURE__ */ jsx(
|
|
2767
|
-
/* @__PURE__ */ jsx("
|
|
2909
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium truncate", children: thread.title || `Thread ${thread.id.slice(0, 8)}` }) }),
|
|
2910
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2911
|
+
/* @__PURE__ */ jsx(
|
|
2912
|
+
DropdownMenuTrigger,
|
|
2913
|
+
{
|
|
2914
|
+
render: (props) => /* @__PURE__ */ jsx(
|
|
2915
|
+
Button,
|
|
2916
|
+
{
|
|
2917
|
+
variant: "ghost",
|
|
2918
|
+
size: "icon-xs",
|
|
2919
|
+
...props,
|
|
2920
|
+
onClick: (e) => {
|
|
2921
|
+
e.stopPropagation();
|
|
2922
|
+
props.onClick?.(e);
|
|
2923
|
+
},
|
|
2924
|
+
children: /* @__PURE__ */ jsx(IconDotsVertical, { className: "size-3.5" })
|
|
2925
|
+
}
|
|
2926
|
+
)
|
|
2927
|
+
}
|
|
2928
|
+
),
|
|
2929
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-32", children: /* @__PURE__ */ jsxs(
|
|
2930
|
+
DropdownMenuItem,
|
|
2931
|
+
{
|
|
2932
|
+
variant: "destructive",
|
|
2933
|
+
onClick: (e) => {
|
|
2934
|
+
e.stopPropagation();
|
|
2935
|
+
handleDelete(thread.id);
|
|
2936
|
+
},
|
|
2937
|
+
children: [
|
|
2938
|
+
/* @__PURE__ */ jsx(IconTrash, { className: "size-4 mr-2" }),
|
|
2939
|
+
/* @__PURE__ */ jsx("span", { children: "Delete" })
|
|
2940
|
+
]
|
|
2941
|
+
}
|
|
2942
|
+
) })
|
|
2943
|
+
] }) })
|
|
2768
2944
|
]
|
|
2769
|
-
}
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" }),
|
|
2774
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
|
|
2775
|
-
] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: sortedThreads.map((thread) => {
|
|
2776
|
-
const isActive = thread.id === activeThreadId;
|
|
2777
|
-
return /* @__PURE__ */ jsxs(
|
|
2778
|
-
"div",
|
|
2779
|
-
{
|
|
2780
|
-
onClick: () => handleThreadClick(thread.id),
|
|
2781
|
-
className: cn(
|
|
2782
|
-
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2783
|
-
isActive ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground"
|
|
2784
|
-
),
|
|
2785
|
-
children: [
|
|
2786
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium truncate", children: thread.title || `Thread ${thread.id.slice(0, 8)}` }) }),
|
|
2787
|
-
/* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2788
|
-
/* @__PURE__ */ jsx(
|
|
2789
|
-
DropdownMenuTrigger,
|
|
2790
|
-
{
|
|
2791
|
-
render: (props) => /* @__PURE__ */ jsx(
|
|
2792
|
-
Button,
|
|
2793
|
-
{
|
|
2794
|
-
variant: "ghost",
|
|
2795
|
-
size: "icon-xs",
|
|
2796
|
-
...props,
|
|
2797
|
-
onClick: (e) => {
|
|
2798
|
-
e.stopPropagation();
|
|
2799
|
-
props.onClick?.(e);
|
|
2800
|
-
},
|
|
2801
|
-
children: /* @__PURE__ */ jsx(IconDotsVertical, { className: "size-3.5" })
|
|
2802
|
-
}
|
|
2803
|
-
)
|
|
2804
|
-
}
|
|
2805
|
-
),
|
|
2806
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-32", children: /* @__PURE__ */ jsxs(
|
|
2807
|
-
DropdownMenuItem,
|
|
2808
|
-
{
|
|
2809
|
-
variant: "destructive",
|
|
2810
|
-
onClick: (e) => {
|
|
2811
|
-
e.stopPropagation();
|
|
2812
|
-
handleDelete(thread.id);
|
|
2813
|
-
},
|
|
2814
|
-
children: [
|
|
2815
|
-
/* @__PURE__ */ jsx(IconTrash, { className: "size-4 mr-2" }),
|
|
2816
|
-
/* @__PURE__ */ jsx("span", { children: "Delete" })
|
|
2817
|
-
]
|
|
2818
|
-
}
|
|
2819
|
-
) })
|
|
2820
|
-
] }) })
|
|
2821
|
-
]
|
|
2822
|
-
},
|
|
2823
|
-
thread.id
|
|
2824
|
-
);
|
|
2825
|
-
}) }) })
|
|
2826
|
-
] });
|
|
2945
|
+
},
|
|
2946
|
+
thread.id
|
|
2947
|
+
);
|
|
2948
|
+
}) }) }) });
|
|
2827
2949
|
};
|
|
2828
|
-
function
|
|
2950
|
+
function PopupChat({
|
|
2829
2951
|
title = "Chat",
|
|
2830
2952
|
placeholder = "Message the AI",
|
|
2831
2953
|
starterPrompts,
|
|
@@ -2929,266 +3051,45 @@ function ChatPopup({
|
|
|
2929
3051
|
)
|
|
2930
3052
|
] });
|
|
2931
3053
|
}
|
|
2932
|
-
function
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
options,
|
|
2937
|
-
className,
|
|
2938
|
-
headerProps,
|
|
2939
|
-
defaultSelectedIds
|
|
2940
|
-
}) {
|
|
2941
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full border-r bg-background w-80", className), children: [
|
|
2942
|
-
/* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
|
|
2943
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
2944
|
-
Thread,
|
|
2945
|
-
{
|
|
2946
|
-
placeholder,
|
|
2947
|
-
starterPrompts,
|
|
2948
|
-
options,
|
|
2949
|
-
className: "h-full",
|
|
2950
|
-
defaultSelectedIds
|
|
2951
|
-
}
|
|
2952
|
-
) })
|
|
2953
|
-
] });
|
|
2954
|
-
}
|
|
2955
|
-
var ChatSidebarContext = createContext(
|
|
2956
|
-
void 0
|
|
2957
|
-
);
|
|
2958
|
-
function useChatSidebar() {
|
|
2959
|
-
const context = useContext(ChatSidebarContext);
|
|
2960
|
-
if (context === void 0) {
|
|
2961
|
-
throw new Error("useChatSidebar must be used within a ChatSidebarProvider");
|
|
2962
|
-
}
|
|
2963
|
-
return context;
|
|
2964
|
-
}
|
|
2965
|
-
function WelcomeScreen({
|
|
2966
|
-
title = "Welcome to Melony",
|
|
2967
|
-
description = "The most powerful AI agent framework for building modern applications. Connect your tools, build your brain, and ship faster.",
|
|
2968
|
-
features = [
|
|
2969
|
-
{
|
|
2970
|
-
title: "Context Aware",
|
|
2971
|
-
description: "Built-in state management for complex LLM flows."
|
|
2972
|
-
},
|
|
2973
|
-
{
|
|
2974
|
-
title: "Extensible",
|
|
2975
|
-
description: "Plugin architecture for easy integrations."
|
|
2976
|
-
},
|
|
2977
|
-
{
|
|
2978
|
-
title: "Real-time",
|
|
2979
|
-
description: "Streaming responses and live state updates."
|
|
2980
|
-
},
|
|
2981
|
-
{
|
|
2982
|
-
title: "Tool-ready",
|
|
2983
|
-
description: "Ready-to-use actions for common tasks."
|
|
2984
|
-
}
|
|
2985
|
-
],
|
|
2986
|
-
className,
|
|
2987
|
-
onLoginClick,
|
|
2988
|
-
termsUrl = "#",
|
|
2989
|
-
privacyUrl = "#",
|
|
2990
|
-
imageUrl,
|
|
2991
|
-
imageAlt = "Product screenshot"
|
|
2992
|
-
}) {
|
|
2993
|
-
const { login, isLoading } = useAuth();
|
|
2994
|
-
const handleLogin = () => {
|
|
2995
|
-
if (onLoginClick) {
|
|
2996
|
-
onLoginClick();
|
|
2997
|
-
} else {
|
|
2998
|
-
login();
|
|
2999
|
-
}
|
|
3000
|
-
};
|
|
3001
|
-
return /* @__PURE__ */ jsxs(
|
|
3054
|
+
function Sidebar({ side, children, className }) {
|
|
3055
|
+
const { leftCollapsed, rightCollapsed } = useSidebar();
|
|
3056
|
+
const collapsed = side === "left" ? leftCollapsed : rightCollapsed;
|
|
3057
|
+
return /* @__PURE__ */ jsx(
|
|
3002
3058
|
"div",
|
|
3003
3059
|
{
|
|
3004
3060
|
className: cn(
|
|
3005
|
-
"flex
|
|
3006
|
-
|
|
3061
|
+
"flex-shrink-0 border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3062
|
+
side === "left" ? "border-r" : "border-l",
|
|
3063
|
+
collapsed ? "w-0 border-r-0 border-l-0 min-w-0" : "",
|
|
3064
|
+
!collapsed && className
|
|
3007
3065
|
),
|
|
3008
|
-
children:
|
|
3009
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col bg-sidebar text-foreground relative overflow-hidden", children: [
|
|
3010
|
-
/* @__PURE__ */ jsx("div", { className: "absolute -top-24 -left-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
3011
|
-
/* @__PURE__ */ jsx("div", { className: "absolute -bottom-24 -right-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
3012
|
-
/* @__PURE__ */ 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__ */ jsxs("div", { className: "max-w-xl mx-auto w-full", children: [
|
|
3013
|
-
/* @__PURE__ */ jsx("h1", { className: "mb-6 text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-foreground", children: title }),
|
|
3014
|
-
/* @__PURE__ */ jsx("p", { className: "mb-12 text-lg text-muted-foreground md:text-xl leading-relaxed", children: description }),
|
|
3015
|
-
imageUrl && /* @__PURE__ */ jsxs("div", { className: "mb-12 relative group", children: [
|
|
3016
|
-
/* @__PURE__ */ 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" }),
|
|
3017
|
-
/* @__PURE__ */ jsx(
|
|
3018
|
-
"img",
|
|
3019
|
-
{
|
|
3020
|
-
src: imageUrl,
|
|
3021
|
-
alt: imageAlt,
|
|
3022
|
-
className: "relative rounded-xl border border-border/50 shadow-2xl transition-transform duration-500 hover:scale-[1.02] w-full"
|
|
3023
|
-
}
|
|
3024
|
-
)
|
|
3025
|
-
] }),
|
|
3026
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2", children: features.map((feature, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3027
|
-
/* @__PURE__ */ jsx("h3", { className: "font-bold text-lg text-foreground", children: feature.title }),
|
|
3028
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: feature.description })
|
|
3029
|
-
] }, i)) })
|
|
3030
|
-
] }) })
|
|
3031
|
-
] }),
|
|
3032
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center justify-center p-8 md:p-12 lg:p-20 bg-background transition-colors duration-300", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-8", children: [
|
|
3033
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-3 text-center md:text-left", children: [
|
|
3034
|
-
/* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: "Get Started" }),
|
|
3035
|
-
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-lg", children: "Sign in to your account to continue" })
|
|
3036
|
-
] }),
|
|
3037
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
3038
|
-
/* @__PURE__ */ jsxs(
|
|
3039
|
-
Button,
|
|
3040
|
-
{
|
|
3041
|
-
size: "lg",
|
|
3042
|
-
variant: "outline",
|
|
3043
|
-
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",
|
|
3044
|
-
onClick: handleLogin,
|
|
3045
|
-
disabled: isLoading,
|
|
3046
|
-
children: [
|
|
3047
|
-
/* @__PURE__ */ jsx(IconBrandGoogle, { className: "size-6" }),
|
|
3048
|
-
isLoading ? "Signing in..." : "Continue with Google"
|
|
3049
|
-
]
|
|
3050
|
-
}
|
|
3051
|
-
),
|
|
3052
|
-
/* @__PURE__ */ jsxs("div", { className: "relative py-4", children: [
|
|
3053
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "w-full border-t border-border" }) }),
|
|
3054
|
-
/* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-3 text-muted-foreground tracking-widest font-medium", children: "Secure access" }) })
|
|
3055
|
-
] })
|
|
3056
|
-
] }),
|
|
3057
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground leading-relaxed text-center md:text-left", children: [
|
|
3058
|
-
"By continuing, you agree to our ",
|
|
3059
|
-
/* @__PURE__ */ jsx("br", { className: "hidden md:block" }),
|
|
3060
|
-
/* @__PURE__ */ jsx(
|
|
3061
|
-
"a",
|
|
3062
|
-
{
|
|
3063
|
-
href: termsUrl,
|
|
3064
|
-
target: "_blank",
|
|
3065
|
-
rel: "noopener noreferrer",
|
|
3066
|
-
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
3067
|
-
children: "Terms of Service"
|
|
3068
|
-
}
|
|
3069
|
-
),
|
|
3070
|
-
" ",
|
|
3071
|
-
"and",
|
|
3072
|
-
" ",
|
|
3073
|
-
/* @__PURE__ */ jsx(
|
|
3074
|
-
"a",
|
|
3075
|
-
{
|
|
3076
|
-
href: privacyUrl,
|
|
3077
|
-
target: "_blank",
|
|
3078
|
-
rel: "noopener noreferrer",
|
|
3079
|
-
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
3080
|
-
children: "Privacy Policy"
|
|
3081
|
-
}
|
|
3082
|
-
),
|
|
3083
|
-
"."
|
|
3084
|
-
] })
|
|
3085
|
-
] }) })
|
|
3086
|
-
]
|
|
3066
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children })
|
|
3087
3067
|
}
|
|
3088
3068
|
);
|
|
3089
3069
|
}
|
|
3090
|
-
function
|
|
3070
|
+
function FullChat({
|
|
3091
3071
|
title = "Chat",
|
|
3092
3072
|
placeholder,
|
|
3093
3073
|
starterPrompts,
|
|
3094
3074
|
options,
|
|
3095
3075
|
className,
|
|
3096
3076
|
headerProps,
|
|
3097
|
-
leftSidebar,
|
|
3098
|
-
rightSidebar,
|
|
3099
|
-
leftSidebarClassName,
|
|
3100
|
-
rightSidebarClassName,
|
|
3101
3077
|
autoFocus = false,
|
|
3102
|
-
defaultSelectedIds
|
|
3103
|
-
showWelcomeScreen = false,
|
|
3104
|
-
welcomeScreenProps
|
|
3078
|
+
defaultSelectedIds
|
|
3105
3079
|
}) {
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
return false;
|
|
3120
|
-
});
|
|
3121
|
-
useEffect(() => {
|
|
3122
|
-
if (isSmallScreen) {
|
|
3123
|
-
setInternalLeftCollapsed(true);
|
|
3124
|
-
setInternalRightCollapsed(true);
|
|
3125
|
-
}
|
|
3126
|
-
}, [isSmallScreen]);
|
|
3127
|
-
const leftCollapsed = internalLeftCollapsed;
|
|
3128
|
-
const rightCollapsed = internalRightCollapsed;
|
|
3129
|
-
const handleLeftToggle = useCallback((collapsed) => {
|
|
3130
|
-
setInternalLeftCollapsed(collapsed);
|
|
3131
|
-
}, []);
|
|
3132
|
-
const handleRightToggle = useCallback((collapsed) => {
|
|
3133
|
-
setInternalRightCollapsed(collapsed);
|
|
3134
|
-
}, []);
|
|
3135
|
-
const contextValue = useMemo(
|
|
3136
|
-
() => ({
|
|
3137
|
-
leftCollapsed,
|
|
3138
|
-
rightCollapsed,
|
|
3139
|
-
setLeftCollapsed: handleLeftToggle,
|
|
3140
|
-
setRightCollapsed: handleRightToggle,
|
|
3141
|
-
leftCollapsible: true,
|
|
3142
|
-
rightCollapsible: true
|
|
3143
|
-
}),
|
|
3144
|
-
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
3145
|
-
);
|
|
3146
|
-
if (showWelcomeScreen && !isAuthenticated && !isLoading) {
|
|
3147
|
-
return /* @__PURE__ */ jsx(WelcomeScreen, { ...welcomeScreenProps });
|
|
3148
|
-
}
|
|
3149
|
-
return /* @__PURE__ */ jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
|
|
3150
|
-
"div",
|
|
3151
|
-
{
|
|
3152
|
-
className: cn("flex flex-col h-full w-full bg-background", className),
|
|
3153
|
-
children: [
|
|
3154
|
-
title && /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
|
|
3155
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
|
|
3156
|
-
leftSidebar && /* @__PURE__ */ jsx(
|
|
3157
|
-
"div",
|
|
3158
|
-
{
|
|
3159
|
-
className: cn(
|
|
3160
|
-
"flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3161
|
-
leftCollapsed ? "w-0 border-r-0 min-w-0" : "",
|
|
3162
|
-
!leftCollapsed && leftSidebarClassName
|
|
3163
|
-
),
|
|
3164
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
|
|
3165
|
-
}
|
|
3166
|
-
),
|
|
3167
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(
|
|
3168
|
-
Thread,
|
|
3169
|
-
{
|
|
3170
|
-
placeholder,
|
|
3171
|
-
starterPrompts,
|
|
3172
|
-
options,
|
|
3173
|
-
autoFocus,
|
|
3174
|
-
defaultSelectedIds
|
|
3175
|
-
}
|
|
3176
|
-
) }),
|
|
3177
|
-
rightSidebar && /* @__PURE__ */ jsx(
|
|
3178
|
-
"div",
|
|
3179
|
-
{
|
|
3180
|
-
className: cn(
|
|
3181
|
-
"flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3182
|
-
rightCollapsed ? "w-0 border-l-0 min-w-0" : "",
|
|
3183
|
-
!rightCollapsed && rightSidebarClassName
|
|
3184
|
-
),
|
|
3185
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
|
|
3186
|
-
}
|
|
3187
|
-
)
|
|
3188
|
-
] })
|
|
3189
|
-
]
|
|
3190
|
-
}
|
|
3191
|
-
) });
|
|
3080
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
|
|
3081
|
+
title && /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
|
|
3082
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden flex relative", children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(
|
|
3083
|
+
Thread,
|
|
3084
|
+
{
|
|
3085
|
+
placeholder,
|
|
3086
|
+
starterPrompts,
|
|
3087
|
+
options,
|
|
3088
|
+
autoFocus,
|
|
3089
|
+
defaultSelectedIds
|
|
3090
|
+
}
|
|
3091
|
+
) }) })
|
|
3092
|
+
] });
|
|
3192
3093
|
}
|
|
3193
3094
|
function SidebarToggle({ side, className }) {
|
|
3194
3095
|
const {
|
|
@@ -3198,13 +3099,14 @@ function SidebarToggle({ side, className }) {
|
|
|
3198
3099
|
setRightCollapsed,
|
|
3199
3100
|
leftCollapsible,
|
|
3200
3101
|
rightCollapsible
|
|
3201
|
-
} =
|
|
3102
|
+
} = useSidebar();
|
|
3202
3103
|
if (side === "left") {
|
|
3203
3104
|
if (!leftCollapsible) return null;
|
|
3204
3105
|
return /* @__PURE__ */ jsx(
|
|
3205
3106
|
Button,
|
|
3206
3107
|
{
|
|
3207
3108
|
variant: "ghost",
|
|
3109
|
+
size: "icon",
|
|
3208
3110
|
onClick: () => setLeftCollapsed(!leftCollapsed),
|
|
3209
3111
|
"aria-label": leftCollapsed ? "Expand left sidebar" : "Collapse left sidebar",
|
|
3210
3112
|
className: cn("", className),
|
|
@@ -3218,6 +3120,7 @@ function SidebarToggle({ side, className }) {
|
|
|
3218
3120
|
Button,
|
|
3219
3121
|
{
|
|
3220
3122
|
variant: "ghost",
|
|
3123
|
+
size: "icon",
|
|
3221
3124
|
onClick: () => setRightCollapsed(!rightCollapsed),
|
|
3222
3125
|
"aria-label": rightCollapsed ? "Expand right sidebar" : "Collapse right sidebar",
|
|
3223
3126
|
className: cn("", className),
|
|
@@ -3227,11 +3130,11 @@ function SidebarToggle({ side, className }) {
|
|
|
3227
3130
|
}
|
|
3228
3131
|
return null;
|
|
3229
3132
|
}
|
|
3230
|
-
var PopoverContext =
|
|
3133
|
+
var PopoverContext = React11.createContext(
|
|
3231
3134
|
void 0
|
|
3232
3135
|
);
|
|
3233
3136
|
function usePopoverContext() {
|
|
3234
|
-
const context =
|
|
3137
|
+
const context = React11.useContext(PopoverContext);
|
|
3235
3138
|
if (!context) {
|
|
3236
3139
|
throw new Error("Popover components must be used within a Popover");
|
|
3237
3140
|
}
|
|
@@ -3243,10 +3146,10 @@ function Popover({
|
|
|
3243
3146
|
open: controlledOpen,
|
|
3244
3147
|
onOpenChange
|
|
3245
3148
|
}) {
|
|
3246
|
-
const [internalOpen, setInternalOpen] =
|
|
3247
|
-
const triggerRef =
|
|
3149
|
+
const [internalOpen, setInternalOpen] = React11.useState(defaultOpen);
|
|
3150
|
+
const triggerRef = React11.useRef(null);
|
|
3248
3151
|
const open = controlledOpen ?? internalOpen;
|
|
3249
|
-
const setOpen =
|
|
3152
|
+
const setOpen = React11.useCallback(
|
|
3250
3153
|
(newOpen) => {
|
|
3251
3154
|
if (controlledOpen === void 0) {
|
|
3252
3155
|
setInternalOpen(newOpen);
|
|
@@ -3255,7 +3158,7 @@ function Popover({
|
|
|
3255
3158
|
},
|
|
3256
3159
|
[controlledOpen, onOpenChange]
|
|
3257
3160
|
);
|
|
3258
|
-
const value =
|
|
3161
|
+
const value = React11.useMemo(
|
|
3259
3162
|
() => ({
|
|
3260
3163
|
open,
|
|
3261
3164
|
setOpen,
|
|
@@ -3265,15 +3168,15 @@ function Popover({
|
|
|
3265
3168
|
);
|
|
3266
3169
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
3267
3170
|
}
|
|
3268
|
-
var PopoverTrigger =
|
|
3171
|
+
var PopoverTrigger = React11.forwardRef(
|
|
3269
3172
|
({ asChild, className, children, ...props }, ref) => {
|
|
3270
3173
|
const { setOpen, triggerRef } = usePopoverContext();
|
|
3271
3174
|
const handleClick = (e) => {
|
|
3272
3175
|
setOpen(true);
|
|
3273
3176
|
props.onClick?.(e);
|
|
3274
3177
|
};
|
|
3275
|
-
if (asChild &&
|
|
3276
|
-
return
|
|
3178
|
+
if (asChild && React11.isValidElement(children)) {
|
|
3179
|
+
return React11.cloneElement(children, {
|
|
3277
3180
|
ref: (node) => {
|
|
3278
3181
|
triggerRef.current = node;
|
|
3279
3182
|
if (typeof children.ref === "function") {
|
|
@@ -3305,7 +3208,7 @@ var PopoverTrigger = React12.forwardRef(
|
|
|
3305
3208
|
}
|
|
3306
3209
|
);
|
|
3307
3210
|
PopoverTrigger.displayName = "PopoverTrigger";
|
|
3308
|
-
var PopoverContent =
|
|
3211
|
+
var PopoverContent = React11.forwardRef(
|
|
3309
3212
|
({
|
|
3310
3213
|
className,
|
|
3311
3214
|
side = "bottom",
|
|
@@ -3316,9 +3219,9 @@ var PopoverContent = React12.forwardRef(
|
|
|
3316
3219
|
...props
|
|
3317
3220
|
}, ref) => {
|
|
3318
3221
|
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
3319
|
-
const [position, setPosition] =
|
|
3320
|
-
const contentRef =
|
|
3321
|
-
|
|
3222
|
+
const [position, setPosition] = React11.useState({ top: 0, left: 0 });
|
|
3223
|
+
const contentRef = React11.useRef(null);
|
|
3224
|
+
React11.useEffect(() => {
|
|
3322
3225
|
if (!open || !triggerRef.current) return;
|
|
3323
3226
|
const updatePosition = () => {
|
|
3324
3227
|
if (!triggerRef.current || !contentRef.current) return;
|
|
@@ -3379,7 +3282,7 @@ var PopoverContent = React12.forwardRef(
|
|
|
3379
3282
|
window.removeEventListener("scroll", updatePosition, true);
|
|
3380
3283
|
};
|
|
3381
3284
|
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
3382
|
-
|
|
3285
|
+
React11.useEffect(() => {
|
|
3383
3286
|
if (!open) return;
|
|
3384
3287
|
const handleClickOutside = (event) => {
|
|
3385
3288
|
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
@@ -3435,7 +3338,7 @@ var ThreadPopover = ({
|
|
|
3435
3338
|
emptyState,
|
|
3436
3339
|
onThreadSelect
|
|
3437
3340
|
}) => {
|
|
3438
|
-
const [isOpen, setIsOpen] =
|
|
3341
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
3439
3342
|
useHotkeys(
|
|
3440
3343
|
"h",
|
|
3441
3344
|
(e) => {
|
|
@@ -3485,12 +3388,12 @@ var ThreadPopover = ({
|
|
|
3485
3388
|
var CreateThreadButton = ({
|
|
3486
3389
|
className,
|
|
3487
3390
|
variant = "ghost",
|
|
3488
|
-
size = "
|
|
3391
|
+
size = "default",
|
|
3489
3392
|
children,
|
|
3490
3393
|
onThreadCreated
|
|
3491
3394
|
}) => {
|
|
3492
3395
|
const { createThread } = useThreads();
|
|
3493
|
-
const [isCreating, setIsCreating] =
|
|
3396
|
+
const [isCreating, setIsCreating] = React11.useState(false);
|
|
3494
3397
|
const handleCreateThread = async () => {
|
|
3495
3398
|
if (isCreating) return;
|
|
3496
3399
|
try {
|
|
@@ -3516,7 +3419,7 @@ var CreateThreadButton = ({
|
|
|
3516
3419
|
// Don't trigger in contenteditable elements
|
|
3517
3420
|
}
|
|
3518
3421
|
);
|
|
3519
|
-
return /* @__PURE__ */
|
|
3422
|
+
return /* @__PURE__ */ jsxs(
|
|
3520
3423
|
Button,
|
|
3521
3424
|
{
|
|
3522
3425
|
variant,
|
|
@@ -3524,7 +3427,10 @@ var CreateThreadButton = ({
|
|
|
3524
3427
|
onClick: handleCreateThread,
|
|
3525
3428
|
disabled: isCreating,
|
|
3526
3429
|
className: cn(className),
|
|
3527
|
-
children:
|
|
3430
|
+
children: [
|
|
3431
|
+
/* @__PURE__ */ jsx(IconPlus, { className: "size-4" }),
|
|
3432
|
+
"New chat"
|
|
3433
|
+
]
|
|
3528
3434
|
}
|
|
3529
3435
|
);
|
|
3530
3436
|
};
|
|
@@ -3616,10 +3522,10 @@ var AccountDialog = ({
|
|
|
3616
3522
|
size
|
|
3617
3523
|
}) => {
|
|
3618
3524
|
const { isLoading, isAuthenticated, user, login, logout } = useAuth();
|
|
3619
|
-
const [open, setOpen] =
|
|
3620
|
-
const [accountInfoOpen, setAccountInfoOpen] =
|
|
3621
|
-
const [error, setError] =
|
|
3622
|
-
const initials =
|
|
3525
|
+
const [open, setOpen] = React11.useState(false);
|
|
3526
|
+
const [accountInfoOpen, setAccountInfoOpen] = React11.useState(false);
|
|
3527
|
+
const [error, setError] = React11.useState(null);
|
|
3528
|
+
const initials = React11.useMemo(() => {
|
|
3623
3529
|
const name = user?.displayName || user?.name;
|
|
3624
3530
|
if (!name) return "";
|
|
3625
3531
|
return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
@@ -3718,17 +3624,14 @@ var AccountDialog = ({
|
|
|
3718
3624
|
] });
|
|
3719
3625
|
}
|
|
3720
3626
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3721
|
-
/* @__PURE__ */
|
|
3627
|
+
/* @__PURE__ */ jsx(
|
|
3722
3628
|
Button,
|
|
3723
3629
|
{
|
|
3724
3630
|
variant,
|
|
3725
3631
|
size,
|
|
3726
3632
|
onClick: () => setOpen(true),
|
|
3727
3633
|
className,
|
|
3728
|
-
children:
|
|
3729
|
-
/* @__PURE__ */ jsx(IconBrandGoogle, { className: "mr-2 size-4" }),
|
|
3730
|
-
"Sign in with Google"
|
|
3731
|
-
]
|
|
3634
|
+
children: "Sign in"
|
|
3732
3635
|
}
|
|
3733
3636
|
),
|
|
3734
3637
|
/* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(AlertDialogContent, { className: "sm:max-w-md", children: [
|
|
@@ -3792,6 +3695,6 @@ function ThemeToggle() {
|
|
|
3792
3695
|
);
|
|
3793
3696
|
}
|
|
3794
3697
|
|
|
3795
|
-
export { AccountDialog, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart,
|
|
3698
|
+
export { AccountDialog, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatHeader, Checkbox, Col, Composer, CreateThreadButton, Divider, Form, FullChat, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyClientProvider, MelonyContext, PopupChat, RadioGroup, Row, Select2 as Select, Sidebar, SidebarContext, SidebarProvider, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, WelcomeScreen, groupEventsToMessages, useAuth, useMelony, useScreenSize, useSidebar, useTheme, useThreads };
|
|
3796
3699
|
//# sourceMappingURL=index.js.map
|
|
3797
3700
|
//# sourceMappingURL=index.js.map
|