@jetcrab/pi-desk 1.1.22-dev → 1.1.23-dev
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/package.json +1 -1
- package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +1 -1
- package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +1 -1
- package/src/client/l2_biz/project-preview/l2-project-preview.tsx +28 -34
- package/src/client/l3_modules/project-files/l3-project-document-view.tsx +162 -151
- package/src/client/l3_modules/project-files/l3-project-file-browser.module.css +30 -0
- package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +137 -111
- package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +26 -6
- package/src/client/l3_modules/project-files/views/l3-project-search-controls.tsx +118 -123
- package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +29 -25
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
- package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/page.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/20460.js +2 -2
- package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/9038-05fd2688407b39c1.js +15 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/{page-e8a5274c115f528d.js → page-54040b9fd54ee8b3.js} +2 -2
- package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/{page-d70ee4e9409b970a.js → page-bc18765121950e65.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/{webpack-b60891a214e0925d.js → webpack-48eecbb66781c006.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/css/10e063cfb3cda7bd.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/2c3b0c0ff1f49c68.css +1 -0
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/9038-03144ed96d613f75.js +0 -15
- package/temp/build/pi-desk/release/.next/static/css/6dbae2922f88ca31.css +0 -1
- package/temp/build/pi-desk/release/.next/static/css/f646ca6c07245c4c.css +0 -1
- /package/temp/build/pi-desk/release/.next/static/{MV6_lBt7Mzmi1rBNI-3dx → gAYTx4KJJR3vTtGYexj4J}/_buildManifest.js +0 -0
- /package/temp/build/pi-desk/release/.next/static/{MV6_lBt7Mzmi1rBNI-3dx → gAYTx4KJJR3vTtGYexj4J}/_ssgManifest.js +0 -0
package/package.json
CHANGED
|
@@ -45,7 +45,7 @@ export function L2ProjectPreviewPage({
|
|
|
45
45
|
refreshOnFocus={false}
|
|
46
46
|
onUnauthorized={onUnauthorized}
|
|
47
47
|
actions={
|
|
48
|
-
<Button size="sm" variant="
|
|
48
|
+
<Button size="sm" variant="ghost" onClick={() => onSelect(null)}>
|
|
49
49
|
<FolderOpenIcon className="size-4" />
|
|
50
50
|
<span>{t('switchProject')}</span>
|
|
51
51
|
</Button>
|
|
@@ -78,6 +78,7 @@ export function L2ProjectPreview({
|
|
|
78
78
|
<L3ProjectFileBrowser
|
|
79
79
|
cwd={cwd}
|
|
80
80
|
projectName={projectName}
|
|
81
|
+
showRootTitle={false}
|
|
81
82
|
runtime={files}
|
|
82
83
|
gitRuntime={git}
|
|
83
84
|
onOpenGitBranches={openGit}
|
|
@@ -85,25 +86,26 @@ export function L2ProjectPreview({
|
|
|
85
86
|
/>
|
|
86
87
|
)
|
|
87
88
|
const code = (
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
89
|
+
<L3ProjectDocumentView
|
|
90
|
+
runtime={files}
|
|
91
|
+
gitRuntime={git}
|
|
92
|
+
compact={width < 1100}
|
|
93
|
+
refreshOnFocus={refreshOnFocus}
|
|
94
|
+
onEscape={onEscape}
|
|
95
|
+
renderHeader={(actions) => (
|
|
96
|
+
<L3ProjectFileTabs
|
|
97
|
+
cwd={cwd}
|
|
98
|
+
gitRuntime={git}
|
|
99
|
+
paths={state.tabs}
|
|
100
|
+
activePath={state.activePath}
|
|
101
|
+
diffPath={diffPath}
|
|
102
|
+
mobile={narrow}
|
|
103
|
+
actions={actions}
|
|
104
|
+
onActivate={(path) => files.openFile(path)}
|
|
105
|
+
onClose={(path, scope) => files.closeTabs(path, scope)}
|
|
106
|
+
/>
|
|
107
|
+
)}
|
|
108
|
+
/>
|
|
107
109
|
)
|
|
108
110
|
const gitView = (
|
|
109
111
|
<div className="flex size-full min-h-0 min-w-0 flex-col">
|
|
@@ -226,7 +228,7 @@ export function L2ProjectPreview({
|
|
|
226
228
|
className="flex size-full min-h-0 min-w-0 flex-col overflow-hidden"
|
|
227
229
|
data-testid="project-preview"
|
|
228
230
|
>
|
|
229
|
-
<header className="flex min-h-
|
|
231
|
+
<header className="flex min-h-9 shrink-0 items-center gap-1 bg-muted px-2 py-1 pt-[max(4px,env(safe-area-inset-top))]">
|
|
230
232
|
{!stacked ? (
|
|
231
233
|
<Button
|
|
232
234
|
size="icon-sm"
|
|
@@ -241,15 +243,11 @@ export function L2ProjectPreview({
|
|
|
241
243
|
)}
|
|
242
244
|
</Button>
|
|
243
245
|
) : null}
|
|
244
|
-
<div className="min-w-0 flex-1">
|
|
245
|
-
|
|
246
|
-
<h1 className="truncate text-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
)}
|
|
250
|
-
<p className="truncate text-xs text-muted-foreground" title={cwd}>
|
|
251
|
-
{cwd}
|
|
252
|
-
</p>
|
|
246
|
+
<div className="flex min-w-0 flex-1 items-baseline gap-3" title={cwd}>
|
|
247
|
+
<div className="min-w-0 shrink-0 max-w-[50%] max-sm:max-w-full max-sm:shrink">
|
|
248
|
+
{title ?? <h1 className="truncate text-sm font-semibold">{projectName}</h1>}
|
|
249
|
+
</div>
|
|
250
|
+
<p className="min-w-0 truncate text-xs text-muted-foreground max-sm:hidden">{cwd}</p>
|
|
253
251
|
</div>
|
|
254
252
|
<Button
|
|
255
253
|
size="sm"
|
|
@@ -272,11 +270,7 @@ export function L2ProjectPreview({
|
|
|
272
270
|
) : null}
|
|
273
271
|
{stacked ? (
|
|
274
272
|
<>
|
|
275
|
-
<div
|
|
276
|
-
className="flex shrink-0 gap-1 border-b px-2 py-1"
|
|
277
|
-
role="group"
|
|
278
|
-
aria-label={t('previewArea')}
|
|
279
|
-
>
|
|
273
|
+
<div className="flex shrink-0 gap-1 px-2 py-1" role="group" aria-label={t('previewArea')}>
|
|
280
274
|
<Button
|
|
281
275
|
size="sm"
|
|
282
276
|
variant={page === 'files' ? 'secondary' : 'ghost'}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
useRef,
|
|
20
20
|
useState,
|
|
21
21
|
useSyncExternalStore,
|
|
22
|
+
type ReactNode,
|
|
22
23
|
type Ref
|
|
23
24
|
} from 'react'
|
|
24
25
|
import { useTranslation } from 'react-i18next'
|
|
@@ -55,7 +56,8 @@ export function L3ProjectDocumentView({
|
|
|
55
56
|
visible = true,
|
|
56
57
|
refreshOnFocus = true,
|
|
57
58
|
onEscape,
|
|
58
|
-
onSwitchPane
|
|
59
|
+
onSwitchPane,
|
|
60
|
+
renderHeader
|
|
59
61
|
}: {
|
|
60
62
|
ref?: Ref<L3ProjectDocumentHandle>
|
|
61
63
|
runtime: L3ProjectFileRuntime
|
|
@@ -65,6 +67,7 @@ export function L3ProjectDocumentView({
|
|
|
65
67
|
refreshOnFocus?: boolean
|
|
66
68
|
onEscape: () => void
|
|
67
69
|
onSwitchPane?: () => void
|
|
70
|
+
renderHeader?: (actions: ReactNode) => ReactNode
|
|
68
71
|
}): React.JSX.Element {
|
|
69
72
|
const { t } = useTranslation('projectFiles')
|
|
70
73
|
const { wrapLines, diffViewMode, collapseUnchanged } = useL4CodePreferences()
|
|
@@ -149,6 +152,160 @@ export function L3ProjectDocumentView({
|
|
|
149
152
|
else toast.error(t('copyContentFailed'))
|
|
150
153
|
})
|
|
151
154
|
}
|
|
155
|
+
const actions =
|
|
156
|
+
activeDiff || activePath ? (
|
|
157
|
+
<>
|
|
158
|
+
{activeDiff ? (
|
|
159
|
+
<>
|
|
160
|
+
<span className="mr-auto shrink-0 px-1 text-xs text-muted-foreground">
|
|
161
|
+
{activeDiff.label ?? t('headToWorking')}
|
|
162
|
+
{activeDiff.status === 'text' &&
|
|
163
|
+
activeDiff.original.content === activeDiff.modified.content
|
|
164
|
+
? t('noDiffChanges')
|
|
165
|
+
: ''}
|
|
166
|
+
</span>
|
|
167
|
+
<L3CodeSurfaceToolbarButton
|
|
168
|
+
label={t('previousChange')}
|
|
169
|
+
onClick={() => diffRef.current?.previousChange()}
|
|
170
|
+
>
|
|
171
|
+
<ArrowUpIcon className="size-4" />
|
|
172
|
+
</L3CodeSurfaceToolbarButton>
|
|
173
|
+
<L3CodeSurfaceToolbarButton
|
|
174
|
+
label={t('nextChange')}
|
|
175
|
+
onClick={() => diffRef.current?.nextChange()}
|
|
176
|
+
>
|
|
177
|
+
<ArrowDownIcon className="size-4" />
|
|
178
|
+
</L3CodeSurfaceToolbarButton>
|
|
179
|
+
{!compact ? (
|
|
180
|
+
<L3CodeSurfaceToolbarButton
|
|
181
|
+
label={diffViewMode === 'side-by-side' ? t('inlineDiff') : t('sideBySideDiff')}
|
|
182
|
+
active={diffViewMode === 'inline'}
|
|
183
|
+
onClick={() =>
|
|
184
|
+
runtime.setDiffViewMode(
|
|
185
|
+
diffViewMode === 'side-by-side' ? 'inline' : 'side-by-side'
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
>
|
|
189
|
+
<Columns2Icon className="size-4" />
|
|
190
|
+
</L3CodeSurfaceToolbarButton>
|
|
191
|
+
) : null}
|
|
192
|
+
<L3CodeSurfaceToolbarButton
|
|
193
|
+
label={t(wrapLines ? 'wrapOff' : 'wrapOn')}
|
|
194
|
+
active={wrapLines}
|
|
195
|
+
onClick={() => runtime.setDiffWrapLines(!wrapLines)}
|
|
196
|
+
>
|
|
197
|
+
<WrapTextIcon className="size-4" />
|
|
198
|
+
</L3CodeSurfaceToolbarButton>
|
|
199
|
+
<L3CodeSurfaceToolbarButton
|
|
200
|
+
label={t(collapseUnchanged ? 'expandUnchanged' : 'collapseUnchanged')}
|
|
201
|
+
active={collapseUnchanged}
|
|
202
|
+
onClick={() => runtime.setDiffCollapseUnchanged(!collapseUnchanged)}
|
|
203
|
+
>
|
|
204
|
+
<FoldVerticalIcon className="size-4" />
|
|
205
|
+
</L3CodeSurfaceToolbarButton>
|
|
206
|
+
<L3CodeSurfaceToolbarButton
|
|
207
|
+
label={t('reloadDiff')}
|
|
208
|
+
onClick={() => runtime.reloadDiff()}
|
|
209
|
+
>
|
|
210
|
+
<RefreshCwIcon className="size-4" />
|
|
211
|
+
</L3CodeSurfaceToolbarButton>
|
|
212
|
+
</>
|
|
213
|
+
) : (
|
|
214
|
+
<>
|
|
215
|
+
{previewKind && document?.status === 'text' && activePath ? (
|
|
216
|
+
<div
|
|
217
|
+
className="mr-auto flex shrink-0"
|
|
218
|
+
role="group"
|
|
219
|
+
aria-label={t(previewKind === 'markdown' ? 'markdownMode' : 'htmlMode')}
|
|
220
|
+
>
|
|
221
|
+
{(['preview', 'source'] as const).map((mode) => (
|
|
222
|
+
<Button
|
|
223
|
+
key={mode}
|
|
224
|
+
variant={document.viewMode === mode ? 'secondary' : 'ghost'}
|
|
225
|
+
size="sm"
|
|
226
|
+
aria-pressed={document.viewMode === mode}
|
|
227
|
+
onClick={() => {
|
|
228
|
+
savePosition()
|
|
229
|
+
runtime.setTextViewMode(activePath, mode)
|
|
230
|
+
}}
|
|
231
|
+
>
|
|
232
|
+
{t(mode === 'preview' ? 'previewMode' : 'sourceMode')}
|
|
233
|
+
</Button>
|
|
234
|
+
))}
|
|
235
|
+
</div>
|
|
236
|
+
) : null}
|
|
237
|
+
{showSource && gitStatus ? (
|
|
238
|
+
<span
|
|
239
|
+
data-testid="file-git-status"
|
|
240
|
+
role="status"
|
|
241
|
+
className="mr-auto min-w-0 truncate text-xs text-muted-foreground"
|
|
242
|
+
title={comparison?.status === 'error' ? comparison.error : gitStatus}
|
|
243
|
+
>
|
|
244
|
+
{compact && comparison?.status === 'ready' && typeof count === 'number'
|
|
245
|
+
? t('gitChangesCompact', { count })
|
|
246
|
+
: gitStatus}
|
|
247
|
+
</span>
|
|
248
|
+
) : null}
|
|
249
|
+
{showSource && comparison?.status === 'ready' ? (
|
|
250
|
+
<>
|
|
251
|
+
{typeof count === 'number' && count > 0 ? (
|
|
252
|
+
<>
|
|
253
|
+
<L3CodeSurfaceToolbarButton
|
|
254
|
+
label={t('previousChange')}
|
|
255
|
+
onClick={() => previewRef.current?.previousChange()}
|
|
256
|
+
>
|
|
257
|
+
<ArrowUpIcon className="size-4" />
|
|
258
|
+
</L3CodeSurfaceToolbarButton>
|
|
259
|
+
<L3CodeSurfaceToolbarButton
|
|
260
|
+
label={t('nextChange')}
|
|
261
|
+
onClick={() => previewRef.current?.nextChange()}
|
|
262
|
+
>
|
|
263
|
+
<ArrowDownIcon className="size-4" />
|
|
264
|
+
</L3CodeSurfaceToolbarButton>
|
|
265
|
+
</>
|
|
266
|
+
) : null}
|
|
267
|
+
<L3CodeSurfaceToolbarButton label={t('viewDiff')} onClick={() => openDiff()}>
|
|
268
|
+
<GitCompareArrowsIcon className="size-4" />
|
|
269
|
+
</L3CodeSurfaceToolbarButton>
|
|
270
|
+
</>
|
|
271
|
+
) : null}
|
|
272
|
+
{showSource && activePath ? (
|
|
273
|
+
<>
|
|
274
|
+
<L3CodeSurfaceToolbarButton
|
|
275
|
+
label={t('findInFile')}
|
|
276
|
+
onClick={() => previewRef.current?.openSearch()}
|
|
277
|
+
>
|
|
278
|
+
<SearchIcon className="size-4" />
|
|
279
|
+
</L3CodeSurfaceToolbarButton>
|
|
280
|
+
{!compact ? (
|
|
281
|
+
<L3CodeSurfaceToolbarButton
|
|
282
|
+
label={t('goToLine')}
|
|
283
|
+
onClick={() => previewRef.current?.gotoLine()}
|
|
284
|
+
>
|
|
285
|
+
<ListOrderedIcon className="size-4" />
|
|
286
|
+
</L3CodeSurfaceToolbarButton>
|
|
287
|
+
) : null}
|
|
288
|
+
<L3CodeSurfaceToolbarButton
|
|
289
|
+
label={t(wrapLines ? 'wrapOff' : 'wrapOn')}
|
|
290
|
+
active={wrapLines}
|
|
291
|
+
onClick={() => runtime.setWrapLines(activePath, !wrapLines)}
|
|
292
|
+
>
|
|
293
|
+
<WrapTextIcon className="size-4" />
|
|
294
|
+
</L3CodeSurfaceToolbarButton>
|
|
295
|
+
<L3CodeSurfaceToolbarButton label={t('copySelectionOrAll')} onClick={copyText}>
|
|
296
|
+
<CopyIcon className="size-4" />
|
|
297
|
+
</L3CodeSurfaceToolbarButton>
|
|
298
|
+
</>
|
|
299
|
+
) : null}
|
|
300
|
+
{activePath ? (
|
|
301
|
+
<L3CodeSurfaceToolbarButton label={t('reloadCurrentFile')} onClick={refresh}>
|
|
302
|
+
<RefreshCwIcon className="size-4" />
|
|
303
|
+
</L3CodeSurfaceToolbarButton>
|
|
304
|
+
) : null}
|
|
305
|
+
</>
|
|
306
|
+
)}
|
|
307
|
+
</>
|
|
308
|
+
) : null
|
|
152
309
|
return (
|
|
153
310
|
<div
|
|
154
311
|
ref={hostRef}
|
|
@@ -162,160 +319,14 @@ export function L3ProjectDocumentView({
|
|
|
162
319
|
hostRef.current?.querySelector<HTMLElement>('[data-testid="markdown-preview"]')?.focus()
|
|
163
320
|
}}
|
|
164
321
|
>
|
|
165
|
-
{
|
|
322
|
+
{renderHeader ? (
|
|
323
|
+
renderHeader(actions)
|
|
324
|
+
) : actions ? (
|
|
166
325
|
<div
|
|
167
326
|
className="flex min-h-9 shrink-0 flex-wrap items-center justify-end gap-2 border-b px-3 py-1"
|
|
168
327
|
aria-label={t('fileActions')}
|
|
169
328
|
>
|
|
170
|
-
{
|
|
171
|
-
<>
|
|
172
|
-
<span className="mr-auto shrink-0 px-1 text-xs text-muted-foreground">
|
|
173
|
-
{activeDiff.label ?? t('headToWorking')}
|
|
174
|
-
{activeDiff.status === 'text' &&
|
|
175
|
-
activeDiff.original.content === activeDiff.modified.content
|
|
176
|
-
? t('noDiffChanges')
|
|
177
|
-
: ''}
|
|
178
|
-
</span>
|
|
179
|
-
<L3CodeSurfaceToolbarButton
|
|
180
|
-
label={t('previousChange')}
|
|
181
|
-
onClick={() => diffRef.current?.previousChange()}
|
|
182
|
-
>
|
|
183
|
-
<ArrowUpIcon className="size-4" />
|
|
184
|
-
</L3CodeSurfaceToolbarButton>
|
|
185
|
-
<L3CodeSurfaceToolbarButton
|
|
186
|
-
label={t('nextChange')}
|
|
187
|
-
onClick={() => diffRef.current?.nextChange()}
|
|
188
|
-
>
|
|
189
|
-
<ArrowDownIcon className="size-4" />
|
|
190
|
-
</L3CodeSurfaceToolbarButton>
|
|
191
|
-
{!compact ? (
|
|
192
|
-
<L3CodeSurfaceToolbarButton
|
|
193
|
-
label={diffViewMode === 'side-by-side' ? t('inlineDiff') : t('sideBySideDiff')}
|
|
194
|
-
active={diffViewMode === 'inline'}
|
|
195
|
-
onClick={() =>
|
|
196
|
-
runtime.setDiffViewMode(
|
|
197
|
-
diffViewMode === 'side-by-side' ? 'inline' : 'side-by-side'
|
|
198
|
-
)
|
|
199
|
-
}
|
|
200
|
-
>
|
|
201
|
-
<Columns2Icon className="size-4" />
|
|
202
|
-
</L3CodeSurfaceToolbarButton>
|
|
203
|
-
) : null}
|
|
204
|
-
<L3CodeSurfaceToolbarButton
|
|
205
|
-
label={t(wrapLines ? 'wrapOff' : 'wrapOn')}
|
|
206
|
-
active={wrapLines}
|
|
207
|
-
onClick={() => runtime.setDiffWrapLines(!wrapLines)}
|
|
208
|
-
>
|
|
209
|
-
<WrapTextIcon className="size-4" />
|
|
210
|
-
</L3CodeSurfaceToolbarButton>
|
|
211
|
-
<L3CodeSurfaceToolbarButton
|
|
212
|
-
label={t(collapseUnchanged ? 'expandUnchanged' : 'collapseUnchanged')}
|
|
213
|
-
active={collapseUnchanged}
|
|
214
|
-
onClick={() => runtime.setDiffCollapseUnchanged(!collapseUnchanged)}
|
|
215
|
-
>
|
|
216
|
-
<FoldVerticalIcon className="size-4" />
|
|
217
|
-
</L3CodeSurfaceToolbarButton>
|
|
218
|
-
<L3CodeSurfaceToolbarButton
|
|
219
|
-
label={t('reloadDiff')}
|
|
220
|
-
onClick={() => runtime.reloadDiff()}
|
|
221
|
-
>
|
|
222
|
-
<RefreshCwIcon className="size-4" />
|
|
223
|
-
</L3CodeSurfaceToolbarButton>
|
|
224
|
-
</>
|
|
225
|
-
) : (
|
|
226
|
-
<>
|
|
227
|
-
{previewKind && document?.status === 'text' && activePath ? (
|
|
228
|
-
<div
|
|
229
|
-
className="mr-auto flex shrink-0"
|
|
230
|
-
role="group"
|
|
231
|
-
aria-label={t(previewKind === 'markdown' ? 'markdownMode' : 'htmlMode')}
|
|
232
|
-
>
|
|
233
|
-
{(['preview', 'source'] as const).map((mode) => (
|
|
234
|
-
<Button
|
|
235
|
-
key={mode}
|
|
236
|
-
variant={document.viewMode === mode ? 'secondary' : 'ghost'}
|
|
237
|
-
size="sm"
|
|
238
|
-
aria-pressed={document.viewMode === mode}
|
|
239
|
-
onClick={() => {
|
|
240
|
-
savePosition()
|
|
241
|
-
runtime.setTextViewMode(activePath, mode)
|
|
242
|
-
}}
|
|
243
|
-
>
|
|
244
|
-
{t(mode === 'preview' ? 'previewMode' : 'sourceMode')}
|
|
245
|
-
</Button>
|
|
246
|
-
))}
|
|
247
|
-
</div>
|
|
248
|
-
) : null}
|
|
249
|
-
{showSource && gitStatus ? (
|
|
250
|
-
<span
|
|
251
|
-
data-testid="file-git-status"
|
|
252
|
-
role="status"
|
|
253
|
-
className="mr-auto min-w-0 truncate text-xs text-muted-foreground"
|
|
254
|
-
title={comparison?.status === 'error' ? comparison.error : gitStatus}
|
|
255
|
-
>
|
|
256
|
-
{compact && comparison?.status === 'ready' && typeof count === 'number'
|
|
257
|
-
? t('gitChangesCompact', { count })
|
|
258
|
-
: gitStatus}
|
|
259
|
-
</span>
|
|
260
|
-
) : null}
|
|
261
|
-
{showSource && comparison?.status === 'ready' ? (
|
|
262
|
-
<>
|
|
263
|
-
{typeof count === 'number' && count > 0 ? (
|
|
264
|
-
<>
|
|
265
|
-
<L3CodeSurfaceToolbarButton
|
|
266
|
-
label={t('previousChange')}
|
|
267
|
-
onClick={() => previewRef.current?.previousChange()}
|
|
268
|
-
>
|
|
269
|
-
<ArrowUpIcon className="size-4" />
|
|
270
|
-
</L3CodeSurfaceToolbarButton>
|
|
271
|
-
<L3CodeSurfaceToolbarButton
|
|
272
|
-
label={t('nextChange')}
|
|
273
|
-
onClick={() => previewRef.current?.nextChange()}
|
|
274
|
-
>
|
|
275
|
-
<ArrowDownIcon className="size-4" />
|
|
276
|
-
</L3CodeSurfaceToolbarButton>
|
|
277
|
-
</>
|
|
278
|
-
) : null}
|
|
279
|
-
<L3CodeSurfaceToolbarButton label={t('viewDiff')} onClick={() => openDiff()}>
|
|
280
|
-
<GitCompareArrowsIcon className="size-4" />
|
|
281
|
-
</L3CodeSurfaceToolbarButton>
|
|
282
|
-
</>
|
|
283
|
-
) : null}
|
|
284
|
-
{showSource && activePath ? (
|
|
285
|
-
<>
|
|
286
|
-
<L3CodeSurfaceToolbarButton
|
|
287
|
-
label={t('findInFile')}
|
|
288
|
-
onClick={() => previewRef.current?.openSearch()}
|
|
289
|
-
>
|
|
290
|
-
<SearchIcon className="size-4" />
|
|
291
|
-
</L3CodeSurfaceToolbarButton>
|
|
292
|
-
{!compact ? (
|
|
293
|
-
<L3CodeSurfaceToolbarButton
|
|
294
|
-
label={t('goToLine')}
|
|
295
|
-
onClick={() => previewRef.current?.gotoLine()}
|
|
296
|
-
>
|
|
297
|
-
<ListOrderedIcon className="size-4" />
|
|
298
|
-
</L3CodeSurfaceToolbarButton>
|
|
299
|
-
) : null}
|
|
300
|
-
<L3CodeSurfaceToolbarButton
|
|
301
|
-
label={t(wrapLines ? 'wrapOff' : 'wrapOn')}
|
|
302
|
-
active={wrapLines}
|
|
303
|
-
onClick={() => runtime.setWrapLines(activePath, !wrapLines)}
|
|
304
|
-
>
|
|
305
|
-
<WrapTextIcon className="size-4" />
|
|
306
|
-
</L3CodeSurfaceToolbarButton>
|
|
307
|
-
<L3CodeSurfaceToolbarButton label={t('copySelectionOrAll')} onClick={copyText}>
|
|
308
|
-
<CopyIcon className="size-4" />
|
|
309
|
-
</L3CodeSurfaceToolbarButton>
|
|
310
|
-
</>
|
|
311
|
-
) : null}
|
|
312
|
-
{activePath ? (
|
|
313
|
-
<L3CodeSurfaceToolbarButton label={t('reloadCurrentFile')} onClick={refresh}>
|
|
314
|
-
<RefreshCwIcon className="size-4" />
|
|
315
|
-
</L3CodeSurfaceToolbarButton>
|
|
316
|
-
) : null}
|
|
317
|
-
</>
|
|
318
|
-
)}
|
|
329
|
+
{actions}
|
|
319
330
|
</div>
|
|
320
331
|
) : null}
|
|
321
332
|
<div className="min-h-0 flex-1 overflow-hidden pb-[env(safe-area-inset-bottom)]">
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
.tree [role='tree'] {
|
|
2
|
+
padding: 0;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.tree [role='tree'] > div {
|
|
6
|
+
padding: 0 4px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tree [data-slot='collapsible-content'] > div {
|
|
10
|
+
border-left-color: color-mix(in oklab, var(--border) 50%, transparent);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@media (pointer: fine) {
|
|
14
|
+
.tree [role='treeitem']:not([aria-expanded]),
|
|
15
|
+
.tree [role='treeitem'][aria-expanded] > div:first-child {
|
|
16
|
+
min-height: 24px;
|
|
17
|
+
gap: 4px;
|
|
18
|
+
padding: 0 4px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.tree [role='treeitem'][aria-expanded] > div:first-child > button {
|
|
22
|
+
min-height: 24px;
|
|
23
|
+
gap: 4px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.tree [data-slot='collapsible-content'] > div {
|
|
27
|
+
margin-left: 8px;
|
|
28
|
+
padding-left: 3px;
|
|
29
|
+
}
|
|
30
|
+
}
|