gitxp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +17 -0
- package/.output/public/assets/index-BGHvBNtP.js +11 -0
- package/.output/public/assets/routes-DuE8S6pX.js +60 -0
- package/.output/public/assets/styles-D5xbQNYu.css +1 -0
- package/.output/server/_chunks/ssr-renderer.mjs +26 -0
- package/.output/server/_libs/@floating-ui/core+[...].mjs +671 -0
- package/.output/server/_libs/@floating-ui/dom+[...].mjs +649 -0
- package/.output/server/_libs/@floating-ui/react-dom+[...].mjs +856 -0
- package/.output/server/_libs/@radix-ui/react-arrow+[...].mjs +258 -0
- package/.output/server/_libs/@radix-ui/react-dialog+[...].mjs +1862 -0
- package/.output/server/_libs/@radix-ui/react-popper+[...].mjs +320 -0
- package/.output/server/_libs/@radix-ui/react-tooltip+[...].mjs +534 -0
- package/.output/server/_libs/@tanstack/db+[...].mjs +14680 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +14563 -0
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +126 -0
- package/.output/server/_libs/@tanstack/router-core+[...].mjs +3636 -0
- package/.output/server/_libs/class-variance-authority+clsx.mjs +69 -0
- package/.output/server/_libs/cmdk.mjs +504 -0
- package/.output/server/_libs/h3+rou3+srvx.mjs +1361 -0
- package/.output/server/_libs/h3-v2.mjs +285 -0
- package/.output/server/_libs/lucide-react.mjs +158 -0
- package/.output/server/_libs/radix-ui__primitive.mjs +44 -0
- package/.output/server/_libs/radix-ui__react-context.mjs +108 -0
- package/.output/server/_libs/tailwind-merge.mjs +3380 -0
- package/.output/server/_libs/tanstack__history.mjs +384 -0
- package/.output/server/_libs/tanstack__query-core.mjs +2225 -0
- package/.output/server/_libs/tanstack__react-db.mjs +242 -0
- package/.output/server/_libs/tanstack__react-query.mjs +140 -0
- package/.output/server/_libs/ufo.mjs +64 -0
- package/.output/server/_runtime.mjs +35 -0
- package/.output/server/_ssr/empty-plugin-adapters-D9UWiqvJ.mjs +5 -0
- package/.output/server/_ssr/events-BNrmOvgU.mjs +13 -0
- package/.output/server/_ssr/notifications-DUoENv6E.mjs +514 -0
- package/.output/server/_ssr/router-DsUHD4bT.mjs +179 -0
- package/.output/server/_ssr/routes-DIFfr242.mjs +982 -0
- package/.output/server/_ssr/ssr.mjs +1854 -0
- package/.output/server/_ssr/start-5Z2QO8AU.mjs +4 -0
- package/.output/server/_tanstack-start-manifest_v-CrD0YpZr.mjs +20 -0
- package/.output/server/index.mjs +310 -0
- package/.output/server/node_modules/tslib/modules/index.js +70 -0
- package/.output/server/node_modules/tslib/modules/package.json +3 -0
- package/.output/server/node_modules/tslib/package.json +47 -0
- package/.output/server/node_modules/tslib/tslib.js +484 -0
- package/.output/server/package.json +9 -0
- package/LICENSE +21 -0
- package/README.md +325 -0
- package/bin/gitxp.js +85 -0
- package/package.json +92 -0
|
@@ -0,0 +1,982 @@
|
|
|
1
|
+
import { i as __toESM } from "../_runtime.mjs";
|
|
2
|
+
import { u as require_react } from "../_libs/@floating-ui/react-dom+[...].mjs";
|
|
3
|
+
import { _ as useNavigate, g as Link } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
4
|
+
import { i as Slot, l as require_jsx_runtime } from "../_libs/@radix-ui/react-arrow+[...].mjs";
|
|
5
|
+
import { i as useQueryClient, n as useQuery, t as useMutation } from "../_libs/tanstack__react-query.mjs";
|
|
6
|
+
import { a as webUrlFor, c as getSyncStatus, d as retryFailedMutations, f as syncNow, i as views, l as markNotificationDone, n as Route$1, o as getFailedMutations, r as reasonLabel, s as getNotifications, u as markNotificationRead } from "./router-DsUHD4bT.mjs";
|
|
7
|
+
import { l as createCollection } from "../_libs/@tanstack/db+[...].mjs";
|
|
8
|
+
import { t as useLiveQuery } from "../_libs/tanstack__react-db.mjs";
|
|
9
|
+
import { n as clsx, t as cva } from "../_libs/class-variance-authority+clsx.mjs";
|
|
10
|
+
import { n as Search, r as PanelLeft, t as X } from "../_libs/lucide-react.mjs";
|
|
11
|
+
import { a as Root3, i as Provider, n as Content2, o as Trigger, r as Portal, t as Arrow2 } from "../_libs/@radix-ui/react-tooltip+[...].mjs";
|
|
12
|
+
import { a as DialogOverlay$1, i as DialogDescription$1, n as DialogClose, o as DialogPortal$1, r as DialogContent$1, s as DialogTitle$1, t as Dialog } from "../_libs/@radix-ui/react-dialog+[...].mjs";
|
|
13
|
+
import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
14
|
+
import { t as _e } from "../_libs/cmdk.mjs";
|
|
15
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/routes-DIFfr242.js
|
|
16
|
+
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
17
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
18
|
+
var MOBILE_BREAKPOINT = 768;
|
|
19
|
+
function useIsMobile() {
|
|
20
|
+
const [isMobile, setIsMobile] = import_react.useState(void 0);
|
|
21
|
+
import_react.useEffect(() => {
|
|
22
|
+
const mql = window.matchMedia(`(max-width: 767px)`);
|
|
23
|
+
const onChange = () => {
|
|
24
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
25
|
+
};
|
|
26
|
+
mql.addEventListener("change", onChange);
|
|
27
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
28
|
+
return () => mql.removeEventListener("change", onChange);
|
|
29
|
+
}, []);
|
|
30
|
+
return !!isMobile;
|
|
31
|
+
}
|
|
32
|
+
function cn(...inputs) {
|
|
33
|
+
return twMerge(clsx(inputs));
|
|
34
|
+
}
|
|
35
|
+
var buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
36
|
+
variants: {
|
|
37
|
+
variant: {
|
|
38
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
39
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
|
40
|
+
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
41
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
42
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
43
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
44
|
+
},
|
|
45
|
+
size: {
|
|
46
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
47
|
+
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
48
|
+
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
|
49
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
50
|
+
icon: "size-9",
|
|
51
|
+
"icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
52
|
+
"icon-sm": "size-8",
|
|
53
|
+
"icon-lg": "size-10"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
defaultVariants: {
|
|
57
|
+
variant: "default",
|
|
58
|
+
size: "default"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
function Button({ className, variant = "default", size = "default", asChild = false, ...props }) {
|
|
62
|
+
const Comp = asChild ? Slot : "button";
|
|
63
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
|
|
64
|
+
"data-slot": "button",
|
|
65
|
+
"data-variant": variant,
|
|
66
|
+
"data-size": size,
|
|
67
|
+
className: cn(buttonVariants({
|
|
68
|
+
variant,
|
|
69
|
+
size,
|
|
70
|
+
className
|
|
71
|
+
})),
|
|
72
|
+
...props
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function Sheet({ ...props }) {
|
|
76
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog, {
|
|
77
|
+
"data-slot": "sheet",
|
|
78
|
+
...props
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function SheetPortal({ ...props }) {
|
|
82
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortal$1, {
|
|
83
|
+
"data-slot": "sheet-portal",
|
|
84
|
+
...props
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function SheetOverlay({ className, ...props }) {
|
|
88
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay$1, {
|
|
89
|
+
"data-slot": "sheet-overlay",
|
|
90
|
+
className: cn("fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0", className),
|
|
91
|
+
...props
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function SheetContent({ className, children, side = "right", showCloseButton = true, ...props }) {
|
|
95
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SheetPortal, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SheetOverlay, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent$1, {
|
|
96
|
+
"data-slot": "sheet-content",
|
|
97
|
+
className: cn("fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500", side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", className),
|
|
98
|
+
...props,
|
|
99
|
+
children: [children, showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogClose, {
|
|
100
|
+
className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary",
|
|
101
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-4" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
102
|
+
className: "sr-only",
|
|
103
|
+
children: "Close"
|
|
104
|
+
})]
|
|
105
|
+
})]
|
|
106
|
+
})] });
|
|
107
|
+
}
|
|
108
|
+
function SheetHeader({ className, ...props }) {
|
|
109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
110
|
+
"data-slot": "sheet-header",
|
|
111
|
+
className: cn("flex flex-col gap-1.5 p-4", className),
|
|
112
|
+
...props
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function SheetTitle({ className, ...props }) {
|
|
116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle$1, {
|
|
117
|
+
"data-slot": "sheet-title",
|
|
118
|
+
className: cn("font-semibold text-foreground", className),
|
|
119
|
+
...props
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function SheetDescription({ className, ...props }) {
|
|
123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription$1, {
|
|
124
|
+
"data-slot": "sheet-description",
|
|
125
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
126
|
+
...props
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function TooltipProvider({ delayDuration = 0, ...props }) {
|
|
130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, {
|
|
131
|
+
"data-slot": "tooltip-provider",
|
|
132
|
+
delayDuration,
|
|
133
|
+
...props
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function Tooltip$1({ ...props }) {
|
|
137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root3, {
|
|
138
|
+
"data-slot": "tooltip",
|
|
139
|
+
...props
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function TooltipTrigger({ ...props }) {
|
|
143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger, {
|
|
144
|
+
"data-slot": "tooltip-trigger",
|
|
145
|
+
...props
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function TooltipContent({ className, sideOffset = 0, children, ...props }) {
|
|
149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content2, {
|
|
150
|
+
"data-slot": "tooltip-content",
|
|
151
|
+
sideOffset,
|
|
152
|
+
className: cn("z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", className),
|
|
153
|
+
...props,
|
|
154
|
+
children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Arrow2, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })]
|
|
155
|
+
}) });
|
|
156
|
+
}
|
|
157
|
+
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
158
|
+
var SIDEBAR_COOKIE_MAX_AGE = 604800;
|
|
159
|
+
var SIDEBAR_WIDTH = "16rem";
|
|
160
|
+
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
161
|
+
var SIDEBAR_WIDTH_ICON = "3rem";
|
|
162
|
+
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
163
|
+
var SidebarContext = import_react.createContext(null);
|
|
164
|
+
function useSidebar() {
|
|
165
|
+
const context = import_react.useContext(SidebarContext);
|
|
166
|
+
if (!context) throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
167
|
+
return context;
|
|
168
|
+
}
|
|
169
|
+
function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }) {
|
|
170
|
+
const isMobile = useIsMobile();
|
|
171
|
+
const [openMobile, setOpenMobile] = import_react.useState(false);
|
|
172
|
+
const [_open, _setOpen] = import_react.useState(defaultOpen);
|
|
173
|
+
const open = openProp ?? _open;
|
|
174
|
+
const setOpen = import_react.useCallback((value) => {
|
|
175
|
+
const openState = typeof value === "function" ? value(open) : value;
|
|
176
|
+
if (setOpenProp) setOpenProp(openState);
|
|
177
|
+
else _setOpen(openState);
|
|
178
|
+
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
179
|
+
}, [setOpenProp, open]);
|
|
180
|
+
const toggleSidebar = import_react.useCallback(() => {
|
|
181
|
+
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
182
|
+
}, [
|
|
183
|
+
isMobile,
|
|
184
|
+
setOpen,
|
|
185
|
+
setOpenMobile
|
|
186
|
+
]);
|
|
187
|
+
import_react.useEffect(() => {
|
|
188
|
+
const handleKeyDown = (event) => {
|
|
189
|
+
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
190
|
+
event.preventDefault();
|
|
191
|
+
toggleSidebar();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
195
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
196
|
+
}, [toggleSidebar]);
|
|
197
|
+
const state = open ? "expanded" : "collapsed";
|
|
198
|
+
const contextValue = import_react.useMemo(() => ({
|
|
199
|
+
state,
|
|
200
|
+
open,
|
|
201
|
+
setOpen,
|
|
202
|
+
isMobile,
|
|
203
|
+
openMobile,
|
|
204
|
+
setOpenMobile,
|
|
205
|
+
toggleSidebar
|
|
206
|
+
}), [
|
|
207
|
+
state,
|
|
208
|
+
open,
|
|
209
|
+
setOpen,
|
|
210
|
+
isMobile,
|
|
211
|
+
openMobile,
|
|
212
|
+
setOpenMobile,
|
|
213
|
+
toggleSidebar
|
|
214
|
+
]);
|
|
215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarContext.Provider, {
|
|
216
|
+
value: contextValue,
|
|
217
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipProvider, {
|
|
218
|
+
delayDuration: 0,
|
|
219
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
220
|
+
"data-slot": "sidebar-wrapper",
|
|
221
|
+
style: {
|
|
222
|
+
"--sidebar-width": SIDEBAR_WIDTH,
|
|
223
|
+
"--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
|
|
224
|
+
...style
|
|
225
|
+
},
|
|
226
|
+
className: cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className),
|
|
227
|
+
...props,
|
|
228
|
+
children
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, ...props }) {
|
|
234
|
+
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
235
|
+
if (collapsible === "none") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
236
|
+
"data-slot": "sidebar",
|
|
237
|
+
className: cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className),
|
|
238
|
+
...props,
|
|
239
|
+
children
|
|
240
|
+
});
|
|
241
|
+
if (isMobile) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sheet, {
|
|
242
|
+
open: openMobile,
|
|
243
|
+
onOpenChange: setOpenMobile,
|
|
244
|
+
...props,
|
|
245
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SheetContent, {
|
|
246
|
+
"data-sidebar": "sidebar",
|
|
247
|
+
"data-slot": "sidebar",
|
|
248
|
+
"data-mobile": "true",
|
|
249
|
+
className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
|
|
250
|
+
style: { "--sidebar-width": SIDEBAR_WIDTH_MOBILE },
|
|
251
|
+
side,
|
|
252
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SheetHeader, {
|
|
253
|
+
className: "sr-only",
|
|
254
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SheetTitle, { children: "Sidebar" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })]
|
|
255
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
256
|
+
className: "flex h-full w-full flex-col",
|
|
257
|
+
children
|
|
258
|
+
})]
|
|
259
|
+
})
|
|
260
|
+
});
|
|
261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
262
|
+
className: "group peer hidden text-sidebar-foreground md:block",
|
|
263
|
+
"data-state": state,
|
|
264
|
+
"data-collapsible": state === "collapsed" ? collapsible : "",
|
|
265
|
+
"data-variant": variant,
|
|
266
|
+
"data-side": side,
|
|
267
|
+
"data-slot": "sidebar",
|
|
268
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
269
|
+
"data-slot": "sidebar-gap",
|
|
270
|
+
className: cn("relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear", "group-data-[collapsible=offcanvas]:w-0", "group-data-[side=right]:rotate-180", variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
|
|
271
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
272
|
+
"data-slot": "sidebar-container",
|
|
273
|
+
className: cn("fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex", side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]", variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className),
|
|
274
|
+
...props,
|
|
275
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
276
|
+
"data-sidebar": "sidebar",
|
|
277
|
+
"data-slot": "sidebar-inner",
|
|
278
|
+
className: "flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm",
|
|
279
|
+
children
|
|
280
|
+
})
|
|
281
|
+
})]
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function SidebarTrigger({ className, onClick, ...props }) {
|
|
285
|
+
const { toggleSidebar } = useSidebar();
|
|
286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
287
|
+
"data-sidebar": "trigger",
|
|
288
|
+
"data-slot": "sidebar-trigger",
|
|
289
|
+
variant: "ghost",
|
|
290
|
+
size: "icon",
|
|
291
|
+
className: cn("size-7", className),
|
|
292
|
+
onClick: (event) => {
|
|
293
|
+
onClick?.(event);
|
|
294
|
+
toggleSidebar();
|
|
295
|
+
},
|
|
296
|
+
...props,
|
|
297
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PanelLeft, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
298
|
+
className: "sr-only",
|
|
299
|
+
children: "Toggle Sidebar"
|
|
300
|
+
})]
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
function SidebarInset({ className, ...props }) {
|
|
304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", {
|
|
305
|
+
"data-slot": "sidebar-inset",
|
|
306
|
+
className: cn("relative flex w-full flex-1 flex-col bg-background", "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2", className),
|
|
307
|
+
...props
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function SidebarContent({ className, ...props }) {
|
|
311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
312
|
+
"data-slot": "sidebar-content",
|
|
313
|
+
"data-sidebar": "content",
|
|
314
|
+
className: cn("flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", className),
|
|
315
|
+
...props
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function SidebarGroup({ className, ...props }) {
|
|
319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
320
|
+
"data-slot": "sidebar-group",
|
|
321
|
+
"data-sidebar": "group",
|
|
322
|
+
className: cn("relative flex w-full min-w-0 flex-col p-2", className),
|
|
323
|
+
...props
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
function SidebarGroupLabel({ className, asChild = false, ...props }) {
|
|
327
|
+
const Comp = asChild ? Slot : "div";
|
|
328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
|
|
329
|
+
"data-slot": "sidebar-group-label",
|
|
330
|
+
"data-sidebar": "group-label",
|
|
331
|
+
className: cn("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0", className),
|
|
332
|
+
...props
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
function SidebarGroupContent({ className, ...props }) {
|
|
336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
337
|
+
"data-slot": "sidebar-group-content",
|
|
338
|
+
"data-sidebar": "group-content",
|
|
339
|
+
className: cn("w-full text-sm", className),
|
|
340
|
+
...props
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
function SidebarMenu({ className, ...props }) {
|
|
344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
345
|
+
"data-slot": "sidebar-menu",
|
|
346
|
+
"data-sidebar": "menu",
|
|
347
|
+
className: cn("flex w-full min-w-0 flex-col gap-1", className),
|
|
348
|
+
...props
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
function SidebarMenuItem({ className, ...props }) {
|
|
352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
|
|
353
|
+
"data-slot": "sidebar-menu-item",
|
|
354
|
+
"data-sidebar": "menu-item",
|
|
355
|
+
className: cn("group/menu-item relative", className),
|
|
356
|
+
...props
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
var sidebarMenuButtonVariants = cva("peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", {
|
|
360
|
+
variants: {
|
|
361
|
+
variant: {
|
|
362
|
+
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
363
|
+
outline: "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
|
|
364
|
+
},
|
|
365
|
+
size: {
|
|
366
|
+
default: "h-8 text-sm",
|
|
367
|
+
sm: "h-7 text-xs",
|
|
368
|
+
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
defaultVariants: {
|
|
372
|
+
variant: "default",
|
|
373
|
+
size: "default"
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
function SidebarMenuButton({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, ...props }) {
|
|
377
|
+
const Comp = asChild ? Slot : "button";
|
|
378
|
+
const { isMobile, state } = useSidebar();
|
|
379
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
|
|
380
|
+
"data-slot": "sidebar-menu-button",
|
|
381
|
+
"data-sidebar": "menu-button",
|
|
382
|
+
"data-size": size,
|
|
383
|
+
"data-active": isActive,
|
|
384
|
+
className: cn(sidebarMenuButtonVariants({
|
|
385
|
+
variant,
|
|
386
|
+
size
|
|
387
|
+
}), className),
|
|
388
|
+
...props
|
|
389
|
+
});
|
|
390
|
+
if (!tooltip) return button;
|
|
391
|
+
if (typeof tooltip === "string") tooltip = { children: tooltip };
|
|
392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tooltip$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipTrigger, {
|
|
393
|
+
asChild: true,
|
|
394
|
+
children: button
|
|
395
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContent, {
|
|
396
|
+
side: "right",
|
|
397
|
+
align: "center",
|
|
398
|
+
hidden: state !== "collapsed" || isMobile,
|
|
399
|
+
...tooltip
|
|
400
|
+
})] });
|
|
401
|
+
}
|
|
402
|
+
function SidebarMenuBadge({ className, ...props }) {
|
|
403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
404
|
+
"data-slot": "sidebar-menu-badge",
|
|
405
|
+
"data-sidebar": "menu-badge",
|
|
406
|
+
className: cn("pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none", "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground", "peer-data-[size=sm]/menu-button:top-1", "peer-data-[size=default]/menu-button:top-1.5", "peer-data-[size=lg]/menu-button:top-2.5", "group-data-[collapsible=icon]:hidden", className),
|
|
407
|
+
...props
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function AppSidebar({ notifications, activeView }) {
|
|
411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sidebar, {
|
|
412
|
+
collapsible: "icon",
|
|
413
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroup, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupLabel, { children: "gitxp" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenu, { children: views.map((view) => {
|
|
414
|
+
const count = notifications.filter(view.match).length;
|
|
415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuItem, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuButton, {
|
|
416
|
+
asChild: true,
|
|
417
|
+
isActive: view.id === activeView,
|
|
418
|
+
tooltip: view.label,
|
|
419
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
|
|
420
|
+
to: "/",
|
|
421
|
+
search: { view: view.id },
|
|
422
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: view.label })
|
|
423
|
+
})
|
|
424
|
+
}), count > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuBadge, { children: count }) : null] }, view.id);
|
|
425
|
+
}) }) })] }) })
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function Dialog$1({ ...props }) {
|
|
429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog, {
|
|
430
|
+
"data-slot": "dialog",
|
|
431
|
+
...props
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
function DialogPortal({ ...props }) {
|
|
435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortal$1, {
|
|
436
|
+
"data-slot": "dialog-portal",
|
|
437
|
+
...props
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
function DialogOverlay({ className, ...props }) {
|
|
441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay$1, {
|
|
442
|
+
"data-slot": "dialog-overlay",
|
|
443
|
+
className: cn("fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0", className),
|
|
444
|
+
...props
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
function DialogContent({ className, children, showCloseButton = true, ...props }) {
|
|
448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPortal, {
|
|
449
|
+
"data-slot": "dialog-portal",
|
|
450
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent$1, {
|
|
451
|
+
"data-slot": "dialog-content",
|
|
452
|
+
className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg", className),
|
|
453
|
+
...props,
|
|
454
|
+
children: [children, showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogClose, {
|
|
455
|
+
"data-slot": "dialog-close",
|
|
456
|
+
className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
457
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
458
|
+
className: "sr-only",
|
|
459
|
+
children: "Close"
|
|
460
|
+
})]
|
|
461
|
+
})]
|
|
462
|
+
})]
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
function DialogHeader({ className, ...props }) {
|
|
466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
467
|
+
"data-slot": "dialog-header",
|
|
468
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
469
|
+
...props
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
function DialogTitle({ className, ...props }) {
|
|
473
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle$1, {
|
|
474
|
+
"data-slot": "dialog-title",
|
|
475
|
+
className: cn("text-lg leading-none font-semibold", className),
|
|
476
|
+
...props
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
function DialogDescription({ className, ...props }) {
|
|
480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription$1, {
|
|
481
|
+
"data-slot": "dialog-description",
|
|
482
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
483
|
+
...props
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
function Command$1({ className, ...props }) {
|
|
487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e, {
|
|
488
|
+
"data-slot": "command",
|
|
489
|
+
className: cn("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", className),
|
|
490
|
+
...props
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
function CommandDialog({ title = "Command Palette", description = "Search for a command to run...", children, className, showCloseButton = true, ...props }) {
|
|
494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Dialog$1, {
|
|
495
|
+
...props,
|
|
496
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogHeader, {
|
|
497
|
+
className: "sr-only",
|
|
498
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: title }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: description })]
|
|
499
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContent, {
|
|
500
|
+
className: cn("overflow-hidden p-0", className),
|
|
501
|
+
showCloseButton,
|
|
502
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Command$1, {
|
|
503
|
+
className: "**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
|
|
504
|
+
children
|
|
505
|
+
})
|
|
506
|
+
})]
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
function CommandInput({ className, ...props }) {
|
|
510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
511
|
+
"data-slot": "command-input-wrapper",
|
|
512
|
+
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
513
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Search, { className: "size-4 shrink-0 opacity-50" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e.Input, {
|
|
514
|
+
"data-slot": "command-input",
|
|
515
|
+
className: cn("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
516
|
+
...props
|
|
517
|
+
})]
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
function CommandList({ className, ...props }) {
|
|
521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e.List, {
|
|
522
|
+
"data-slot": "command-list",
|
|
523
|
+
className: cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", className),
|
|
524
|
+
...props
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
function CommandEmpty({ ...props }) {
|
|
528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e.Empty, {
|
|
529
|
+
"data-slot": "command-empty",
|
|
530
|
+
className: "py-6 text-center text-sm",
|
|
531
|
+
...props
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
function CommandGroup({ className, ...props }) {
|
|
535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e.Group, {
|
|
536
|
+
"data-slot": "command-group",
|
|
537
|
+
className: cn("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className),
|
|
538
|
+
...props
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
function CommandItem({ className, ...props }) {
|
|
542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(_e.Item, {
|
|
543
|
+
"data-slot": "command-item",
|
|
544
|
+
className: cn("relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
|
|
545
|
+
...props
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
function CommandShortcut({ className, ...props }) {
|
|
549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
550
|
+
"data-slot": "command-shortcut",
|
|
551
|
+
className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
|
|
552
|
+
...props
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
function CommandPalette({ onSelectView, onOpenSelected, onRefresh, onDoneSelected, onReadSelected, canOpenSelected }) {
|
|
556
|
+
const [open, setOpen] = (0, import_react.useState)(false);
|
|
557
|
+
(0, import_react.useEffect)(() => {
|
|
558
|
+
const onKeyDown = (event) => {
|
|
559
|
+
if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
|
|
560
|
+
event.preventDefault();
|
|
561
|
+
setOpen((previous) => !previous);
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
window.addEventListener("keydown", onKeyDown);
|
|
565
|
+
return () => {
|
|
566
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
567
|
+
};
|
|
568
|
+
}, []);
|
|
569
|
+
const run = (action) => {
|
|
570
|
+
setOpen(false);
|
|
571
|
+
action();
|
|
572
|
+
};
|
|
573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandDialog, {
|
|
574
|
+
open,
|
|
575
|
+
onOpenChange: setOpen,
|
|
576
|
+
title: "Commands",
|
|
577
|
+
description: "Jump to a view or act on the selection",
|
|
578
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandInput, { placeholder: "Type a command..." }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandList, { children: [
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandEmpty, { children: "No matching command" }),
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandGroup, {
|
|
581
|
+
heading: "Views",
|
|
582
|
+
children: views.map((view) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandItem, {
|
|
583
|
+
value: `view ${view.label}`,
|
|
584
|
+
onSelect: () => run(() => onSelectView(view.id)),
|
|
585
|
+
children: view.label
|
|
586
|
+
}, view.id))
|
|
587
|
+
}),
|
|
588
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandGroup, {
|
|
589
|
+
heading: "Actions",
|
|
590
|
+
children: [
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandItem, {
|
|
592
|
+
value: "sync refresh",
|
|
593
|
+
onSelect: () => run(onRefresh),
|
|
594
|
+
children: "Sync now"
|
|
595
|
+
}),
|
|
596
|
+
canOpenSelected ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandItem, {
|
|
597
|
+
value: "open github",
|
|
598
|
+
onSelect: () => run(onOpenSelected),
|
|
599
|
+
children: ["Open on GitHub", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandShortcut, { children: "Enter" })]
|
|
600
|
+
}) : null,
|
|
601
|
+
onDoneSelected === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandItem, {
|
|
602
|
+
value: "done archive",
|
|
603
|
+
onSelect: () => run(onDoneSelected),
|
|
604
|
+
children: ["Mark as done", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandShortcut, { children: "e" })]
|
|
605
|
+
}),
|
|
606
|
+
onReadSelected === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CommandItem, {
|
|
607
|
+
value: "read",
|
|
608
|
+
onSelect: () => run(onReadSelected),
|
|
609
|
+
children: ["Mark as read", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandShortcut, { children: "r" })]
|
|
610
|
+
})
|
|
611
|
+
]
|
|
612
|
+
})
|
|
613
|
+
] })]
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
function FailedActions() {
|
|
617
|
+
const queryClient = useQueryClient();
|
|
618
|
+
const failed = useQuery({
|
|
619
|
+
queryKey: ["failed-mutations"],
|
|
620
|
+
queryFn: () => getFailedMutations(),
|
|
621
|
+
refetchInterval: 1e4
|
|
622
|
+
});
|
|
623
|
+
const retry = useMutation({
|
|
624
|
+
mutationFn: () => retryFailedMutations(),
|
|
625
|
+
onSettled: () => queryClient.invalidateQueries({ queryKey: ["failed-mutations"] })
|
|
626
|
+
});
|
|
627
|
+
const rows = failed.data ?? [];
|
|
628
|
+
if (rows.length === 0) return null;
|
|
629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
630
|
+
className: "flex items-center gap-2 border-b bg-destructive/10 px-3 py-2 text-xs",
|
|
631
|
+
children: [
|
|
632
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
633
|
+
className: "text-destructive",
|
|
634
|
+
children: [
|
|
635
|
+
rows.length,
|
|
636
|
+
" action",
|
|
637
|
+
rows.length === 1 ? "" : "s",
|
|
638
|
+
" failed"
|
|
639
|
+
]
|
|
640
|
+
}),
|
|
641
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
642
|
+
className: "truncate text-muted-foreground",
|
|
643
|
+
children: rows[0].lastError
|
|
644
|
+
}),
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
|
|
646
|
+
size: "sm",
|
|
647
|
+
variant: "outline",
|
|
648
|
+
className: "ml-auto h-6 shrink-0 text-xs",
|
|
649
|
+
disabled: retry.isPending,
|
|
650
|
+
onClick: () => retry.mutate(),
|
|
651
|
+
children: retry.isPending ? "Retrying" : "Retry"
|
|
652
|
+
})
|
|
653
|
+
]
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
function NotificationList({ notifications, selectedId, onSelect, onOpen, onDone, onRead, emptyMessage }) {
|
|
657
|
+
const listRef = (0, import_react.useRef)(null);
|
|
658
|
+
const selectedIndex = notifications.findIndex((notification) => notification.thread_id === selectedId);
|
|
659
|
+
(0, import_react.useEffect)(() => {
|
|
660
|
+
listRef.current?.querySelector("[data-selected=\"true\"]")?.scrollIntoView({ block: "nearest" });
|
|
661
|
+
}, [selectedId]);
|
|
662
|
+
const move = (delta) => {
|
|
663
|
+
if (notifications.length === 0) return;
|
|
664
|
+
onSelect(notifications[Math.min(Math.max(selectedIndex === -1 ? 0 : selectedIndex + delta, 0), notifications.length - 1)].thread_id);
|
|
665
|
+
};
|
|
666
|
+
const handleKeyDown = (event) => {
|
|
667
|
+
if (event.key === "ArrowDown" || event.key === "j") {
|
|
668
|
+
event.preventDefault();
|
|
669
|
+
move(1);
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
if (event.key === "ArrowUp" || event.key === "k") {
|
|
673
|
+
event.preventDefault();
|
|
674
|
+
move(-1);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
if (event.key === "Enter") {
|
|
678
|
+
event.preventDefault();
|
|
679
|
+
onOpen();
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if (selectedId === void 0 || notifications.length === 0) return;
|
|
683
|
+
if (event.key === "e") {
|
|
684
|
+
event.preventDefault();
|
|
685
|
+
const next = notifications[Math.min(selectedIndex + 1, notifications.length - 1)];
|
|
686
|
+
onDone(selectedId);
|
|
687
|
+
if (next.thread_id !== selectedId) onSelect(next.thread_id);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
if (event.key === "r") {
|
|
691
|
+
event.preventDefault();
|
|
692
|
+
onRead(selectedId);
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
if (notifications.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
696
|
+
className: "flex h-full items-center justify-center p-8 text-sm text-muted-foreground",
|
|
697
|
+
children: emptyMessage
|
|
698
|
+
});
|
|
699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
700
|
+
ref: listRef,
|
|
701
|
+
tabIndex: 0,
|
|
702
|
+
onKeyDown: handleKeyDown,
|
|
703
|
+
className: "h-full overflow-y-auto outline-none",
|
|
704
|
+
"aria-label": "Notifications",
|
|
705
|
+
children: notifications.map((notification) => {
|
|
706
|
+
const selected = notification.thread_id === selectedId;
|
|
707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
|
|
708
|
+
"data-selected": selected,
|
|
709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
710
|
+
type: "button",
|
|
711
|
+
onClick: () => onSelect(notification.thread_id),
|
|
712
|
+
onDoubleClick: onOpen,
|
|
713
|
+
className: cn("flex w-full flex-col gap-1 border-l-2 px-3 py-2 text-left", selected ? "border-l-primary bg-accent" : "border-l-transparent hover:bg-accent/50"),
|
|
714
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
715
|
+
className: "flex items-baseline gap-2",
|
|
716
|
+
children: [
|
|
717
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", notification.unread === 1 ? "bg-primary" : "bg-transparent") }),
|
|
718
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
719
|
+
className: "truncate font-mono text-xs text-muted-foreground",
|
|
720
|
+
children: notification.repo_full_name
|
|
721
|
+
}),
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
723
|
+
className: "ml-auto shrink-0 text-xs text-muted-foreground",
|
|
724
|
+
children: reasonLabel(notification.reason)
|
|
725
|
+
})
|
|
726
|
+
]
|
|
727
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
728
|
+
className: cn("line-clamp-2 pl-3.5 text-sm", notification.unread === 1 ? "font-medium" : "text-muted-foreground"),
|
|
729
|
+
children: notification.subject_title
|
|
730
|
+
})]
|
|
731
|
+
})
|
|
732
|
+
}, notification.thread_id);
|
|
733
|
+
})
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
var badgeVariants = cva("inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3", {
|
|
737
|
+
variants: { variant: {
|
|
738
|
+
default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
739
|
+
secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
740
|
+
destructive: "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
|
|
741
|
+
outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
742
|
+
ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
743
|
+
link: "text-primary underline-offset-4 [a&]:hover:underline"
|
|
744
|
+
} },
|
|
745
|
+
defaultVariants: { variant: "default" }
|
|
746
|
+
});
|
|
747
|
+
function Badge({ className, variant = "default", asChild = false, ...props }) {
|
|
748
|
+
const Comp = asChild ? Slot : "span";
|
|
749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
|
|
750
|
+
"data-slot": "badge",
|
|
751
|
+
"data-variant": variant,
|
|
752
|
+
className: cn(badgeVariants({ variant }), className),
|
|
753
|
+
...props
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
function NotificationPreview({ notification }) {
|
|
757
|
+
if (notification === void 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
758
|
+
className: "flex h-full items-center justify-center p-8 text-sm text-muted-foreground",
|
|
759
|
+
children: "Select a notification"
|
|
760
|
+
});
|
|
761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
762
|
+
className: "flex h-full flex-col gap-4 overflow-y-auto p-6",
|
|
763
|
+
children: [
|
|
764
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
765
|
+
className: "flex flex-col gap-2",
|
|
766
|
+
children: [
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
768
|
+
className: "font-mono text-xs text-muted-foreground",
|
|
769
|
+
children: notification.repo_full_name
|
|
770
|
+
}),
|
|
771
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
|
|
772
|
+
className: "text-lg font-medium",
|
|
773
|
+
children: notification.subject_title
|
|
774
|
+
}),
|
|
775
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
776
|
+
className: "flex flex-wrap items-center gap-2",
|
|
777
|
+
children: [
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
779
|
+
variant: "secondary",
|
|
780
|
+
children: reasonLabel(notification.reason)
|
|
781
|
+
}),
|
|
782
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
783
|
+
variant: "outline",
|
|
784
|
+
children: notification.subject_type
|
|
785
|
+
}),
|
|
786
|
+
notification.unread === 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, { children: "Unread" }) : null
|
|
787
|
+
]
|
|
788
|
+
})
|
|
789
|
+
]
|
|
790
|
+
}),
|
|
791
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
|
|
792
|
+
className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-sm",
|
|
793
|
+
children: [
|
|
794
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
795
|
+
className: "text-muted-foreground",
|
|
796
|
+
children: "Updated"
|
|
797
|
+
}),
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: new Date(notification.updated_at).toLocaleString() }),
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
800
|
+
className: "text-muted-foreground",
|
|
801
|
+
children: "Last read"
|
|
802
|
+
}),
|
|
803
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: notification.last_read_at === null ? "Never" : new Date(notification.last_read_at).toLocaleString() })
|
|
804
|
+
]
|
|
805
|
+
}),
|
|
806
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
|
|
807
|
+
asChild: true,
|
|
808
|
+
variant: "outline",
|
|
809
|
+
size: "sm",
|
|
810
|
+
className: "self-start",
|
|
811
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
812
|
+
href: webUrlFor(notification),
|
|
813
|
+
target: "_blank",
|
|
814
|
+
rel: "noreferrer",
|
|
815
|
+
children: "Open on GitHub"
|
|
816
|
+
})
|
|
817
|
+
}),
|
|
818
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
819
|
+
className: "mt-auto text-xs text-muted-foreground",
|
|
820
|
+
children: "The pull request itself, its diff and its checks land here next."
|
|
821
|
+
})
|
|
822
|
+
]
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
var notificationsCollection = createCollection({
|
|
826
|
+
id: "notifications",
|
|
827
|
+
getKey: (row) => row.thread_id,
|
|
828
|
+
sync: {
|
|
829
|
+
rowUpdateMode: "full",
|
|
830
|
+
sync: ({ begin, write, commit, markReady, markError, truncate, collection }) => {
|
|
831
|
+
let cancelled = false;
|
|
832
|
+
let inFlight;
|
|
833
|
+
let queued = false;
|
|
834
|
+
const apply = async () => {
|
|
835
|
+
const rows = await getNotifications();
|
|
836
|
+
if (cancelled) return;
|
|
837
|
+
begin();
|
|
838
|
+
truncate();
|
|
839
|
+
for (const row of rows) write({
|
|
840
|
+
type: "insert",
|
|
841
|
+
value: row
|
|
842
|
+
});
|
|
843
|
+
commit();
|
|
844
|
+
markReady();
|
|
845
|
+
};
|
|
846
|
+
const load = () => {
|
|
847
|
+
if (inFlight) {
|
|
848
|
+
queued = true;
|
|
849
|
+
return inFlight;
|
|
850
|
+
}
|
|
851
|
+
inFlight = apply().catch((error) => {
|
|
852
|
+
if (cancelled) return;
|
|
853
|
+
console.error("notifications sync failed", error);
|
|
854
|
+
if (collection.status === "loading") markError(error);
|
|
855
|
+
}).finally(() => {
|
|
856
|
+
inFlight = void 0;
|
|
857
|
+
if (queued && !cancelled) {
|
|
858
|
+
queued = false;
|
|
859
|
+
load();
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
return inFlight;
|
|
863
|
+
};
|
|
864
|
+
if (typeof window === "undefined") return () => {
|
|
865
|
+
cancelled = true;
|
|
866
|
+
};
|
|
867
|
+
const source = new EventSource("/api/events");
|
|
868
|
+
source.addEventListener("change", () => {
|
|
869
|
+
load();
|
|
870
|
+
});
|
|
871
|
+
load();
|
|
872
|
+
return () => {
|
|
873
|
+
cancelled = true;
|
|
874
|
+
source.close();
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
onUpdate: async ({ transaction }) => {
|
|
879
|
+
for (const mutation of transaction.mutations) if (mutation.changes.unread === 0) await markNotificationRead({ data: mutation.key });
|
|
880
|
+
},
|
|
881
|
+
onDelete: async ({ transaction }) => {
|
|
882
|
+
for (const mutation of transaction.mutations) await markNotificationDone({ data: mutation.key });
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
function Inbox() {
|
|
886
|
+
const { view, thread } = Route$1.useSearch();
|
|
887
|
+
const navigate = useNavigate({ from: Route$1.fullPath });
|
|
888
|
+
const initial = Route$1.useLoaderData();
|
|
889
|
+
const { data, isLoading } = useLiveQuery((q) => q.from({ notification: notificationsCollection }));
|
|
890
|
+
const rows = isLoading ? initial : data;
|
|
891
|
+
const firstSyncPending = useQuery({
|
|
892
|
+
queryKey: ["sync-status"],
|
|
893
|
+
queryFn: () => getSyncStatus(),
|
|
894
|
+
refetchInterval: (query) => query.state.data?.hasSynced === true ? false : 2e3
|
|
895
|
+
}).data?.hasSynced !== true;
|
|
896
|
+
const all = (0, import_react.useMemo)(() => [...rows].sort((a, b) => b.updated_at.localeCompare(a.updated_at)), [rows]);
|
|
897
|
+
const active = views.find((candidate) => candidate.id === view) ?? views[0];
|
|
898
|
+
const visible = (0, import_react.useMemo)(() => all.filter(active.match), [all, active]);
|
|
899
|
+
const selected = visible.find((notification) => notification.thread_id === thread);
|
|
900
|
+
const select = (threadId) => {
|
|
901
|
+
navigate({
|
|
902
|
+
search: (previous) => ({
|
|
903
|
+
...previous,
|
|
904
|
+
thread: threadId
|
|
905
|
+
}),
|
|
906
|
+
replace: true
|
|
907
|
+
});
|
|
908
|
+
};
|
|
909
|
+
const selectView = (next) => {
|
|
910
|
+
navigate({
|
|
911
|
+
search: { view: next },
|
|
912
|
+
replace: true
|
|
913
|
+
});
|
|
914
|
+
};
|
|
915
|
+
const markDone = (threadId) => {
|
|
916
|
+
notificationsCollection.delete(threadId);
|
|
917
|
+
};
|
|
918
|
+
const markRead = (threadId) => {
|
|
919
|
+
notificationsCollection.update(threadId, (draft) => {
|
|
920
|
+
draft.unread = 0;
|
|
921
|
+
});
|
|
922
|
+
};
|
|
923
|
+
const openSelected = () => {
|
|
924
|
+
if (selected === void 0) return;
|
|
925
|
+
window.open(webUrlFor(selected), "_blank", "noreferrer");
|
|
926
|
+
};
|
|
927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarProvider, { children: [
|
|
928
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppSidebar, {
|
|
929
|
+
notifications: all,
|
|
930
|
+
activeView: active.id
|
|
931
|
+
}),
|
|
932
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarInset, {
|
|
933
|
+
className: "h-svh overflow-hidden",
|
|
934
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
935
|
+
className: "grid h-full grid-cols-[minmax(280px,380px)_1fr]",
|
|
936
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
937
|
+
className: "flex min-h-0 flex-col border-r",
|
|
938
|
+
children: [
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
|
|
940
|
+
className: "flex items-center gap-2 border-b px-3 py-2",
|
|
941
|
+
children: [
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarTrigger, {}),
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
944
|
+
className: "text-sm font-medium",
|
|
945
|
+
children: active.label
|
|
946
|
+
}),
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
948
|
+
className: "text-xs text-muted-foreground",
|
|
949
|
+
children: firstSyncPending && all.length === 0 ? "syncing" : visible.length
|
|
950
|
+
}),
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("kbd", {
|
|
952
|
+
className: "ml-auto rounded border px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground",
|
|
953
|
+
children: "⌘K"
|
|
954
|
+
})
|
|
955
|
+
]
|
|
956
|
+
}),
|
|
957
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FailedActions, {}),
|
|
958
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotificationList, {
|
|
959
|
+
notifications: visible,
|
|
960
|
+
selectedId: selected?.thread_id,
|
|
961
|
+
onSelect: select,
|
|
962
|
+
onOpen: openSelected,
|
|
963
|
+
onDone: markDone,
|
|
964
|
+
onRead: markRead,
|
|
965
|
+
emptyMessage: firstSyncPending && all.length === 0 ? "Fetching your notifications from GitHub..." : "Nothing here"
|
|
966
|
+
})
|
|
967
|
+
]
|
|
968
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotificationPreview, { notification: selected })]
|
|
969
|
+
})
|
|
970
|
+
}),
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandPalette, {
|
|
972
|
+
onSelectView: selectView,
|
|
973
|
+
onOpenSelected: openSelected,
|
|
974
|
+
onRefresh: () => void syncNow(),
|
|
975
|
+
onDoneSelected: selected === void 0 ? void 0 : () => markDone(selected.thread_id),
|
|
976
|
+
onReadSelected: selected === void 0 ? void 0 : () => markRead(selected.thread_id),
|
|
977
|
+
canOpenSelected: selected !== void 0
|
|
978
|
+
})
|
|
979
|
+
] });
|
|
980
|
+
}
|
|
981
|
+
//#endregion
|
|
982
|
+
export { Inbox as component };
|