refactor: Unify document selection and drag interactions by replacing stack-specific callbacks and simplifying drag state.

This commit is contained in:
2025-11-25 20:54:53 +01:00
parent 13c87f4b07
commit e0fce40bc3
10 changed files with 279 additions and 267 deletions
+36 -33
View File
@@ -171,6 +171,8 @@ interface DesktopWorkspaceViewProps extends Omit<DocumentsViewProps, 'entries' |
recalcVisibleDocIds: () => void;
dragSettings: DragSettings;
markLayoutDirty: () => void;
onSelect?: (descriptor: unknown, event?: unknown) => void;
onPromoteSelection?: (docId: Identifier, event?: unknown) => void;
}
const defaultGetDocumentAsset: GetAsset = () => null;
@@ -192,6 +194,7 @@ const DesktopWorkspace: React.FC<DocumentsViewProps> = ({
clearSelection,
handleEntrySelection,
promoteSelectionOrder,
configureSelectionEnvironment,
} = useWorkspaceSelectionContext();
const items = useMemo<DeskDocument[]>(
() => {
@@ -213,36 +216,16 @@ const DesktopWorkspace: React.FC<DocumentsViewProps> = ({
[entries],
);
const getDocRowKey = useCallback((id: Identifier | null) => (id != null ? `document:${id}` : null), []);
const handleStackSelect = useCallback(
(docIds: Identifier[], event?: PointerEvent | MouseEvent | null) => {
if (!Array.isArray(docIds) || docIds.length === 0) {
return;
}
const syntheticEvent = event || ({
metaKey: true,
ctrlKey: true,
preventDefault: () => { },
} as unknown as PointerEvent);
docIds.forEach((id) => {
const key = getDocRowKey(id);
if (key) {
handleEntrySelection(key, syntheticEvent);
}
});
},
[getDocRowKey, handleEntrySelection],
);
const getDocEntryKey = useCallback((id: Identifier | null) => (id != null ? `document:${id}` : null), []);
const handlePromoteSelection = useCallback(
(docId: Identifier | null) => {
const key = getDocRowKey(docId);
if (key && promoteSelectionOrder) {
promoteSelectionOrder(key);
const key = getDocEntryKey(docId);
if (key) {
promoteSelectionOrder(docId);
}
},
[getDocRowKey, promoteSelectionOrder],
[getDocEntryKey, promoteSelectionOrder],
);
const allowLayoutPersistence = Boolean(tenantId && viewId && viewId.startsWith('folder:'));
@@ -307,10 +290,6 @@ const DesktopWorkspace: React.FC<DocumentsViewProps> = ({
engine.setDocumentLookup(map);
}, [engine, items]);
useEffect(() => {
engine.setEnsureDocumentSize(ensureDocumentSize);
}, [engine, ensureDocumentSize]);
const workspaceSnapshot = useWorkspaceSnapshot(engine, useSyncExternalStore) as WorkspaceSnapshotState;
const {
layout: layoutSnapshot,
@@ -323,6 +302,19 @@ const DesktopWorkspace: React.FC<DocumentsViewProps> = ({
initialLoadDone,
} = workspaceSnapshot;
useEffect(() => {
const visibleEntryKeySet = new Set<string>();
visibleDocIds.forEach((id) => {
const key = getDocEntryKey(id);
if (key) visibleEntryKeySet.add(key);
});
configureSelectionEnvironment({
visibleEntryKeySet,
navigableEntryKeys: [], // Desktop doesn't have linear navigation yet
});
}, [visibleDocIds, getDocEntryKey, configureSelectionEnvironment]);
useEffect(() => {
const shouldWaitForPersisted = allowLayoutPersistence && !initialLoadDone;
@@ -794,10 +786,22 @@ const DesktopWorkspace: React.FC<DocumentsViewProps> = ({
overlayOriginRect,
overlayOriginTransform,
overlayDocument,
onDocumentStackSelect: handleStackSelect,
onPromoteSelection: handlePromoteSelection,
selectedDocumentIds,
onClearSelection: clearSelection,
onDocumentClick: passThroughProps.onDocumentClick,
onSelect: (descriptorOrDescriptors: any, event: any) => {
const descriptors = Array.isArray(descriptorOrDescriptors)
? descriptorOrDescriptors
: [descriptorOrDescriptors];
const keys = descriptors
.map((d: any) => getDocEntryKey(d.id))
.filter((k: any) => k);
if (keys.length > 0) {
handleEntrySelection(keys, event);
}
},
documentLookup,
resolveBaseMetrics,
bringToFront,
@@ -836,7 +840,6 @@ function DesktopWorkspaceView({
overlayOriginTransform,
overlayDocument,
onDocumentClick,
onDocumentStackSelect,
onPromoteSelection,
selectedDocumentIds,
onClearSelection,
@@ -850,6 +853,7 @@ function DesktopWorkspaceView({
dragSettings,
onDocumentActivate,
markLayoutDirty,
onSelect,
}: DesktopWorkspaceViewProps) {
const handleDeskDocumentActivate = useCallback(
(docId: Identifier) => {
@@ -888,7 +892,6 @@ function DesktopWorkspaceView({
settings: dragSettings,
containerRef,
onDocumentActivate: handleDeskDocumentActivate,
selectedDocumentIds,
markLayoutDirty,
}) as {
handlePointerDown: React.PointerEventHandler<HTMLElement>;
@@ -908,11 +911,11 @@ function DesktopWorkspaceView({
handlePointerUp,
handlePointerCancel,
onDocumentClick: handleDeskDocumentClick,
onDocumentStackSelect,
onPromoteSelection,
onDocumentActivate: handleDeskDocumentActivate,
selectedDocumentIds,
openOverlayForDoc,
onSelect,
});
useEffect(() => {