|
9 | 9 | import { move } from "@dnd-kit/helpers"; |
10 | 10 | import { BackgroundByLayers } from "libs/ui/svelte/components/BackgroundByLayers"; |
11 | 11 | import { t } from "../i18n/index.ts"; |
12 | | - import { dockState } from "../state/items.svelte.ts"; |
| 12 | + import { |
| 13 | + dockState, |
| 14 | + HARDCODED_SEPARATOR_LEFT, |
| 15 | + HARDCODED_SEPARATOR_RIGHT, |
| 16 | + } from "../state/items.svelte.ts"; |
13 | 17 | import { settingsState } from "../state/settings.svelte.ts"; |
14 | 18 | import { systemState } from "../state/system.svelte.ts"; |
15 | 19 | import { interactables, getWindowsForItem } from "../state/windows.svelte.ts"; |
16 | 20 | import { dockShouldBeHidden, setDockIsDraggingItem } from "../state/hidden.svelte.ts"; |
17 | 21 | import { getSeelenWegMenu } from "../dockMenu.ts"; |
18 | 22 | import { DND_PLUGINS, DND_SENSORS } from "libs/ui/dnd.ts"; |
19 | | - import DraggableItem from "./DraggableItem.svelte"; |
| 23 | + import type { SwItem } from "../types.ts"; |
| 24 | + import DockItemsGroup from "./DockItemsGroup.svelte"; |
20 | 25 | import WegItemSwitch from "./WegItemSwitch.svelte"; |
21 | 26 |
|
22 | 27 | const settings = $derived(settingsState.value as any); |
23 | 28 | const isHorizontal = $derived( |
24 | 29 | settings?.position === "Top" || settings?.position === "Bottom", |
25 | 30 | ); |
26 | 31 |
|
27 | | - const visibleItems = $derived.by(() => { |
| 32 | + function isItemVisible(item: SwItem): boolean { |
28 | 33 | const pinnedVisibility = settings?.pinnedItemsVisibility as WegPinnedItemsVisibility; |
29 | 34 | const temporalVisibility = settings?.temporalItemsVisibility as WegTemporalItemsVisibility; |
30 | 35 | const monitor = systemState.currentMonitor; |
|
38 | 43 | ? interactables.value.filter((w) => w.monitor === monitor.id) |
39 | 44 | : interactables.value; |
40 | 45 |
|
41 | | - return dockState.items.filter((item) => { |
42 | | - if (item.type !== "AppOrFile") { |
43 | | - return showPinned; |
44 | | - } |
45 | | - if (item.pinned && showPinned) { |
46 | | - return true; |
47 | | - } |
48 | | - return getWindowsForItem(item as any, windows).length > 0; |
49 | | - }); |
| 46 | + if (item.type !== "AppOrFile") { |
| 47 | + return showPinned; |
| 48 | + } |
| 49 | + if (item.pinned && showPinned) { |
| 50 | + return true; |
| 51 | + } |
| 52 | + return getWindowsForItem(item as any, windows).length > 0; |
| 53 | + } |
| 54 | +
|
| 55 | + // splits the flat items array (left..., left-separator, center..., right-separator, ...right) |
| 56 | + // into their three groups, same as the toolbar does |
| 57 | + const groupedItems = $derived.by(() => { |
| 58 | + const items = dockState.items; |
| 59 | + const idx1 = items.findIndex((i) => i.id === HARDCODED_SEPARATOR_LEFT.id); |
| 60 | + const idx2 = items.findIndex((i) => i.id === HARDCODED_SEPARATOR_RIGHT.id); |
| 61 | + return { |
| 62 | + left: items.slice(0, idx1), |
| 63 | + center: items.slice(idx1, idx2 + 1), |
| 64 | + right: items.slice(idx2 + 1), |
| 65 | + }; |
50 | 66 | }); |
51 | 67 |
|
| 68 | + const visibleGroupedItems = $derived.by(() => ({ |
| 69 | + left: groupedItems.left.filter(isItemVisible), |
| 70 | + center: groupedItems.center.filter(isItemVisible), |
| 71 | + right: groupedItems.right.filter(isItemVisible), |
| 72 | + })); |
| 73 | +
|
52 | 74 | const isEmpty = $derived( |
53 | | - visibleItems.filter((c) => c.type !== "Separator").length === 0, |
| 75 | + [ |
| 76 | + ...visibleGroupedItems.left, |
| 77 | + ...visibleGroupedItems.center, |
| 78 | + ...visibleGroupedItems.right, |
| 79 | + ].filter((c) => c.type !== "Separator").length === 0, |
54 | 80 | ); |
55 | 81 |
|
| 82 | + const itemIndexById = $derived.by(() => { |
| 83 | + const map = new Map<string, number>(); |
| 84 | + dockState.items.forEach((item, i) => map.set(item.id, i)); |
| 85 | + return map; |
| 86 | + }); |
| 87 | +
|
56 | 88 | function onContextMenu() { |
57 | 89 | const alignX = settingsState.popupAlignX; |
58 | 90 | const alignY = settingsState.popupAlignY; |
|
100 | 132 | {#if isEmpty} |
101 | 133 | <span class="weg-empty-state-label">{$t("weg.empty")}</span> |
102 | 134 | {:else} |
103 | | - {#each visibleItems as item, index (item.id)} |
104 | | - <DraggableItem {item} {index}> |
105 | | - <WegItemSwitch {item} /> |
106 | | - </DraggableItem> |
107 | | - {/each} |
| 135 | + <DockItemsGroup id="left" items={visibleGroupedItems.left} {itemIndexById} /> |
| 136 | + <DockItemsGroup id="center" items={visibleGroupedItems.center} {itemIndexById} /> |
| 137 | + <DockItemsGroup id="right" items={visibleGroupedItems.right} {itemIndexById} /> |
108 | 138 | {/if} |
109 | 139 | </div> |
110 | 140 |
|
111 | 141 | <DragOverlay> |
112 | 142 | {#snippet children(source)} |
113 | | - {@const overlayItem = visibleItems.find((c) => c.id === source.id)} |
| 143 | + {@const overlayItem = dockState.items.find((c) => c.id === source.id)} |
114 | 144 | {#if overlayItem} |
115 | 145 | <WegItemSwitch item={overlayItem} isOverlay={true} /> |
116 | 146 | {/if} |
|
0 commit comments