create-tauri-ui 1.0.4 → 1.0.5
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/assets/debug-panel/debug-panel.tsx.tmpl +293 -203
- package/dist/index.mjs +84 -79
- package/package.json +1 -1
|
@@ -14,6 +14,7 @@ import { attachConsole } from "@tauri-apps/plugin-log"
|
|
|
14
14
|
import {
|
|
15
15
|
AlertTriangleIcon,
|
|
16
16
|
CopyIcon,
|
|
17
|
+
EllipsisIcon,
|
|
17
18
|
ExternalLinkIcon,
|
|
18
19
|
PinIcon,
|
|
19
20
|
RefreshCwIcon,
|
|
@@ -24,13 +25,17 @@ import {
|
|
|
24
25
|
import { Badge } from "__ALIAS_PREFIX__components/ui/badge"
|
|
25
26
|
import { Button } from "__ALIAS_PREFIX__components/ui/button"
|
|
26
27
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
DropdownMenu,
|
|
29
|
+
DropdownMenuContent,
|
|
30
|
+
DropdownMenuItem,
|
|
31
|
+
DropdownMenuLabel,
|
|
32
|
+
DropdownMenuRadioGroup,
|
|
33
|
+
DropdownMenuRadioItem,
|
|
34
|
+
DropdownMenuSeparator,
|
|
35
|
+
DropdownMenuShortcut,
|
|
36
|
+
DropdownMenuTrigger,
|
|
37
|
+
} from "__ALIAS_PREFIX__components/ui/dropdown-menu"
|
|
32
38
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "__ALIAS_PREFIX__components/ui/tabs"
|
|
33
|
-
import { ToggleGroup, ToggleGroupItem } from "__ALIAS_PREFIX__components/ui/toggle-group"
|
|
34
39
|
import {
|
|
35
40
|
DEBUG_EVENT_NAME,
|
|
36
41
|
type DebugEvent,
|
|
@@ -104,7 +109,54 @@ const DEBUG_PANEL_SIDE_KEY = "ctui-debug-panel-side"
|
|
|
104
109
|
const DEBUG_PANEL_TAB_KEY = "ctui-debug-panel-tab"
|
|
105
110
|
const DEBUG_PANEL_ATTACH_KEY = "ctui-debug-panel-attach"
|
|
106
111
|
const SIDE_PANEL_WIDTH = 480
|
|
107
|
-
const BOTTOM_PANEL_HEIGHT =
|
|
112
|
+
const BOTTOM_PANEL_HEIGHT = 360
|
|
113
|
+
const DEBUG_PANEL_THEME_STYLE_LIGHT = {
|
|
114
|
+
colorScheme: "light",
|
|
115
|
+
"--background": "oklch(0.955 0.006 250)",
|
|
116
|
+
"--foreground": "oklch(0.255 0.015 250)",
|
|
117
|
+
"--card": "oklch(0.985 0.004 250)",
|
|
118
|
+
"--card-foreground": "oklch(0.255 0.015 250)",
|
|
119
|
+
"--popover": "oklch(0.955 0.006 250)",
|
|
120
|
+
"--popover-foreground": "oklch(0.255 0.015 250)",
|
|
121
|
+
"--primary": "oklch(0.56 0.1 235)",
|
|
122
|
+
"--primary-foreground": "oklch(0.985 0 0)",
|
|
123
|
+
"--secondary": "oklch(0.925 0.008 250)",
|
|
124
|
+
"--secondary-foreground": "oklch(0.31 0.015 250)",
|
|
125
|
+
"--muted": "oklch(0.935 0.006 250)",
|
|
126
|
+
"--muted-foreground": "oklch(0.52 0.014 250)",
|
|
127
|
+
"--accent": "oklch(0.925 0.01 250)",
|
|
128
|
+
"--accent-foreground": "oklch(0.255 0.015 250)",
|
|
129
|
+
"--destructive": "oklch(0.63 0.20 24)",
|
|
130
|
+
"--destructive-foreground": "oklch(0.985 0 0)",
|
|
131
|
+
"--border": "oklch(0.86 0.008 250)",
|
|
132
|
+
"--input": "oklch(0.86 0.008 250)",
|
|
133
|
+
"--ring": "oklch(0.62 0.08 235)",
|
|
134
|
+
"--radius": "0.5rem",
|
|
135
|
+
} as React.CSSProperties
|
|
136
|
+
|
|
137
|
+
const DEBUG_PANEL_THEME_STYLE_DARK = {
|
|
138
|
+
colorScheme: "dark",
|
|
139
|
+
"--background": "oklch(0.205 0.012 250)",
|
|
140
|
+
"--foreground": "oklch(0.92 0.008 250)",
|
|
141
|
+
"--card": "oklch(0.235 0.012 250)",
|
|
142
|
+
"--card-foreground": "oklch(0.92 0.008 250)",
|
|
143
|
+
"--popover": "oklch(0.205 0.012 250)",
|
|
144
|
+
"--popover-foreground": "oklch(0.92 0.008 250)",
|
|
145
|
+
"--primary": "oklch(0.74 0.085 230)",
|
|
146
|
+
"--primary-foreground": "oklch(0.19 0.01 250)",
|
|
147
|
+
"--secondary": "oklch(0.28 0.012 250)",
|
|
148
|
+
"--secondary-foreground": "oklch(0.9 0.008 250)",
|
|
149
|
+
"--muted": "oklch(0.255 0.012 250)",
|
|
150
|
+
"--muted-foreground": "oklch(0.7 0.012 250)",
|
|
151
|
+
"--accent": "oklch(0.28 0.012 250)",
|
|
152
|
+
"--accent-foreground": "oklch(0.92 0.008 250)",
|
|
153
|
+
"--destructive": "oklch(0.66 0.19 24)",
|
|
154
|
+
"--destructive-foreground": "oklch(0.98 0 0)",
|
|
155
|
+
"--border": "oklch(0.36 0.01 250)",
|
|
156
|
+
"--input": "oklch(0.36 0.01 250)",
|
|
157
|
+
"--ring": "oklch(0.68 0.07 230)",
|
|
158
|
+
"--radius": "0.5rem",
|
|
159
|
+
} as React.CSSProperties
|
|
108
160
|
|
|
109
161
|
function isDebugPanelSide(value: string): value is DebugPanelSide {
|
|
110
162
|
return value === "left" || value === "right" || value === "bottom"
|
|
@@ -176,17 +228,17 @@ function parsePluginLogMessage(message: string) {
|
|
|
176
228
|
function getLogLevelClasses(level: string) {
|
|
177
229
|
switch (level) {
|
|
178
230
|
case "error":
|
|
179
|
-
return "border-destructive/
|
|
231
|
+
return "border-destructive/25 bg-destructive/15 text-destructive"
|
|
180
232
|
case "warn":
|
|
181
|
-
return "border-amber-500/
|
|
233
|
+
return "border-amber-500/25 bg-amber-500/15 text-amber-600 dark:text-amber-400"
|
|
182
234
|
case "info":
|
|
183
|
-
return "border-emerald-500/
|
|
235
|
+
return "border-emerald-500/25 bg-emerald-500/15 text-emerald-600 dark:text-emerald-400"
|
|
184
236
|
case "debug":
|
|
185
|
-
return "border-sky-500/
|
|
237
|
+
return "border-sky-500/25 bg-sky-500/15 text-sky-600 dark:text-sky-400"
|
|
186
238
|
case "trace":
|
|
187
|
-
return "border-border bg-muted
|
|
239
|
+
return "border-border/25 bg-muted text-muted-foreground"
|
|
188
240
|
default:
|
|
189
|
-
return "border-border bg-muted
|
|
241
|
+
return "border-border/25 bg-muted text-foreground"
|
|
190
242
|
}
|
|
191
243
|
}
|
|
192
244
|
|
|
@@ -205,20 +257,33 @@ function DebugSection({
|
|
|
205
257
|
title,
|
|
206
258
|
description,
|
|
207
259
|
children,
|
|
260
|
+
className,
|
|
261
|
+
bodyClassName,
|
|
208
262
|
}: {
|
|
209
263
|
title: string
|
|
210
264
|
description?: string
|
|
211
265
|
children: React.ReactNode
|
|
266
|
+
className?: string
|
|
267
|
+
bodyClassName?: string
|
|
212
268
|
}) {
|
|
213
269
|
return (
|
|
214
|
-
<section
|
|
215
|
-
|
|
216
|
-
|
|
270
|
+
<section
|
|
271
|
+
className={cn(
|
|
272
|
+
"min-h-0 overflow-hidden rounded-lg border border-border/25 bg-card",
|
|
273
|
+
className
|
|
274
|
+
)}
|
|
275
|
+
>
|
|
276
|
+
<div className="border-b border-border/20 px-3 py-2">
|
|
277
|
+
<h3 className="text-[12px] font-semibold tracking-tight text-foreground">
|
|
278
|
+
{title}
|
|
279
|
+
</h3>
|
|
217
280
|
{description ? (
|
|
218
|
-
<p className="text-
|
|
281
|
+
<p className="mt-0.5 text-[11px] leading-4 text-muted-foreground">
|
|
282
|
+
{description}
|
|
283
|
+
</p>
|
|
219
284
|
) : null}
|
|
220
285
|
</div>
|
|
221
|
-
{children}
|
|
286
|
+
<div className={cn("min-h-0 p-3", bodyClassName)}>{children}</div>
|
|
222
287
|
</section>
|
|
223
288
|
)
|
|
224
289
|
}
|
|
@@ -229,13 +294,16 @@ function KeyValueGrid({
|
|
|
229
294
|
entries: Array<[label: string, value: React.ReactNode]>
|
|
230
295
|
}) {
|
|
231
296
|
return (
|
|
232
|
-
<dl className="grid
|
|
233
|
-
{entries.map(([label, value]) => (
|
|
297
|
+
<dl className="grid text-[11px] leading-5">
|
|
298
|
+
{entries.map(([label, value], index) => (
|
|
234
299
|
<div
|
|
235
300
|
key={label}
|
|
236
|
-
className=
|
|
301
|
+
className={cn(
|
|
302
|
+
"grid grid-cols-[92px_minmax(0,1fr)] items-start gap-3 py-1",
|
|
303
|
+
index > 0 && "border-t border-border/20"
|
|
304
|
+
)}
|
|
237
305
|
>
|
|
238
|
-
<dt className="text-muted-foreground">{label}</dt>
|
|
306
|
+
<dt className="text-muted-foreground/90">{label}</dt>
|
|
239
307
|
<dd className="font-mono break-all text-foreground">{value}</dd>
|
|
240
308
|
</div>
|
|
241
309
|
))}
|
|
@@ -391,14 +459,22 @@ export function DebugPanel() {
|
|
|
391
459
|
updateThemeInfo()
|
|
392
460
|
|
|
393
461
|
const mediaQuery = window.matchMedia(COLOR_SCHEME_QUERY)
|
|
462
|
+
const observer = new MutationObserver(() => {
|
|
463
|
+
updateThemeInfo()
|
|
464
|
+
})
|
|
394
465
|
const handleMediaChange = () => {
|
|
395
466
|
updateThemeInfo()
|
|
396
467
|
}
|
|
397
468
|
|
|
398
469
|
mediaQuery.addEventListener("change", handleMediaChange)
|
|
470
|
+
observer.observe(document.documentElement, {
|
|
471
|
+
attributes: true,
|
|
472
|
+
attributeFilter: ["class"],
|
|
473
|
+
})
|
|
399
474
|
|
|
400
475
|
return () => {
|
|
401
476
|
mediaQuery.removeEventListener("change", handleMediaChange)
|
|
477
|
+
observer.disconnect()
|
|
402
478
|
}
|
|
403
479
|
}, [])
|
|
404
480
|
|
|
@@ -794,7 +870,7 @@ export function DebugPanel() {
|
|
|
794
870
|
}, [])
|
|
795
871
|
|
|
796
872
|
React.useEffect(() => {
|
|
797
|
-
const mainElement = document.querySelector("
|
|
873
|
+
const mainElement = document.querySelector("[data-ui-scroll-container]")
|
|
798
874
|
|
|
799
875
|
if (!(mainElement instanceof HTMLElement)) {
|
|
800
876
|
return
|
|
@@ -854,89 +930,93 @@ export function DebugPanel() {
|
|
|
854
930
|
}, 1200)
|
|
855
931
|
}
|
|
856
932
|
|
|
933
|
+
const isBottomDock = panelSide === "bottom"
|
|
934
|
+
const runtimeCount =
|
|
935
|
+
invokeLogs.length + externalLinks.length + runtimeEvents.length + logEntries.length
|
|
936
|
+
const overviewLayoutClassName = isBottomDock
|
|
937
|
+
? "grid min-h-full content-start gap-3 pr-1 xl:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)_minmax(0,0.9fr)]"
|
|
938
|
+
: "h-full space-y-3 overflow-y-auto pr-1"
|
|
939
|
+
const runtimeLayoutClassName = isBottomDock
|
|
940
|
+
? "grid min-h-full content-start gap-3 pr-1 xl:grid-cols-2"
|
|
941
|
+
: "h-full space-y-3 overflow-y-auto pr-1"
|
|
942
|
+
const systemLayoutClassName = isBottomDock
|
|
943
|
+
? "grid min-h-full content-start gap-3 pr-1 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]"
|
|
944
|
+
: "h-full space-y-3 overflow-y-auto pr-1"
|
|
945
|
+
const debugPanelThemeStyle =
|
|
946
|
+
themeInfo.current === "light"
|
|
947
|
+
? DEBUG_PANEL_THEME_STYLE_LIGHT
|
|
948
|
+
: DEBUG_PANEL_THEME_STYLE_DARK
|
|
949
|
+
|
|
857
950
|
const panelContent = (
|
|
858
951
|
<>
|
|
859
|
-
<
|
|
860
|
-
<div className="flex items-
|
|
861
|
-
<div className="
|
|
862
|
-
|
|
863
|
-
<
|
|
864
|
-
) : null}
|
|
865
|
-
<h2 className="flex items-center gap-2 text-base font-medium text-foreground">
|
|
866
|
-
<TerminalSquareIcon className="size-4" />
|
|
952
|
+
<div className="border-b px-3 py-2">
|
|
953
|
+
<div className="flex items-center justify-between gap-3">
|
|
954
|
+
<div className="min-w-0">
|
|
955
|
+
<h2 className="flex items-center gap-2 text-[13px] font-semibold tracking-tight text-foreground">
|
|
956
|
+
<TerminalSquareIcon className="size-3.5" />
|
|
867
957
|
Development Debug Panel
|
|
868
958
|
</h2>
|
|
869
959
|
</div>
|
|
870
|
-
<div className="flex items-center gap-
|
|
871
|
-
<div className="inline-flex items-center rounded-md border bg-muted/40 px-2 py-1 text-xs">
|
|
872
|
-
<span
|
|
873
|
-
className={cn(
|
|
874
|
-
"font-medium transition-colors",
|
|
875
|
-
tauriReady ? "text-foreground" : "text-muted-foreground"
|
|
876
|
-
)}
|
|
877
|
-
>
|
|
878
|
-
Tauri
|
|
879
|
-
</span>
|
|
880
|
-
<span className="px-1 text-muted-foreground">/</span>
|
|
881
|
-
<span
|
|
882
|
-
className={cn(
|
|
883
|
-
"font-medium transition-colors",
|
|
884
|
-
tauriReady ? "text-muted-foreground" : "text-foreground"
|
|
885
|
-
)}
|
|
886
|
-
>
|
|
887
|
-
Web
|
|
888
|
-
</span>
|
|
889
|
-
</div>
|
|
890
|
-
<Button
|
|
891
|
-
variant="ghost"
|
|
892
|
-
size="icon-sm"
|
|
893
|
-
onClick={() => setOpen(false)}
|
|
894
|
-
aria-label="Close debug panel"
|
|
895
|
-
>
|
|
896
|
-
<XIcon className="size-4" />
|
|
897
|
-
</Button>
|
|
898
|
-
</div>
|
|
899
|
-
</div>
|
|
900
|
-
<div className="flex flex-wrap items-center justify-between gap-3 text-xs text-muted-foreground">
|
|
901
|
-
<div className="flex items-center gap-2">
|
|
902
|
-
<span className="rounded-md border px-1.5 py-0.5 font-mono">Cmd/Ctrl + D</span>
|
|
903
|
-
<span>toggle panel</span>
|
|
904
|
-
</div>
|
|
905
|
-
<div className="flex items-center gap-2">
|
|
960
|
+
<div className="flex items-center gap-1.5">
|
|
906
961
|
<Button
|
|
907
962
|
variant={attached ? "secondary" : "outline"}
|
|
908
963
|
size="icon-sm"
|
|
964
|
+
className="size-7"
|
|
909
965
|
onClick={() => setAttached((current) => !current)}
|
|
910
966
|
aria-pressed={attached}
|
|
911
967
|
aria-label={attached ? "Detach debug panel" : "Attach debug panel"}
|
|
912
968
|
title={attached ? "Detach debug panel" : "Attach debug panel"}
|
|
913
969
|
>
|
|
914
|
-
<PinIcon className="size-
|
|
970
|
+
<PinIcon className="size-3.5" />
|
|
915
971
|
</Button>
|
|
916
|
-
<
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
972
|
+
<DropdownMenu>
|
|
973
|
+
<DropdownMenuTrigger asChild>
|
|
974
|
+
<Button variant="ghost" size="icon-sm" className="size-7" aria-label="Debug panel options">
|
|
975
|
+
<EllipsisIcon className="size-3.5" />
|
|
976
|
+
</Button>
|
|
977
|
+
</DropdownMenuTrigger>
|
|
978
|
+
<DropdownMenuContent align="end" className="w-52">
|
|
979
|
+
<DropdownMenuItem onClick={() => void handleCopySnapshot()}>
|
|
980
|
+
<CopyIcon className="size-3.5" />
|
|
981
|
+
{copied ? "Copied snapshot" : "Copy snapshot"}
|
|
982
|
+
</DropdownMenuItem>
|
|
983
|
+
<DropdownMenuItem onClick={() => window.location.reload()}>
|
|
984
|
+
<RefreshCwIcon className="size-3.5" />
|
|
985
|
+
Reload app
|
|
986
|
+
</DropdownMenuItem>
|
|
987
|
+
<DropdownMenuSeparator />
|
|
988
|
+
<DropdownMenuLabel>Dock</DropdownMenuLabel>
|
|
989
|
+
<DropdownMenuRadioGroup
|
|
990
|
+
value={panelSide}
|
|
991
|
+
onValueChange={(value) => {
|
|
992
|
+
if (isDebugPanelSide(value)) {
|
|
993
|
+
setPanelSide(value)
|
|
994
|
+
}
|
|
995
|
+
}}
|
|
996
|
+
>
|
|
997
|
+
<DropdownMenuRadioItem value="left">Left</DropdownMenuRadioItem>
|
|
998
|
+
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
|
|
999
|
+
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
|
|
1000
|
+
</DropdownMenuRadioGroup>
|
|
1001
|
+
<DropdownMenuSeparator />
|
|
1002
|
+
<DropdownMenuItem disabled>
|
|
1003
|
+
Toggle panel
|
|
1004
|
+
<DropdownMenuShortcut>⌘/Ctrl+D</DropdownMenuShortcut>
|
|
1005
|
+
</DropdownMenuItem>
|
|
1006
|
+
</DropdownMenuContent>
|
|
1007
|
+
</DropdownMenu>
|
|
1008
|
+
<Button
|
|
1009
|
+
variant="ghost"
|
|
1010
|
+
size="icon-sm"
|
|
1011
|
+
className="size-7"
|
|
1012
|
+
onClick={() => setOpen(false)}
|
|
1013
|
+
aria-label="Close debug panel"
|
|
926
1014
|
>
|
|
927
|
-
<
|
|
928
|
-
|
|
929
|
-
</ToggleGroupItem>
|
|
930
|
-
<ToggleGroupItem value="right" aria-label="Dock panel right">
|
|
931
|
-
Right
|
|
932
|
-
</ToggleGroupItem>
|
|
933
|
-
<ToggleGroupItem value="bottom" aria-label="Dock panel bottom">
|
|
934
|
-
Bottom
|
|
935
|
-
</ToggleGroupItem>
|
|
936
|
-
</ToggleGroup>
|
|
1015
|
+
<XIcon className="size-3.5" />
|
|
1016
|
+
</Button>
|
|
937
1017
|
</div>
|
|
938
1018
|
</div>
|
|
939
|
-
</
|
|
1019
|
+
</div>
|
|
940
1020
|
|
|
941
1021
|
<Tabs
|
|
942
1022
|
value={activeTab}
|
|
@@ -945,31 +1025,38 @@ export function DebugPanel() {
|
|
|
945
1025
|
setActiveTab(value)
|
|
946
1026
|
}
|
|
947
1027
|
}}
|
|
948
|
-
className="min-h-0 flex-1 gap-0 px-
|
|
1028
|
+
className="min-h-0 flex-1 gap-0 px-3"
|
|
949
1029
|
>
|
|
950
|
-
<TabsList className="w-
|
|
951
|
-
<TabsTrigger value="overview">
|
|
952
|
-
|
|
1030
|
+
<TabsList className="-mx-3 grid h-9 w-[calc(100%+1.5rem)] grid-cols-4 justify-start border-y border-border/20 bg-muted p-0">
|
|
1031
|
+
<TabsTrigger value="overview" className="h-9 rounded-none border-r border-border/20 px-2 text-[12px] font-medium">
|
|
1032
|
+
Overview
|
|
1033
|
+
</TabsTrigger>
|
|
1034
|
+
<TabsTrigger value="runtime" className="h-9 rounded-none border-r border-border/20 px-2 text-[12px] font-medium">
|
|
953
1035
|
Runtime
|
|
954
|
-
{
|
|
955
|
-
<Badge variant="secondary" className="ml-1 h-
|
|
956
|
-
{
|
|
1036
|
+
{runtimeCount ? (
|
|
1037
|
+
<Badge variant="secondary" className="ml-1 h-4 min-w-4 rounded-sm px-1 text-[10px]">
|
|
1038
|
+
{runtimeCount}
|
|
957
1039
|
</Badge>
|
|
958
1040
|
) : null}
|
|
959
1041
|
</TabsTrigger>
|
|
960
|
-
<TabsTrigger value="system">
|
|
961
|
-
|
|
1042
|
+
<TabsTrigger value="system" className="h-9 rounded-none border-r border-border/20 px-2 text-[12px] font-medium">
|
|
1043
|
+
System
|
|
1044
|
+
</TabsTrigger>
|
|
1045
|
+
<TabsTrigger value="errors" className="h-9 rounded-none px-2 text-[12px] font-medium">
|
|
962
1046
|
Errors
|
|
963
1047
|
{errors.length ? (
|
|
964
|
-
<Badge variant="destructive" className="ml-1 h-
|
|
1048
|
+
<Badge variant="destructive" className="ml-1 h-4 min-w-4 rounded-sm px-1 text-[10px]">
|
|
965
1049
|
{errors.length}
|
|
966
1050
|
</Badge>
|
|
967
1051
|
) : null}
|
|
968
1052
|
</TabsTrigger>
|
|
969
1053
|
</TabsList>
|
|
970
1054
|
|
|
971
|
-
<TabsContent
|
|
972
|
-
|
|
1055
|
+
<TabsContent
|
|
1056
|
+
value="overview"
|
|
1057
|
+
className={cn("min-h-0 flex-1 pt-2", isBottomDock ? "overflow-y-auto" : "overflow-hidden")}
|
|
1058
|
+
>
|
|
1059
|
+
<div className={overviewLayoutClassName}>
|
|
973
1060
|
<DebugSection
|
|
974
1061
|
title="App"
|
|
975
1062
|
description="Static application metadata from Tauri v2."
|
|
@@ -980,10 +1067,12 @@ export function DebugPanel() {
|
|
|
980
1067
|
["URL", locationState.href || "Unavailable"],
|
|
981
1068
|
["Search", locationState.search || "(none)"],
|
|
982
1069
|
["Hash", locationState.hash || "(none)"],
|
|
1070
|
+
["Bridge", tauriReady ? "Tauri" : "Web"],
|
|
983
1071
|
["Name", appInfo.name ?? "Unavailable"],
|
|
984
1072
|
["Version", appInfo.version ?? "Unavailable"],
|
|
985
1073
|
["Identifier", appInfo.identifier ?? "Unavailable"],
|
|
986
1074
|
["Tauri", appInfo.tauriVersion ?? "Unavailable"],
|
|
1075
|
+
["Shortcut", "Cmd/Ctrl + D"],
|
|
987
1076
|
]}
|
|
988
1077
|
/>
|
|
989
1078
|
</DebugSection>
|
|
@@ -1051,35 +1140,45 @@ export function DebugPanel() {
|
|
|
1051
1140
|
</div>
|
|
1052
1141
|
</TabsContent>
|
|
1053
1142
|
|
|
1054
|
-
<TabsContent
|
|
1055
|
-
|
|
1143
|
+
<TabsContent
|
|
1144
|
+
value="runtime"
|
|
1145
|
+
className={cn("min-h-0 flex-1 pt-2", isBottomDock ? "overflow-y-auto" : "overflow-hidden")}
|
|
1146
|
+
>
|
|
1147
|
+
<div className={runtimeLayoutClassName}>
|
|
1056
1148
|
<DebugSection
|
|
1057
1149
|
title="Recent invoke() calls"
|
|
1058
1150
|
description="Calls captured through the tracked Tauri helper."
|
|
1151
|
+
bodyClassName="min-h-0"
|
|
1059
1152
|
>
|
|
1060
1153
|
{invokeLogs.length ? (
|
|
1061
|
-
<div
|
|
1154
|
+
<div
|
|
1155
|
+
className={cn(
|
|
1156
|
+
"space-y-1.5 overflow-y-auto pr-1",
|
|
1157
|
+
isBottomDock ? "h-full" : "max-h-72"
|
|
1158
|
+
)}
|
|
1159
|
+
>
|
|
1062
1160
|
{invokeLogs.map((entry) => {
|
|
1063
1161
|
if (entry.kind !== "invoke") {
|
|
1064
1162
|
return null
|
|
1065
1163
|
}
|
|
1066
1164
|
|
|
1067
1165
|
return (
|
|
1068
|
-
<div key={entry.id} className="rounded-
|
|
1069
|
-
<div className="mb-
|
|
1070
|
-
<div className="font-mono text-
|
|
1166
|
+
<div key={entry.id} className="rounded-md border border-border/20 bg-card p-2.5">
|
|
1167
|
+
<div className="mb-1.5 flex items-center justify-between gap-3">
|
|
1168
|
+
<div className="font-mono text-[11px]">{entry.command}</div>
|
|
1071
1169
|
<div className="flex items-center gap-2">
|
|
1072
1170
|
<Badge
|
|
1073
1171
|
variant={entry.status === "success" ? "secondary" : "destructive"}
|
|
1172
|
+
className="h-4 rounded-sm px-1 text-[10px]"
|
|
1074
1173
|
>
|
|
1075
1174
|
{entry.status}
|
|
1076
1175
|
</Badge>
|
|
1077
|
-
<span className="text-[
|
|
1176
|
+
<span className="text-[10px] text-muted-foreground">
|
|
1078
1177
|
{entry.durationMs} ms
|
|
1079
1178
|
</span>
|
|
1080
1179
|
</div>
|
|
1081
1180
|
</div>
|
|
1082
|
-
<pre className="overflow-x-auto rounded-md bg-muted
|
|
1181
|
+
<pre className="overflow-x-auto rounded-md bg-muted p-2 text-[10px] leading-4 break-words whitespace-pre-wrap">
|
|
1083
1182
|
{JSON.stringify(
|
|
1084
1183
|
{
|
|
1085
1184
|
args: entry.args,
|
|
@@ -1101,44 +1200,32 @@ export function DebugPanel() {
|
|
|
1101
1200
|
)}
|
|
1102
1201
|
</DebugSection>
|
|
1103
1202
|
|
|
1104
|
-
<DebugSection
|
|
1105
|
-
title="External links"
|
|
1106
|
-
description="URLs intercepted by the external-link guard."
|
|
1107
|
-
>
|
|
1108
|
-
{externalLinks.length ? (
|
|
1109
|
-
<ul className="max-h-56 space-y-2 overflow-y-auto pr-1 text-xs">
|
|
1110
|
-
{externalLinks.map((href, index) => (
|
|
1111
|
-
<li key={`${href}-${index}`} className="flex gap-2">
|
|
1112
|
-
<ExternalLinkIcon className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
|
|
1113
|
-
<span className="font-mono break-all">{href}</span>
|
|
1114
|
-
</li>
|
|
1115
|
-
))}
|
|
1116
|
-
</ul>
|
|
1117
|
-
) : (
|
|
1118
|
-
<p className="text-xs text-muted-foreground">
|
|
1119
|
-
No external links opened yet.
|
|
1120
|
-
</p>
|
|
1121
|
-
)}
|
|
1122
|
-
</DebugSection>
|
|
1123
|
-
|
|
1124
1203
|
<DebugSection
|
|
1125
1204
|
title="Runtime events"
|
|
1126
1205
|
description="Recent Tauri window and emitted event activity."
|
|
1206
|
+
bodyClassName="min-h-0"
|
|
1127
1207
|
>
|
|
1128
1208
|
{runtimeEvents.length ? (
|
|
1129
|
-
<ul
|
|
1209
|
+
<ul
|
|
1210
|
+
className={cn(
|
|
1211
|
+
"space-y-1.5 overflow-y-auto pr-1 text-[11px]",
|
|
1212
|
+
isBottomDock ? "h-full" : "max-h-72"
|
|
1213
|
+
)}
|
|
1214
|
+
>
|
|
1130
1215
|
{newestFirst(runtimeEvents).map((entry) => (
|
|
1131
|
-
<li key={entry.id} className="relative rounded-
|
|
1216
|
+
<li key={entry.id} className="relative rounded-md border border-border/20 bg-card p-2.5">
|
|
1132
1217
|
{highlightedRuntimeEventIds.includes(entry.id) ? <EntryHighlight /> : null}
|
|
1133
1218
|
<div className="mb-1 flex items-center justify-between gap-3">
|
|
1134
1219
|
<span className="font-mono">{entry.name}</span>
|
|
1135
|
-
<Badge variant="outline">
|
|
1220
|
+
<Badge variant="outline" className="h-4 rounded-sm px-1 text-[10px]">
|
|
1221
|
+
{entry.source}
|
|
1222
|
+
</Badge>
|
|
1136
1223
|
</div>
|
|
1137
|
-
<div className="mb-
|
|
1224
|
+
<div className="mb-1.5 text-[10px] text-muted-foreground">
|
|
1138
1225
|
{formatTimestamp(entry.timestamp)}
|
|
1139
1226
|
</div>
|
|
1140
1227
|
{entry.payload !== undefined ? (
|
|
1141
|
-
<pre className="overflow-x-auto rounded-md bg-muted
|
|
1228
|
+
<pre className="overflow-x-auto rounded-md bg-muted p-2 text-[10px] leading-4 break-words whitespace-pre-wrap">
|
|
1142
1229
|
{JSON.stringify(entry.payload, null, 2)}
|
|
1143
1230
|
</pre>
|
|
1144
1231
|
) : null}
|
|
@@ -1155,14 +1242,20 @@ export function DebugPanel() {
|
|
|
1155
1242
|
<DebugSection
|
|
1156
1243
|
title="Plugin logs"
|
|
1157
1244
|
description="Recent logs surfaced through the browser console and Tauri log plugin."
|
|
1245
|
+
bodyClassName="min-h-0"
|
|
1158
1246
|
>
|
|
1159
1247
|
{logEntries.length ? (
|
|
1160
|
-
<ul
|
|
1248
|
+
<ul
|
|
1249
|
+
className={cn(
|
|
1250
|
+
"space-y-1.5 overflow-y-auto pr-1 text-[11px]",
|
|
1251
|
+
isBottomDock ? "h-full" : "max-h-72"
|
|
1252
|
+
)}
|
|
1253
|
+
>
|
|
1161
1254
|
{newestFirst(logEntries).map((entry) => {
|
|
1162
1255
|
const parsed = parsePluginLogMessage(entry.message)
|
|
1163
1256
|
|
|
1164
1257
|
return (
|
|
1165
|
-
<li key={entry.id} className="relative rounded-
|
|
1258
|
+
<li key={entry.id} className="relative rounded-md border border-border/20 bg-card p-2.5">
|
|
1166
1259
|
{highlightedLogIds.includes(entry.id) ? <EntryHighlight /> : null}
|
|
1167
1260
|
{parsed ? (
|
|
1168
1261
|
<div className="space-y-2">
|
|
@@ -1171,33 +1264,35 @@ export function DebugPanel() {
|
|
|
1171
1264
|
<div className="flex min-w-0 items-center gap-2">
|
|
1172
1265
|
<span
|
|
1173
1266
|
className={cn(
|
|
1174
|
-
"inline-flex rounded-
|
|
1267
|
+
"inline-flex rounded-sm border px-1 py-0.5 text-[10px] font-medium uppercase tracking-wide",
|
|
1175
1268
|
getLogLevelClasses(parsed.level)
|
|
1176
1269
|
)}
|
|
1177
1270
|
>
|
|
1178
1271
|
{parsed.level}
|
|
1179
1272
|
</span>
|
|
1180
|
-
<span className="truncate font-mono text-[
|
|
1273
|
+
<span className="truncate font-mono text-[10px] text-muted-foreground">
|
|
1181
1274
|
{parsed.target}
|
|
1182
1275
|
</span>
|
|
1183
1276
|
</div>
|
|
1184
1277
|
</div>
|
|
1185
|
-
<div className="shrink-0 text-right text-[
|
|
1278
|
+
<div className="shrink-0 text-right text-[10px] text-muted-foreground">
|
|
1186
1279
|
<div>{parsed.time}</div>
|
|
1187
1280
|
<div>{parsed.date}</div>
|
|
1188
1281
|
</div>
|
|
1189
1282
|
</div>
|
|
1190
|
-
<p className="font-mono break-words text-foreground">{parsed.text}</p>
|
|
1283
|
+
<p className="font-mono break-words text-[11px] text-foreground">{parsed.text}</p>
|
|
1191
1284
|
</div>
|
|
1192
1285
|
) : (
|
|
1193
1286
|
<>
|
|
1194
1287
|
<div className="mb-1 flex items-center justify-between gap-3">
|
|
1195
|
-
<Badge variant="outline">
|
|
1196
|
-
|
|
1288
|
+
<Badge variant="outline" className="h-4 rounded-sm px-1 text-[10px]">
|
|
1289
|
+
{entry.level}
|
|
1290
|
+
</Badge>
|
|
1291
|
+
<span className="text-[10px] text-muted-foreground">
|
|
1197
1292
|
{formatTimestamp(entry.timestamp)}
|
|
1198
1293
|
</span>
|
|
1199
1294
|
</div>
|
|
1200
|
-
<p className="font-mono break-words text-foreground">
|
|
1295
|
+
<p className="font-mono break-words text-[11px] text-foreground">
|
|
1201
1296
|
{entry.message}
|
|
1202
1297
|
</p>
|
|
1203
1298
|
</>
|
|
@@ -1212,16 +1307,45 @@ export function DebugPanel() {
|
|
|
1212
1307
|
</p>
|
|
1213
1308
|
)}
|
|
1214
1309
|
</DebugSection>
|
|
1310
|
+
|
|
1311
|
+
<DebugSection
|
|
1312
|
+
title="External links"
|
|
1313
|
+
description="URLs intercepted by the external-link guard."
|
|
1314
|
+
bodyClassName="min-h-0"
|
|
1315
|
+
>
|
|
1316
|
+
{externalLinks.length ? (
|
|
1317
|
+
<ul
|
|
1318
|
+
className={cn(
|
|
1319
|
+
"space-y-1.5 overflow-y-auto pr-1 text-[11px]",
|
|
1320
|
+
isBottomDock ? "h-full" : "max-h-56"
|
|
1321
|
+
)}
|
|
1322
|
+
>
|
|
1323
|
+
{externalLinks.map((href, index) => (
|
|
1324
|
+
<li key={`${href}-${index}`} className="flex gap-2 rounded-md border border-border/20 bg-card p-2">
|
|
1325
|
+
<ExternalLinkIcon className="mt-0.5 size-3 shrink-0 text-muted-foreground" />
|
|
1326
|
+
<span className="font-mono break-all">{href}</span>
|
|
1327
|
+
</li>
|
|
1328
|
+
))}
|
|
1329
|
+
</ul>
|
|
1330
|
+
) : (
|
|
1331
|
+
<p className="text-xs text-muted-foreground">
|
|
1332
|
+
No external links opened yet.
|
|
1333
|
+
</p>
|
|
1334
|
+
)}
|
|
1335
|
+
</DebugSection>
|
|
1215
1336
|
</div>
|
|
1216
1337
|
</TabsContent>
|
|
1217
1338
|
|
|
1218
|
-
<TabsContent
|
|
1219
|
-
|
|
1339
|
+
<TabsContent
|
|
1340
|
+
value="system"
|
|
1341
|
+
className={cn("min-h-0 flex-1 pt-2", isBottomDock ? "overflow-y-auto" : "overflow-hidden")}
|
|
1342
|
+
>
|
|
1343
|
+
<div className={systemLayoutClassName}>
|
|
1220
1344
|
<DebugSection
|
|
1221
1345
|
title="Paths"
|
|
1222
1346
|
description="Resolved Tauri application directories."
|
|
1223
1347
|
>
|
|
1224
|
-
<div className="space-y-
|
|
1348
|
+
<div className="space-y-1.5">
|
|
1225
1349
|
{[
|
|
1226
1350
|
["App data", pathInfo.appDataDir],
|
|
1227
1351
|
["App config", pathInfo.appConfigDir],
|
|
@@ -1229,18 +1353,13 @@ export function DebugPanel() {
|
|
|
1229
1353
|
].map(([label, value]) => (
|
|
1230
1354
|
<div
|
|
1231
1355
|
key={label}
|
|
1232
|
-
className="grid grid-cols-[
|
|
1356
|
+
className="grid grid-cols-[92px_minmax(0,1fr)_auto] items-start gap-3 border-t border-border/20 py-1 text-[11px] first:border-t-0 first:pt-0"
|
|
1233
1357
|
>
|
|
1234
1358
|
<div className="text-muted-foreground">{label}</div>
|
|
1235
1359
|
<div className="font-mono break-all text-foreground">
|
|
1236
1360
|
{value ?? "Unavailable"}
|
|
1237
1361
|
</div>
|
|
1238
|
-
<Button
|
|
1239
|
-
variant="ghost"
|
|
1240
|
-
size="sm"
|
|
1241
|
-
disabled={!value}
|
|
1242
|
-
onClick={() => value && void handleCopyText(value)}
|
|
1243
|
-
>
|
|
1362
|
+
<Button variant="ghost" size="sm" disabled={!value} onClick={() => value && void handleCopyText(value)}>
|
|
1244
1363
|
<CopyIcon className="size-3.5" />
|
|
1245
1364
|
Copy
|
|
1246
1365
|
</Button>
|
|
@@ -1249,24 +1368,27 @@ export function DebugPanel() {
|
|
|
1249
1368
|
</div>
|
|
1250
1369
|
</DebugSection>
|
|
1251
1370
|
|
|
1252
|
-
<DebugSection
|
|
1371
|
+
<DebugSection
|
|
1372
|
+
title="Webview"
|
|
1373
|
+
description="Current webview identity."
|
|
1374
|
+
>
|
|
1253
1375
|
<KeyValueGrid entries={[["Current label", windowInfo.label]]} />
|
|
1254
1376
|
</DebugSection>
|
|
1255
1377
|
</div>
|
|
1256
1378
|
</TabsContent>
|
|
1257
1379
|
|
|
1258
1380
|
<TabsContent value="errors" className="min-h-0 flex-1 overflow-hidden pt-2">
|
|
1259
|
-
<div className="h-full
|
|
1381
|
+
<div className="h-full overflow-y-auto pr-1">
|
|
1260
1382
|
<DebugSection
|
|
1261
1383
|
title="Recent errors"
|
|
1262
1384
|
description="Uncaught runtime errors and unhandled promise rejections."
|
|
1263
1385
|
>
|
|
1264
1386
|
{errors.length ? (
|
|
1265
|
-
<ul className="space-y-
|
|
1387
|
+
<ul className="space-y-1.5 text-[11px]">
|
|
1266
1388
|
{errors.map((entry) => (
|
|
1267
1389
|
<li
|
|
1268
1390
|
key={entry.id}
|
|
1269
|
-
className="rounded-
|
|
1391
|
+
className="rounded-md border border-border/20 bg-card p-2.5"
|
|
1270
1392
|
>
|
|
1271
1393
|
<div className="mb-1 flex items-center gap-2">
|
|
1272
1394
|
<AlertTriangleIcon className="size-3.5 text-destructive" />
|
|
@@ -1290,22 +1412,12 @@ export function DebugPanel() {
|
|
|
1290
1412
|
</div>
|
|
1291
1413
|
</TabsContent>
|
|
1292
1414
|
|
|
1293
|
-
<div className="mt-4 flex shrink-0 flex-wrap gap-2 border-t py-3">
|
|
1294
|
-
<Button onClick={handleCopySnapshot} variant="outline" size="sm">
|
|
1295
|
-
<CopyIcon className="size-4" />
|
|
1296
|
-
{copied ? "Copied" : "Copy snapshot"}
|
|
1297
|
-
</Button>
|
|
1298
|
-
<Button onClick={() => window.location.reload()} variant="outline" size="sm">
|
|
1299
|
-
<RefreshCwIcon className="size-4" />
|
|
1300
|
-
Reload app
|
|
1301
|
-
</Button>
|
|
1302
|
-
</div>
|
|
1303
1415
|
</Tabs>
|
|
1304
1416
|
</>
|
|
1305
1417
|
)
|
|
1306
1418
|
|
|
1307
|
-
const
|
|
1308
|
-
"ui-selectable fixed z-50 flex overflow-hidden bg-
|
|
1419
|
+
const panelFrameClassName = cn(
|
|
1420
|
+
"ui-selectable fixed z-50 flex overflow-hidden border border-border/25 bg-background text-[12px] text-foreground",
|
|
1309
1421
|
panelSide === "bottom"
|
|
1310
1422
|
? "inset-x-0 bottom-0 flex-col border-t"
|
|
1311
1423
|
: panelSide === "left"
|
|
@@ -1315,40 +1427,18 @@ export function DebugPanel() {
|
|
|
1315
1427
|
|
|
1316
1428
|
return (
|
|
1317
1429
|
<>
|
|
1318
|
-
{
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
) : null
|
|
1331
|
-
) : panelSide === "bottom" ? (
|
|
1332
|
-
open ? (
|
|
1333
|
-
<div
|
|
1334
|
-
className="ui-selectable fixed inset-x-0 bottom-0 z-50 flex flex-col overflow-hidden border-t bg-popover text-sm text-popover-foreground shadow-lg"
|
|
1335
|
-
style={{ height: `${BOTTOM_PANEL_HEIGHT}px` }}
|
|
1336
|
-
>
|
|
1337
|
-
{panelContent}
|
|
1338
|
-
</div>
|
|
1339
|
-
) : null
|
|
1340
|
-
) : (
|
|
1341
|
-
<Sheet open={open} onOpenChange={setOpen}>
|
|
1342
|
-
<SheetContent
|
|
1343
|
-
side={panelSide}
|
|
1344
|
-
showCloseButton={false}
|
|
1345
|
-
className="ui-selectable flex h-full max-w-[92vw] flex-col gap-0 overflow-hidden p-0"
|
|
1346
|
-
style={{ width: `${SIDE_PANEL_WIDTH}px` }}
|
|
1347
|
-
>
|
|
1348
|
-
{panelContent}
|
|
1349
|
-
</SheetContent>
|
|
1350
|
-
</Sheet>
|
|
1351
|
-
)}
|
|
1430
|
+
{open ? (
|
|
1431
|
+
<div
|
|
1432
|
+
className={panelFrameClassName}
|
|
1433
|
+
style={
|
|
1434
|
+
panelSide === "bottom"
|
|
1435
|
+
? { ...debugPanelThemeStyle, height: `${BOTTOM_PANEL_HEIGHT}px` }
|
|
1436
|
+
: { ...debugPanelThemeStyle, width: `${SIDE_PANEL_WIDTH}px` }
|
|
1437
|
+
}
|
|
1438
|
+
>
|
|
1439
|
+
{panelContent}
|
|
1440
|
+
</div>
|
|
1441
|
+
) : null}
|
|
1352
1442
|
</>
|
|
1353
1443
|
)
|
|
1354
1444
|
}
|