feat(app): color filetree change dots by diff kind
This commit is contained in:
@@ -17,6 +17,8 @@ import {
|
|||||||
import { Dynamic } from "solid-js/web"
|
import { Dynamic } from "solid-js/web"
|
||||||
import type { FileNode } from "@opencode-ai/sdk/v2"
|
import type { FileNode } from "@opencode-ai/sdk/v2"
|
||||||
|
|
||||||
|
type Kind = "add" | "del" | "mix"
|
||||||
|
|
||||||
type Filter = {
|
type Filter = {
|
||||||
files: Set<string>
|
files: Set<string>
|
||||||
dirs: Set<string>
|
dirs: Set<string>
|
||||||
@@ -29,6 +31,7 @@ export default function FileTree(props: {
|
|||||||
level?: number
|
level?: number
|
||||||
allowed?: readonly string[]
|
allowed?: readonly string[]
|
||||||
modified?: readonly string[]
|
modified?: readonly string[]
|
||||||
|
kinds?: ReadonlyMap<string, Kind>
|
||||||
draggable?: boolean
|
draggable?: boolean
|
||||||
tooltip?: boolean
|
tooltip?: boolean
|
||||||
onFileClick?: (file: FileNode) => void
|
onFileClick?: (file: FileNode) => void
|
||||||
@@ -36,6 +39,7 @@ export default function FileTree(props: {
|
|||||||
_filter?: Filter
|
_filter?: Filter
|
||||||
_marks?: Set<string>
|
_marks?: Set<string>
|
||||||
_deeps?: Map<string, number>
|
_deeps?: Map<string, number>
|
||||||
|
_kinds?: ReadonlyMap<string, Kind>
|
||||||
}) {
|
}) {
|
||||||
const file = useFile()
|
const file = useFile()
|
||||||
const level = props.level ?? 0
|
const level = props.level ?? 0
|
||||||
@@ -66,11 +70,16 @@ export default function FileTree(props: {
|
|||||||
const marks = createMemo(() => {
|
const marks = createMemo(() => {
|
||||||
if (props._marks) return props._marks
|
if (props._marks) return props._marks
|
||||||
|
|
||||||
const modified = props.modified
|
const modified = props.modified ?? (props.kinds ? Array.from(props.kinds.keys()) : undefined)
|
||||||
if (!modified || modified.length === 0) return
|
if (!modified || modified.length === 0) return
|
||||||
return new Set(modified)
|
return new Set(modified)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const kinds = createMemo(() => {
|
||||||
|
if (props._kinds) return props._kinds
|
||||||
|
return props.kinds
|
||||||
|
})
|
||||||
|
|
||||||
const deeps = createMemo(() => {
|
const deeps = createMemo(() => {
|
||||||
if (props._deeps) return props._deeps
|
if (props._deeps) return props._deeps
|
||||||
|
|
||||||
@@ -179,9 +188,27 @@ export default function FileTree(props: {
|
|||||||
>
|
>
|
||||||
{local.node.name}
|
{local.node.name}
|
||||||
</span>
|
</span>
|
||||||
{local.node.type === "file" && marks()?.has(local.node.path) ? (
|
{(() => {
|
||||||
<div class="shrink-0 size-1.5 rounded-full bg-surface-warning-strong" />
|
if (local.node.type !== "file") return null
|
||||||
) : null}
|
if (!marks()?.has(local.node.path)) return null
|
||||||
|
|
||||||
|
const kind = kinds()?.get(local.node.path)
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
classList={{
|
||||||
|
"shrink-0 size-1.5 rounded-full": true,
|
||||||
|
"bg-surface-warning-strong": !kind || kind === "mix",
|
||||||
|
}}
|
||||||
|
style={
|
||||||
|
kind === "add"
|
||||||
|
? "background-color: var(--icon-diff-add-base)"
|
||||||
|
: kind === "del"
|
||||||
|
? "background-color: var(--icon-diff-delete-base)"
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})()}
|
||||||
</Dynamic>
|
</Dynamic>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -235,12 +262,14 @@ export default function FileTree(props: {
|
|||||||
level={level + 1}
|
level={level + 1}
|
||||||
allowed={props.allowed}
|
allowed={props.allowed}
|
||||||
modified={props.modified}
|
modified={props.modified}
|
||||||
|
kinds={props.kinds}
|
||||||
draggable={props.draggable}
|
draggable={props.draggable}
|
||||||
tooltip={props.tooltip}
|
tooltip={props.tooltip}
|
||||||
onFileClick={props.onFileClick}
|
onFileClick={props.onFileClick}
|
||||||
_filter={filter()}
|
_filter={filter()}
|
||||||
_marks={marks()}
|
_marks={marks()}
|
||||||
_deeps={deeps()}
|
_deeps={deeps()}
|
||||||
|
_kinds={kinds()}
|
||||||
/>
|
/>
|
||||||
</Collapsible.Content>
|
</Collapsible.Content>
|
||||||
</Collapsible>
|
</Collapsible>
|
||||||
|
|||||||
@@ -479,6 +479,16 @@ export default function Page() {
|
|||||||
scrollToMessage(msgs[targetIndex], "auto")
|
scrollToMessage(msgs[targetIndex], "auto")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const kinds = createMemo(() => {
|
||||||
|
const out = new Map<string, "add" | "del" | "mix">()
|
||||||
|
for (const diff of diffs()) {
|
||||||
|
const add = diff.additions > 0
|
||||||
|
const del = diff.deletions > 0
|
||||||
|
const kind = add && del ? "mix" : add ? "add" : del ? "del" : "mix"
|
||||||
|
out.set(diff.file, kind)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
})
|
||||||
const emptyDiffFiles: string[] = []
|
const emptyDiffFiles: string[] = []
|
||||||
const diffFiles = createMemo(() => diffs().map((d) => d.file), emptyDiffFiles, { equals: same })
|
const diffFiles = createMemo(() => diffs().map((d) => d.file), emptyDiffFiles, { equals: same })
|
||||||
const diffsReady = createMemo(() => {
|
const diffsReady = createMemo(() => {
|
||||||
@@ -2652,6 +2662,7 @@ export default function Page() {
|
|||||||
<FileTree
|
<FileTree
|
||||||
path=""
|
path=""
|
||||||
allowed={diffFiles()}
|
allowed={diffFiles()}
|
||||||
|
kinds={kinds()}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
tooltip={false}
|
tooltip={false}
|
||||||
onFileClick={(node) => focusReviewDiff(node.path)}
|
onFileClick={(node) => focusReviewDiff(node.path)}
|
||||||
@@ -2669,6 +2680,7 @@ export default function Page() {
|
|||||||
<FileTree
|
<FileTree
|
||||||
path=""
|
path=""
|
||||||
modified={diffFiles()}
|
modified={diffFiles()}
|
||||||
|
kinds={kinds()}
|
||||||
tooltip={false}
|
tooltip={false}
|
||||||
onFileClick={(node) => openTab(file.tab(node.path))}
|
onFileClick={(node) => openTab(file.tab(node.path))}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user