|
@@ -395,7 +395,7 @@ export default function Page() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const isDesktop = createMediaQuery("(min-width: 768px)")
|
|
const isDesktop = createMediaQuery("(min-width: 768px)")
|
|
|
- const centered = createMemo(() => isDesktop() && !layout.fileTree.opened())
|
|
|
|
|
|
|
+ const centered = createMemo(() => isDesktop() && !view().reviewPanel.opened())
|
|
|
|
|
|
|
|
function normalizeTab(tab: string) {
|
|
function normalizeTab(tab: string) {
|
|
|
if (!tab.startsWith("file://")) return tab
|
|
if (!tab.startsWith("file://")) return tab
|
|
@@ -1043,7 +1043,18 @@ export default function Page() {
|
|
|
description: "",
|
|
description: "",
|
|
|
category: language.t("command.category.view"),
|
|
category: language.t("command.category.view"),
|
|
|
keybind: "mod+shift+r",
|
|
keybind: "mod+shift+r",
|
|
|
- onSelect: () => layout.fileTree.toggle(),
|
|
|
|
|
|
|
+ onSelect: () => view().reviewPanel.toggle(),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ id: "fileTree.toggle",
|
|
|
|
|
+ title: language.t("command.fileTree.toggle"),
|
|
|
|
|
+ description: "",
|
|
|
|
|
+ category: language.t("command.category.view"),
|
|
|
|
|
+ onSelect: () => {
|
|
|
|
|
+ const opening = !layout.fileTree.opened()
|
|
|
|
|
+ if (opening && !view().reviewPanel.opened()) view().reviewPanel.open()
|
|
|
|
|
+ layout.fileTree.toggle()
|
|
|
|
|
+ },
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
id: "terminal.new",
|
|
id: "terminal.new",
|
|
@@ -1409,10 +1420,11 @@ export default function Page() {
|
|
|
const openedTabs = createMemo(() =>
|
|
const openedTabs = createMemo(() =>
|
|
|
tabs()
|
|
tabs()
|
|
|
.all()
|
|
.all()
|
|
|
- .filter((tab) => tab !== "context"),
|
|
|
|
|
|
|
+ .filter((tab) => tab !== "context" && tab !== "review"),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
const mobileChanges = createMemo(() => !isDesktop() && store.mobileTab === "changes")
|
|
const mobileChanges = createMemo(() => !isDesktop() && store.mobileTab === "changes")
|
|
|
|
|
+ const reviewTab = createMemo(() => isDesktop() && !layout.fileTree.opened())
|
|
|
|
|
|
|
|
const fileTreeTab = () => layout.fileTree.tab()
|
|
const fileTreeTab = () => layout.fileTree.tab()
|
|
|
const setFileTreeTab = (value: "changes" | "all") => layout.fileTree.setTab(value)
|
|
const setFileTreeTab = (value: "changes" | "all") => layout.fileTree.setTab(value)
|
|
@@ -1627,29 +1639,71 @@ export default function Page() {
|
|
|
const activeTab = createMemo(() => {
|
|
const activeTab = createMemo(() => {
|
|
|
const active = tabs().active()
|
|
const active = tabs().active()
|
|
|
if (active === "context") return "context"
|
|
if (active === "context") return "context"
|
|
|
|
|
+ if (active === "review" && reviewTab()) return "review"
|
|
|
if (active && file.pathFromTab(active)) return normalizeTab(active)
|
|
if (active && file.pathFromTab(active)) return normalizeTab(active)
|
|
|
|
|
|
|
|
const first = openedTabs()[0]
|
|
const first = openedTabs()[0]
|
|
|
if (first) return first
|
|
if (first) return first
|
|
|
if (contextOpen()) return "context"
|
|
if (contextOpen()) return "context"
|
|
|
|
|
+ if (reviewTab() && hasReview()) return "review"
|
|
|
return "empty"
|
|
return "empty"
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
createEffect(() => {
|
|
createEffect(() => {
|
|
|
if (!layout.ready()) return
|
|
if (!layout.ready()) return
|
|
|
if (tabs().active()) return
|
|
if (tabs().active()) return
|
|
|
- if (openedTabs().length === 0 && !contextOpen()) return
|
|
|
|
|
|
|
+ if (openedTabs().length === 0 && !contextOpen() && !(reviewTab() && hasReview())) return
|
|
|
|
|
|
|
|
const next = activeTab()
|
|
const next = activeTab()
|
|
|
if (next === "empty") return
|
|
if (next === "empty") return
|
|
|
tabs().setActive(next)
|
|
tabs().setActive(next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ createEffect(
|
|
|
|
|
+ on(
|
|
|
|
|
+ () => layout.fileTree.opened(),
|
|
|
|
|
+ (opened, prev) => {
|
|
|
|
|
+ if (prev === undefined) return
|
|
|
|
|
+ if (!isDesktop()) return
|
|
|
|
|
+
|
|
|
|
|
+ if (opened) {
|
|
|
|
|
+ const active = tabs().active()
|
|
|
|
|
+ const tab = active === "review" || (!active && hasReview()) ? "changes" : "all"
|
|
|
|
|
+ layout.fileTree.setTab(tab)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (fileTreeTab() !== "changes") return
|
|
|
|
|
+ tabs().setActive("review")
|
|
|
|
|
+ },
|
|
|
|
|
+ { defer: true },
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ createEffect(() => {
|
|
|
|
|
+ if (!isDesktop()) return
|
|
|
|
|
+ if (!layout.fileTree.opened()) return
|
|
|
|
|
+ if (fileTreeTab() !== "all") return
|
|
|
|
|
+
|
|
|
|
|
+ const active = tabs().active()
|
|
|
|
|
+ if (active && active !== "review") return
|
|
|
|
|
+
|
|
|
|
|
+ const first = openedTabs()[0]
|
|
|
|
|
+ if (first) {
|
|
|
|
|
+ tabs().setActive(first)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (contextOpen()) tabs().setActive("context")
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
createEffect(() => {
|
|
createEffect(() => {
|
|
|
const id = params.id
|
|
const id = params.id
|
|
|
if (!id) return
|
|
if (!id) return
|
|
|
|
|
|
|
|
- const wants = isDesktop() ? layout.fileTree.opened() : store.mobileTab === "changes"
|
|
|
|
|
|
|
+ const wants = isDesktop()
|
|
|
|
|
+ ? view().reviewPanel.opened() && (layout.fileTree.opened() || activeTab() === "review")
|
|
|
|
|
+ : store.mobileTab === "changes"
|
|
|
if (!wants) return
|
|
if (!wants) return
|
|
|
if (sync.data.session_diff[id] !== undefined) return
|
|
if (sync.data.session_diff[id] !== undefined) return
|
|
|
if (sync.status === "loading") return
|
|
if (sync.status === "loading") return
|
|
@@ -1661,6 +1715,7 @@ export default function Page() {
|
|
|
createEffect(() => {
|
|
createEffect(() => {
|
|
|
const dir = sdk.directory
|
|
const dir = sdk.directory
|
|
|
if (!isDesktop()) return
|
|
if (!isDesktop()) return
|
|
|
|
|
+ if (!view().reviewPanel.opened()) return
|
|
|
if (!layout.fileTree.opened()) return
|
|
if (!layout.fileTree.opened()) return
|
|
|
if (sync.status === "loading") return
|
|
if (sync.status === "loading") return
|
|
|
|
|
|
|
@@ -2195,10 +2250,10 @@ export default function Page() {
|
|
|
classList={{
|
|
classList={{
|
|
|
"@container relative shrink-0 flex flex-col min-h-0 h-full bg-background-stronger": true,
|
|
"@container relative shrink-0 flex flex-col min-h-0 h-full bg-background-stronger": true,
|
|
|
"flex-1 pt-2 md:pt-3": true,
|
|
"flex-1 pt-2 md:pt-3": true,
|
|
|
- "md:flex-none": layout.fileTree.opened(),
|
|
|
|
|
|
|
+ "md:flex-none": view().reviewPanel.opened(),
|
|
|
}}
|
|
}}
|
|
|
style={{
|
|
style={{
|
|
|
- width: isDesktop() && layout.fileTree.opened() ? `${layout.session.width()}px` : "100%",
|
|
|
|
|
|
|
+ width: isDesktop() && view().reviewPanel.opened() ? `${layout.session.width()}px` : "100%",
|
|
|
"--prompt-height": store.promptHeight ? `${store.promptHeight}px` : undefined,
|
|
"--prompt-height": store.promptHeight ? `${store.promptHeight}px` : undefined,
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
@@ -2711,7 +2766,7 @@ export default function Page() {
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <Show when={isDesktop() && layout.fileTree.opened()}>
|
|
|
|
|
|
|
+ <Show when={isDesktop() && view().reviewPanel.opened()}>
|
|
|
<ResizeHandle
|
|
<ResizeHandle
|
|
|
direction="horizontal"
|
|
direction="horizontal"
|
|
|
size={layout.session.width()}
|
|
size={layout.session.width()}
|
|
@@ -2723,7 +2778,7 @@ export default function Page() {
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
{/* Desktop side panel - hidden on mobile */}
|
|
{/* Desktop side panel - hidden on mobile */}
|
|
|
- <Show when={isDesktop() && layout.fileTree.opened()}>
|
|
|
|
|
|
|
+ <Show when={isDesktop() && view().reviewPanel.opened()}>
|
|
|
<aside
|
|
<aside
|
|
|
id="review-panel"
|
|
id="review-panel"
|
|
|
aria-label={language.t("session.panel.reviewAndFiles")}
|
|
aria-label={language.t("session.panel.reviewAndFiles")}
|
|
@@ -2731,7 +2786,7 @@ export default function Page() {
|
|
|
>
|
|
>
|
|
|
<div class="flex-1 min-w-0 h-full">
|
|
<div class="flex-1 min-w-0 h-full">
|
|
|
<Show
|
|
<Show
|
|
|
- when={fileTreeTab() === "changes"}
|
|
|
|
|
|
|
+ when={layout.fileTree.opened() && fileTreeTab() === "changes"}
|
|
|
fallback={
|
|
fallback={
|
|
|
<DragDropProvider
|
|
<DragDropProvider
|
|
|
onDragStart={handleDragStart}
|
|
onDragStart={handleDragStart}
|
|
@@ -2799,6 +2854,18 @@ export default function Page() {
|
|
|
})
|
|
})
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
|
|
|
+ <Show when={reviewTab()}>
|
|
|
|
|
+ <Tabs.Trigger value="review" classes={{ button: "!pl-6" }}>
|
|
|
|
|
+ <div class="flex items-center gap-1.5">
|
|
|
|
|
+ <div>{language.t("session.tab.review")}</div>
|
|
|
|
|
+ <Show when={hasReview()}>
|
|
|
|
|
+ <div class="text-12-medium text-text-strong h-4 px-2 flex flex-col items-center justify-center rounded-full bg-surface-base">
|
|
|
|
|
+ {reviewCount()}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Show>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Tabs.Trigger>
|
|
|
|
|
+ </Show>
|
|
|
<Show when={contextOpen()}>
|
|
<Show when={contextOpen()}>
|
|
|
<Tabs.Trigger
|
|
<Tabs.Trigger
|
|
|
value="context"
|
|
value="context"
|
|
@@ -2847,6 +2914,12 @@ export default function Page() {
|
|
|
</Tabs.List>
|
|
</Tabs.List>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+ <Show when={reviewTab()}>
|
|
|
|
|
+ <Tabs.Content value="review" class="flex flex-col h-full overflow-hidden contain-strict">
|
|
|
|
|
+ <Show when={activeTab() === "review"}>{reviewPanel()}</Show>
|
|
|
|
|
+ </Tabs.Content>
|
|
|
|
|
+ </Show>
|
|
|
|
|
+
|
|
|
<Tabs.Content value="empty" class="flex flex-col h-full overflow-hidden contain-strict">
|
|
<Tabs.Content value="empty" class="flex flex-col h-full overflow-hidden contain-strict">
|
|
|
<Show when={activeTab() === "empty"}>
|
|
<Show when={activeTab() === "empty"}>
|
|
|
<div class="relative pt-2 flex-1 min-h-0 overflow-hidden">
|
|
<div class="relative pt-2 flex-1 min-h-0 overflow-hidden">
|