/* eslint-disable @typescript-eslint/ban-ts-comment */ import { type DiffFile, getSplitLines } from "@git-diff-view/core"; import { removeAllSelection, diffFontSizeName, diffAsideWidthName } from "@git-diff-view/utils"; import { memo, useMemo, useRef } from "react"; // SEE https://github.com/facebook/react/pull/25231 // @ts-ignore import { useSyncExternalStore } from "use-sync-external-store/shim/index.js"; import { useTextWidth } from "../../hooks/useTextWidth"; import { SplitSide } from "../DiffView"; import { useDiffViewContext } from "../DiffViewContext"; import { DiffSplitViewLine } from "./DiffSplitViewLineWrap_v2"; import type { MouseEventHandler } from "react"; export const DiffSplitViewWrap = memo(({ diffFile }: { diffFile: DiffFile }) => { const splitLineLength = Math.max(diffFile.splitLineLength, diffFile.fileLineLength); const { useDiffContext } = useDiffViewContext(); const ref = useRef(null); const fontSize = useDiffContext.useShallowStableSelector((s) => s.fontSize); useSyncExternalStore(diffFile.subscribe, diffFile.getUpdateCount, diffFile.getUpdateCount); const font = useMemo(() => ({ fontSize: fontSize + "px", fontFamily: "Menlo, Consolas, monospace" }), [fontSize]); const _width = useTextWidth({ text: splitLineLength.toString(), font, }); const width = Math.max(40, _width + 25); const lines = getSplitLines(diffFile); const setStyle = (side?: SplitSide) => { if (!ref.current) return; if (!side) { ref.current.textContent = ""; } else { const id = `diff-root${diffFile.getId()}`; const targetSide = side === SplitSide.old ? SplitSide.new : SplitSide.old; ref.current.textContent = `#${id} [data-side="${SplitSide[targetSide]}"] {user-select: none} \n#${id} [data-state="extend"] {user-select: none} \n#${id} [data-state="hunk"] {user-select: none} \n#${id} [data-state="widget"] {user-select: none}`; } }; const onMouseDown: MouseEventHandler = (e) => { let ele: Element | null = e.target as Element; // need remove all the selection if (ele && ele instanceof HTMLElement && ele.nodeName === "BUTTON") { removeAllSelection(); return; } while (ele && ele instanceof HTMLElement) { const state = ele.getAttribute("data-state"); const side = ele.getAttribute("data-side") as unknown as SplitSide; if (side) { setStyle(SplitSide[side] as unknown as SplitSide); removeAllSelection(); } if (state) { if (state === "extend" || state === "hunk" || state === "widget") { setStyle(undefined); removeAllSelection(); return; } else { return; } } ele = ele.parentElement; } }; return (