feat: publish HoloLake model-native living system source
This commit is contained in:
parent
6ad10edde1
commit
c395dd3a99
2467 changed files with 615073 additions and 0 deletions
288
product-source/hololake-platform/src/hooks/useDiffMode.ts
Normal file
288
product-source/hololake-platform/src/hooks/useDiffMode.ts
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useRef,
|
||||
useMemo,
|
||||
type Dispatch,
|
||||
type SetStateAction,
|
||||
} from 'react'
|
||||
|
||||
export interface CommitDiffRequest {
|
||||
requestId: number
|
||||
path: string
|
||||
commitHash?: string | null
|
||||
}
|
||||
|
||||
interface UseDiffModeParams {
|
||||
activeTabPath: string | null
|
||||
onLoadDiff?: (path: string) => Promise<string>
|
||||
onLoadDiffAtCommit?: (path: string, commitHash: string) => Promise<string>
|
||||
pendingCommitDiffRequest?: CommitDiffRequest | null
|
||||
onPendingCommitDiffHandled?: (requestId: number) => void
|
||||
}
|
||||
|
||||
interface DiffStateSetters {
|
||||
setDiffMode: Dispatch<SetStateAction<boolean>>
|
||||
setDiffContent: Dispatch<SetStateAction<string | null>>
|
||||
setDiffLoading: Dispatch<SetStateAction<boolean>>
|
||||
setDiffPath: Dispatch<SetStateAction<string | null>>
|
||||
}
|
||||
|
||||
type DiffLoadCancellation = { current: boolean }
|
||||
|
||||
function useDiffLoadCancellation() {
|
||||
const activeDiffLoadRef = useRef<DiffLoadCancellation | null>(null)
|
||||
|
||||
const cancelActiveDiffLoad = useCallback(() => {
|
||||
if (!activeDiffLoadRef.current) return
|
||||
activeDiffLoadRef.current.current = true
|
||||
activeDiffLoadRef.current = null
|
||||
}, [])
|
||||
|
||||
const createDiffLoadCancellation = useCallback(() => {
|
||||
cancelActiveDiffLoad()
|
||||
const cancellation = { current: false }
|
||||
activeDiffLoadRef.current = cancellation
|
||||
return cancellation
|
||||
}, [cancelActiveDiffLoad])
|
||||
|
||||
const clearDiffLoadCancellation = useCallback((cancellation: DiffLoadCancellation) => {
|
||||
if (activeDiffLoadRef.current === cancellation) {
|
||||
activeDiffLoadRef.current = null
|
||||
}
|
||||
}, [])
|
||||
|
||||
return {
|
||||
cancelActiveDiffLoad,
|
||||
createDiffLoadCancellation,
|
||||
clearDiffLoadCancellation,
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDiffForPath(
|
||||
path: string,
|
||||
onLoadDiff: ((path: string) => Promise<string>) | undefined,
|
||||
{ setDiffMode, setDiffContent, setDiffLoading, setDiffPath }: DiffStateSetters,
|
||||
) {
|
||||
if (!onLoadDiff) return
|
||||
setDiffLoading(true)
|
||||
try {
|
||||
const diff = await onLoadDiff(path)
|
||||
setDiffContent(diff)
|
||||
setDiffPath(path)
|
||||
setDiffMode(true)
|
||||
} catch (err) {
|
||||
console.warn('Failed to load diff:', err)
|
||||
} finally {
|
||||
setDiffLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCommitDiffForPath(
|
||||
path: string,
|
||||
commitHash: string,
|
||||
onLoadDiffAtCommit: ((path: string, commitHash: string) => Promise<string>) | undefined,
|
||||
{ setDiffMode, setDiffContent, setDiffLoading, setDiffPath }: DiffStateSetters,
|
||||
) {
|
||||
if (!onLoadDiffAtCommit) return
|
||||
setDiffLoading(true)
|
||||
try {
|
||||
const diff = await onLoadDiffAtCommit(path, commitHash)
|
||||
setDiffContent(diff)
|
||||
setDiffPath(path)
|
||||
setDiffMode(true)
|
||||
} catch (err) {
|
||||
console.warn('Failed to load commit diff:', err)
|
||||
} finally {
|
||||
setDiffLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
function shouldHandlePendingCommitDiffRequest(
|
||||
activeTabPath: string | null,
|
||||
pendingCommitDiffRequest: CommitDiffRequest | null | undefined,
|
||||
): pendingCommitDiffRequest is CommitDiffRequest {
|
||||
return !!pendingCommitDiffRequest && pendingCommitDiffRequest.path === activeTabPath
|
||||
}
|
||||
|
||||
function hasCommitHash(pendingCommitDiffRequest: CommitDiffRequest): pendingCommitDiffRequest is CommitDiffRequest & { commitHash: string } {
|
||||
return typeof pendingCommitDiffRequest.commitHash === 'string' && pendingCommitDiffRequest.commitHash.length > 0
|
||||
}
|
||||
|
||||
function buildGuardedDiffStateSetters(
|
||||
cancelledRef: DiffLoadCancellation,
|
||||
{ setDiffMode, setDiffContent, setDiffLoading, setDiffPath }: DiffStateSetters,
|
||||
): DiffStateSetters {
|
||||
return {
|
||||
setDiffMode: (value) => { if (!cancelledRef.current) setDiffMode(value) },
|
||||
setDiffContent: (value) => { if (!cancelledRef.current) setDiffContent(value) },
|
||||
setDiffLoading: (value) => { if (!cancelledRef.current) setDiffLoading(value) },
|
||||
setDiffPath: (value) => { if (!cancelledRef.current) setDiffPath(value) },
|
||||
}
|
||||
}
|
||||
|
||||
function closeDiffMode(activeTabPath: string | null, {
|
||||
setDiffMode,
|
||||
setDiffContent,
|
||||
setDiffLoading,
|
||||
setDiffPath,
|
||||
}: DiffStateSetters) {
|
||||
setDiffPath(activeTabPath)
|
||||
setDiffMode(false)
|
||||
setDiffContent(null)
|
||||
setDiffLoading(false)
|
||||
}
|
||||
|
||||
function runPendingCommitDiffRequest(
|
||||
pendingCommitDiffRequest: CommitDiffRequest,
|
||||
onLoadDiff: ((path: string) => Promise<string>) | undefined,
|
||||
onLoadDiffAtCommit: ((path: string, commitHash: string) => Promise<string>) | undefined,
|
||||
onPendingCommitDiffHandled: ((requestId: number) => void) | undefined,
|
||||
diffState: DiffStateSetters,
|
||||
) {
|
||||
const cancelledRef = { current: false }
|
||||
|
||||
const loadDiffPromise = hasCommitHash(pendingCommitDiffRequest)
|
||||
? loadCommitDiffForPath(
|
||||
pendingCommitDiffRequest.path,
|
||||
pendingCommitDiffRequest.commitHash,
|
||||
onLoadDiffAtCommit,
|
||||
buildGuardedDiffStateSetters(cancelledRef, diffState),
|
||||
)
|
||||
: loadDiffForPath(
|
||||
pendingCommitDiffRequest.path,
|
||||
onLoadDiff,
|
||||
buildGuardedDiffStateSetters(cancelledRef, diffState),
|
||||
)
|
||||
|
||||
void loadDiffPromise.finally(() => {
|
||||
if (cancelledRef.current) return
|
||||
onPendingCommitDiffHandled?.(pendingCommitDiffRequest.requestId)
|
||||
})
|
||||
|
||||
return () => {
|
||||
cancelledRef.current = true
|
||||
}
|
||||
}
|
||||
|
||||
function usePendingCommitDiffRequest({
|
||||
activeTabPath,
|
||||
onLoadDiff,
|
||||
onLoadDiffAtCommit,
|
||||
pendingCommitDiffRequest,
|
||||
onPendingCommitDiffHandled,
|
||||
setDiffMode,
|
||||
setDiffContent,
|
||||
setDiffLoading,
|
||||
setDiffPath,
|
||||
}: UseDiffModeParams & DiffStateSetters) {
|
||||
useEffect(() => {
|
||||
if (!shouldHandlePendingCommitDiffRequest(activeTabPath, pendingCommitDiffRequest)) return
|
||||
if (hasCommitHash(pendingCommitDiffRequest) && !onLoadDiffAtCommit) {
|
||||
onPendingCommitDiffHandled?.(pendingCommitDiffRequest.requestId)
|
||||
return
|
||||
}
|
||||
if (!hasCommitHash(pendingCommitDiffRequest) && !onLoadDiff) {
|
||||
onPendingCommitDiffHandled?.(pendingCommitDiffRequest.requestId)
|
||||
return
|
||||
}
|
||||
|
||||
return runPendingCommitDiffRequest(
|
||||
pendingCommitDiffRequest,
|
||||
onLoadDiff,
|
||||
onLoadDiffAtCommit,
|
||||
onPendingCommitDiffHandled,
|
||||
{ setDiffMode, setDiffContent, setDiffLoading, setDiffPath },
|
||||
)
|
||||
}, [activeTabPath, onLoadDiff, onLoadDiffAtCommit, onPendingCommitDiffHandled, pendingCommitDiffRequest, setDiffContent, setDiffLoading, setDiffMode, setDiffPath])
|
||||
}
|
||||
|
||||
function useDiffPathReset(
|
||||
activeTabPath: string | null,
|
||||
cancelActiveDiffLoad: () => void,
|
||||
diffState: DiffStateSetters,
|
||||
) {
|
||||
useEffect(() => {
|
||||
cancelActiveDiffLoad()
|
||||
closeDiffMode(activeTabPath, diffState)
|
||||
}, [activeTabPath, cancelActiveDiffLoad, diffState])
|
||||
}
|
||||
|
||||
function useCancelDiffLoadOnUnmount(cancelActiveDiffLoad: () => void) {
|
||||
useEffect(() => () => cancelActiveDiffLoad(), [cancelActiveDiffLoad])
|
||||
}
|
||||
|
||||
export function useDiffMode({
|
||||
activeTabPath,
|
||||
onLoadDiff,
|
||||
onLoadDiffAtCommit,
|
||||
pendingCommitDiffRequest,
|
||||
onPendingCommitDiffHandled,
|
||||
}: UseDiffModeParams) {
|
||||
const [diffMode, setDiffMode] = useState(false)
|
||||
const [diffContent, setDiffContent] = useState<string | null>(null)
|
||||
const [diffLoading, setDiffLoading] = useState(false)
|
||||
const [diffPath, setDiffPath] = useState<string | null>(activeTabPath)
|
||||
const diffState = useMemo(() => ({
|
||||
setDiffMode,
|
||||
setDiffContent,
|
||||
setDiffLoading,
|
||||
setDiffPath,
|
||||
}), [])
|
||||
const {
|
||||
cancelActiveDiffLoad,
|
||||
createDiffLoadCancellation,
|
||||
clearDiffLoadCancellation,
|
||||
} = useDiffLoadCancellation()
|
||||
|
||||
useDiffPathReset(activeTabPath, cancelActiveDiffLoad, diffState)
|
||||
useCancelDiffLoadOnUnmount(cancelActiveDiffLoad)
|
||||
|
||||
usePendingCommitDiffRequest({
|
||||
activeTabPath,
|
||||
onLoadDiff,
|
||||
onLoadDiffAtCommit,
|
||||
pendingCommitDiffRequest,
|
||||
onPendingCommitDiffHandled,
|
||||
setDiffMode,
|
||||
setDiffContent,
|
||||
setDiffLoading,
|
||||
setDiffPath,
|
||||
})
|
||||
|
||||
const isDiffVisible = diffMode && diffPath === activeTabPath
|
||||
|
||||
const handleToggleDiff = useCallback(async () => {
|
||||
if (isDiffVisible) {
|
||||
cancelActiveDiffLoad()
|
||||
closeDiffMode(activeTabPath, diffState)
|
||||
return
|
||||
}
|
||||
if (!activeTabPath || !onLoadDiff) return
|
||||
const cancellation = createDiffLoadCancellation()
|
||||
try {
|
||||
await loadDiffForPath(activeTabPath, onLoadDiff, buildGuardedDiffStateSetters(cancellation, diffState))
|
||||
} finally {
|
||||
clearDiffLoadCancellation(cancellation)
|
||||
}
|
||||
}, [activeTabPath, cancelActiveDiffLoad, clearDiffLoadCancellation, createDiffLoadCancellation, diffState, isDiffVisible, onLoadDiff])
|
||||
|
||||
const handleViewCommitDiff = useCallback(async (commitHash: string) => {
|
||||
if (!activeTabPath) return
|
||||
const cancellation = createDiffLoadCancellation()
|
||||
try {
|
||||
await loadCommitDiffForPath(activeTabPath, commitHash, onLoadDiffAtCommit, buildGuardedDiffStateSetters(cancellation, diffState))
|
||||
} finally {
|
||||
clearDiffLoadCancellation(cancellation)
|
||||
}
|
||||
}, [activeTabPath, clearDiffLoadCancellation, createDiffLoadCancellation, diffState, onLoadDiffAtCommit])
|
||||
|
||||
return {
|
||||
diffMode: isDiffVisible,
|
||||
diffContent: isDiffVisible ? diffContent : null,
|
||||
diffLoading,
|
||||
handleToggleDiff,
|
||||
handleViewCommitDiff,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue