Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions apps/desktop/src/components/dnd/dnd-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { handleEditorDrop } from "./editor-drop-handler"
import { EditorDropLine } from "./editor-drop-indicator"
import { isPoint } from "./editor-drop-indicator.helpers"
import { EditorDropOwnershipProvider } from "./editor-drop-ownership"
import { ExplorerDragOverlay } from "./explorer-drag-overlay"
import {
ExplorerDragOverlay,
getExplorerDragOverlayName,
} from "./explorer-drag-overlay"
import {
EMPTY_DRAGGED_EXPLORER_PATHS,
ExplorerDragPathsProvider,
Expand Down Expand Up @@ -61,7 +64,7 @@ function renderDragOverlay(source: DragOverlaySource) {
if (isFileEntryDragData(source.data) && source.data.name) {
return (
<ExplorerDragOverlay
name={source.data.name}
name={getExplorerDragOverlayName(source.data)}
isDirectory={Boolean(source.data.isDirectory)}
/>
)
Expand Down
9 changes: 5 additions & 4 deletions apps/desktop/src/components/dnd/dnd-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type FileEntryDragData = {
path?: string
isDirectory?: boolean
name?: string
displayName?: string
}

export type EditorDragData = {
Expand Down Expand Up @@ -80,15 +81,15 @@ export function isFileEntryDragData(data: unknown): data is FileEntryDragData {
}

const hasKnownKey = "path" in data || "isDirectory" in data || "name" in data
if (!hasKnownKey) {
if (!hasKnownKey && !("displayName" in data)) {
return false
}

const { path, isDirectory, name } = data
const { path, isDirectory, name, displayName } = data
return (
(path === undefined || typeof path === "string") &&
(isDirectory === undefined || typeof isDirectory === "boolean") &&
(name === undefined || typeof name === "string")
(name === undefined || typeof name === "string") &&
(displayName === undefined || typeof displayName === "string")
)
}

Expand Down
23 changes: 23 additions & 0 deletions apps/desktop/src/components/dnd/explorer-drag-overlay.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { describe, expect, it } from "vitest"
import { getExplorerDragOverlayName } from "./explorer-drag-overlay"

describe("getExplorerDragOverlayName", () => {
it("prefers the display name when present", () => {
expect(
getExplorerDragOverlayName({
name: "note.md",
displayName: "note",
isDirectory: false,
}),
).toBe("note")
})

it("falls back to the source name when no display name is provided", () => {
expect(
getExplorerDragOverlayName({
name: "folder",
isDirectory: true,
}),
).toBe("folder")
})
})
5 changes: 5 additions & 0 deletions apps/desktop/src/components/dnd/explorer-drag-overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { cn } from "@mdit/ui/lib/utils"
import { ChevronRight } from "lucide-react"
import type { FileEntryDragData } from "./dnd-types"

type ExplorerDragOverlayProps = {
name: string
isDirectory: boolean
}

export function getExplorerDragOverlayName(data: FileEntryDragData): string {
return data.displayName ?? data.name ?? ""
}

function getExplorerDragOverlayClassName(isDirectory: boolean) {
return cn(
"pointer-events-none flex min-w-0 max-w-80 items-center gap-1 rounded-sm bg-transparent px-0 py-0 text-sm text-accent-foreground/95 shadow-none ring-0 outline-none border-0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ export function FileTreeNode({
}, [entry.isDirectory, entry.name])

const baseName = useMemo(() => {
if (entry.isDirectory || !extension) {
if (!extension) {
return entry.name
}

return entry.name.slice(0, entry.name.length - extension.length)
}, [entry.isDirectory, entry.name, extension])
return entry.name.slice(0, -extension.length)
}, [entry.name, extension])

const isMarkdown = useMemo(
() => !entry.isDirectory && extension.toLowerCase() === ".md",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { describe, expect, it } from "vitest"
import { getExplorerDragData } from "./use-tree-node-interactions"

describe("getExplorerDragData", () => {
it("includes an overlay display name without the file extension", () => {
expect(
getExplorerDragData({
path: "/notes/archive.tar.gz",
name: "archive.tar.gz",
isDirectory: false,
}),
).toEqual({
path: "/notes/archive.tar.gz",
name: "archive.tar.gz",
isDirectory: false,
displayName: "archive.tar",
})
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useDraggable } from "@dnd-kit/react"
import type { FileTreeRenderNode } from "@mdit/file-tree"
import { useCallback } from "react"
import type { FileEntryDragData } from "@/components/dnd/dnd-types"
import { useDraggedExplorerPaths } from "@/components/dnd/explorer-drag-state"
import type { WorkspaceEntry } from "@/store"
import { getExplorerEntryDisplayName } from "../utils/display-name"

type UseTreeNodeInteractionsParams = {
node: FileTreeRenderNode<WorkspaceEntry>
Expand All @@ -13,6 +15,15 @@ type UseTreeNodeInteractionsParams = {
onEntryContextMenu: (entry: WorkspaceEntry) => void | Promise<void>
}

export function getExplorerDragData(entry: WorkspaceEntry): FileEntryDragData {
return {
path: entry.path,
isDirectory: entry.isDirectory,
name: entry.name,
displayName: getExplorerEntryDisplayName(entry.name, entry.isDirectory),
}
}

export function useTreeNodeInteractions({
node,
onEntryPrimaryAction,
Expand All @@ -27,11 +38,7 @@ export function useTreeNodeInteractions({

const { ref: draggableRef, isDragging: isSourceDragging } = useDraggable({
id: entry.path,
data: {
path: entry.path,
isDirectory: entry.isDirectory,
name: entry.name,
},
data: getExplorerDragData(entry),
disabled: isBusy,
})
const isDragging = isSourceDragging || draggedExplorerPaths.has(entry.path)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest"
import { getExplorerEntryDisplayName } from "./display-name"

describe("getExplorerEntryDisplayName", () => {
it("strips the last file extension for files", () => {
expect(getExplorerEntryDisplayName("note.md", false)).toBe("note")
expect(getExplorerEntryDisplayName("archive.tar.gz", false)).toBe(
"archive.tar",
)
})

it("preserves dotfiles", () => {
expect(getExplorerEntryDisplayName(".env", false)).toBe(".env")
})

it("preserves directory names", () => {
expect(getExplorerEntryDisplayName("folder.with.dot", true)).toBe(
"folder.with.dot",
)
})
})
12 changes: 12 additions & 0 deletions apps/desktop/src/components/file-explorer/utils/display-name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getFileNameWithoutExtension } from "@mdit/utils/path-utils"

export function getExplorerEntryDisplayName(
name: string,
isDirectory: boolean,
): string {
if (isDirectory) {
return name
}

return getFileNameWithoutExtension(name)
}
Loading