Repository: GraphiteEditor/Graphite
File: frontend/src/components/panels/Layers.svelte (Svelte)

Code before:
	}

	function draggingKeyDown(e: KeyboardEvent) {
		if (e.key === "Escape" && internalDragState?.active) {
			justFinishedDrag = true;
			abortDrag();
		}
	}

	function handleLayerPanelKeyDown(e: KeyboardEvent) {
		// Only handle F2 if not currently editing a layer name
		if (e.key === "F2" && !isAnyLayerBeingEdited()) {
			// Find the first selected layer
			const selectedLayer = layers.find((layer) => layer.entry.selected);
			if (selectedLayer) {
				e.preventDefault();
				onEditLayerName(selectedLayer);
			}
		}
	}

	function isAnyLayerBeingEdited(): boolean {
		return layers.some((layer) => layer.editingName);
	}

	async function navigateToLayer(currentListing: LayerListingInfo, direction: "next" | "previous" | "up" | "down") {
		// Save the current layer name
		const inputElement = document.activeElement;
		if (inputElement instanceof HTMLInputElement) {
			const name = inputElement.value || "";
			editor.handle.setLayerName(currentListing.entry.id, name);
			currentListing.entry.alias = name;
		}

		// Find current layer index
		const currentIndex = layers.findIndex((layer) => layer.entry.id === currentListing.entry.id);
		if (currentIndex === -1) return;

		// Calculate target index based on direction
		let targetIndex: number;
		if (direction === "next" || direction === "down") {
			targetIndex = currentIndex + 1;
			if (targetIndex >= layers.length) return; // Don't wrap around at the end
		} else {
			// previous or up
			targetIndex = currentIndex - 1;
			if (targetIndex < 0) return; // Don't wrap around at the beginning
		}

		const targetListing = layers[targetIndex];
		if (!targetListing) return;

Review comment (suggestion):
I don't think there's any reason to have four instead of two directions, when each pair are just synonyms of each other. Just name them "Up" and "Down", with the first letter capitalized because these are the JS equivalent of Rust's enum variants which are also PascalCase.

Code after:
		if (list) draggingData = calculateDragIndex(list, e.clientY);
	}

	function fileDrop(e: DragEvent) {
		if (!draggingData || !e.dataTransfer || !e.dataTransfer.types.includes("Files")) return;

		const { insertParentId, insertIndex } = draggingData;

		e.preventDefault();

		Array.from(e.dataTransfer.items).forEach(async (item) => await pasteFile(item, editor, undefined, insertParentId, insertIndex));

		draggingData = undefined;
		fakeHighlightOfNotYetSelectedLayerBeingDragged = undefined;
		dragInPanel = false;
	}

	function rebuildLayerHierarchy(layerStructure: LayerStructureEntry[]) {
		const layerWithNameBeingEdited = layers.find((layer: LayerListingInfo) => layer.editingName);
		const layerIdWithNameBeingEdited = layerWithNameBeingEdited?.entry.id;

		// Clear the layer hierarchy before rebuilding it
		layers = [];

		// Build the new layer hierarchy
		const recurse = (children: LayerStructureEntry[]) => {
			children.forEach((item, index) => {
				const mapping = layerCache.get(String(item.layerId));
				if (mapping) {
					mapping.id = item.layerId;
					layers.push({
						folderIndex: index,
						bottomLayer: index === children.length - 1,
						entry: mapping,
						editingName: layerIdWithNameBeingEdited === item.layerId,
					});
				}

				// Call self recursively if there are any children
				if (item.children.length >= 1) recurse(item.children);
			});
		};
		recurse(layerStructure);
		layers = layers;
	}

	function updateLayerInTree(targetId: bigint, targetLayer: LayerPanelEntry) {
		layerCache.set(String(targetId), targetLayer);

		const layer = layers.find((layer: LayerListingInfo) => layer.entry.id === targetId);
		if (layer) {