mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-22 20:05:23 +00:00
fix: separate sidebar drag ids by type
This commit is contained in:
@@ -83,9 +83,16 @@ import {
|
||||
LocalWorkspace,
|
||||
SortableWorkspace,
|
||||
WorkspaceDragOverlay,
|
||||
workspaceSortableDirectory,
|
||||
workspaceSortableId,
|
||||
type WorkspaceSidebarContext,
|
||||
} from "./layout/sidebar-workspace"
|
||||
import { ProjectDragOverlay, SortableProject, type ProjectSidebarContext } from "./layout/sidebar-project"
|
||||
import {
|
||||
ProjectDragOverlay,
|
||||
SortableProject,
|
||||
projectSortableWorktree,
|
||||
type ProjectSidebarContext,
|
||||
} from "./layout/sidebar-project"
|
||||
import { SidebarContent } from "./layout/sidebar-shell"
|
||||
|
||||
export default function Layout(props: ParentProps) {
|
||||
@@ -1841,7 +1848,7 @@ export default function Layout(props: ParentProps) {
|
||||
)
|
||||
|
||||
function handleDragStart(event: unknown) {
|
||||
const id = getDraggableId(event)
|
||||
const id = projectSortableWorktree(getDraggableId(event))
|
||||
if (!id) return
|
||||
setHoverProject(undefined)
|
||||
setStore("activeProject", id)
|
||||
@@ -1850,11 +1857,14 @@ export default function Layout(props: ParentProps) {
|
||||
function handleDragOver(event: DragEvent) {
|
||||
const { draggable, droppable } = event
|
||||
if (draggable && droppable) {
|
||||
const from = projectSortableWorktree(draggable.id?.toString())
|
||||
const to = projectSortableWorktree(droppable.id?.toString())
|
||||
if (!from || !to) return
|
||||
const projects = layout.projects.list()
|
||||
const fromIndex = projects.findIndex((p) => p.worktree === draggable.id.toString())
|
||||
const toIndex = projects.findIndex((p) => p.worktree === droppable.id.toString())
|
||||
const fromIndex = projects.findIndex((p) => p.worktree === from)
|
||||
const toIndex = projects.findIndex((p) => p.worktree === to)
|
||||
if (fromIndex !== toIndex && toIndex !== -1) {
|
||||
layout.projects.move(draggable.id.toString(), toIndex)
|
||||
layout.projects.move(from, toIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1892,7 +1902,7 @@ export default function Layout(props: ParentProps) {
|
||||
})
|
||||
|
||||
function handleWorkspaceDragStart(event: unknown) {
|
||||
const id = getDraggableId(event)
|
||||
const id = workspaceSortableDirectory(getDraggableId(event))
|
||||
if (!id) return
|
||||
setStore("activeWorkspace", id)
|
||||
}
|
||||
@@ -1900,13 +1910,16 @@ export default function Layout(props: ParentProps) {
|
||||
function handleWorkspaceDragOver(event: DragEvent) {
|
||||
const { draggable, droppable } = event
|
||||
if (!draggable || !droppable) return
|
||||
const from = workspaceSortableDirectory(draggable.id?.toString())
|
||||
const to = workspaceSortableDirectory(droppable.id?.toString())
|
||||
if (!from || !to) return
|
||||
|
||||
const project = sidebarProject()
|
||||
if (!project) return
|
||||
|
||||
const ids = workspaceIds(project)
|
||||
const fromIndex = ids.findIndex((dir) => dir === draggable.id.toString())
|
||||
const toIndex = ids.findIndex((dir) => dir === droppable.id.toString())
|
||||
const fromIndex = ids.findIndex((dir) => dir === from)
|
||||
const toIndex = ids.findIndex((dir) => dir === to)
|
||||
if (fromIndex === -1 || toIndex === -1) return
|
||||
if (fromIndex === toIndex) return
|
||||
|
||||
@@ -2267,13 +2280,13 @@ export default function Layout(props: ParentProps) {
|
||||
}}
|
||||
class="size-full flex flex-col py-2 gap-4 overflow-y-auto no-scrollbar [overflow-anchor:none]"
|
||||
>
|
||||
<SortableProvider ids={workspaces()}>
|
||||
<SortableProvider ids={workspaces().map(workspaceSortableId)}>
|
||||
<For each={workspaces()}>
|
||||
{(directory) => (
|
||||
<SortableWorkspace
|
||||
ctx={workspaceSidebarCtx}
|
||||
directory={directory}
|
||||
project={project()}
|
||||
project={project()!}
|
||||
sortNow={sortNow}
|
||||
mobile={panelProps.mobile}
|
||||
/>
|
||||
|
||||
@@ -34,6 +34,17 @@ export type ProjectSidebarContext = {
|
||||
sessionProps: Omit<SessionItemProps, "session" | "list" | "slug" | "mobile" | "dense">
|
||||
}
|
||||
|
||||
const PROJECT_SORTABLE_PREFIX = "project:"
|
||||
|
||||
export function projectSortableId(worktree: string) {
|
||||
return `${PROJECT_SORTABLE_PREFIX}${worktree}`
|
||||
}
|
||||
|
||||
export function projectSortableWorktree(id: string | undefined) {
|
||||
if (!id?.startsWith(PROJECT_SORTABLE_PREFIX)) return
|
||||
return id.slice(PROJECT_SORTABLE_PREFIX.length)
|
||||
}
|
||||
|
||||
export const ProjectDragOverlay = (props: {
|
||||
projects: Accessor<LocalProject[]>
|
||||
activeProject: Accessor<string | undefined>
|
||||
@@ -275,7 +286,7 @@ export const SortableProject = (props: {
|
||||
}): JSX.Element => {
|
||||
const globalSync = useGlobalSync()
|
||||
const language = useLanguage()
|
||||
const sortable = createSortable(props.project.worktree)
|
||||
const sortable = createSortable(projectSortableId(props.project.worktree))
|
||||
const selected = createMemo(() => props.ctx.currentProject()?.worktree === props.project.worktree)
|
||||
const workspaces = createMemo(() => props.ctx.workspaceIds(props.project).slice(0, 2))
|
||||
const workspaceEnabled = createMemo(() => props.ctx.workspacesEnabled(props.project))
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ConstrainDragXAxis } from "@/utils/solid-dnd"
|
||||
import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
|
||||
import { type LocalProject } from "@/context/layout"
|
||||
import { projectSortableId } from "./sidebar-project"
|
||||
|
||||
export const SidebarContent = (props: {
|
||||
mobile?: boolean
|
||||
@@ -63,7 +64,7 @@ export const SidebarContent = (props: {
|
||||
<DragDropSensors />
|
||||
<ConstrainDragXAxis />
|
||||
<div class="h-full w-full flex flex-col items-center gap-3 px-3 py-3 overflow-y-auto no-scrollbar">
|
||||
<SortableProvider ids={props.projects().map((p) => p.worktree)}>
|
||||
<SortableProvider ids={props.projects().map((p) => projectSortableId(p.worktree))}>
|
||||
<For each={props.projects()}>{(project) => props.renderProject(project)}</For>
|
||||
</SortableProvider>
|
||||
<Tooltip
|
||||
|
||||
@@ -54,6 +54,17 @@ export type WorkspaceSidebarContext = {
|
||||
setScrollContainerRef: (el: HTMLDivElement | undefined, mobile?: boolean) => void
|
||||
}
|
||||
|
||||
const WORKSPACE_SORTABLE_PREFIX = "workspace:"
|
||||
|
||||
export function workspaceSortableId(directory: string) {
|
||||
return `${WORKSPACE_SORTABLE_PREFIX}${directory}`
|
||||
}
|
||||
|
||||
export function workspaceSortableDirectory(id: string | undefined) {
|
||||
if (!id?.startsWith(WORKSPACE_SORTABLE_PREFIX)) return
|
||||
return id.slice(WORKSPACE_SORTABLE_PREFIX.length)
|
||||
}
|
||||
|
||||
export const WorkspaceDragOverlay = (props: {
|
||||
sidebarProject: Accessor<LocalProject | undefined>
|
||||
activeWorkspace: Accessor<string | undefined>
|
||||
@@ -300,7 +311,7 @@ export const SortableWorkspace = (props: {
|
||||
const params = useParams()
|
||||
const globalSync = useGlobalSync()
|
||||
const language = useLanguage()
|
||||
const sortable = createSortable(props.directory)
|
||||
const sortable = createSortable(workspaceSortableId(props.directory))
|
||||
const [workspaceStore, setWorkspaceStore] = globalSync.child(props.directory, { bootstrap: false })
|
||||
const [menu, setMenu] = createStore({
|
||||
open: false,
|
||||
|
||||
Reference in New Issue
Block a user