Files
orca/mobile/src/session/use-mobile-diff-review-diff-loading.ts
T
Kelvin Amoaba 9d2e441947 fix(mobile): compare branches and show diffs with desktop's base-ref and whitespace settings (#34038)
* fix(mobile): compare branches and show diffs with desktop's base-ref and whitespace settings

Base-ref resolution moves to src/shared and the host publishes the compare-against-upstream
and show-whitespace settings, so the phone's branch compare and diffs match desktop.

* fix(mobile): use the upstream compare policy on the review screen and rebuild diffs when whitespace changes

* fix(mobile): reread Source Control settings on Refresh and restart diffs loading under the old whitespace setting

* test(mobile): cover diffs dropped when desktop's whitespace setting arrives

* refactor(mobile): share one Source Control settings read per host across screens
2026-10-27 05:29:46 +00:00

89 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useRef, useState } from 'react'
import type { ConnectionState } from '../transport/types'
import type { RpcClient } from '../transport/rpc-client'
import { loadMobileDiffReviewDiff } from './mobile-diff-review-loaders'
import { shouldIgnoreTrimWhitespace } from '../../../src/shared/diff-whitespace'
import { useMobileSourceControlSettings } from '../source-control/mobile-source-control-settings'
import type { MobileDiffReviewQueueItem } from './mobile-diff-review-queue'
import type { ReviewDiffState, ReviewScreenState } from './mobile-diff-review-screen-model'
type DiffLoadingInput = {
client: RpcClient | null
connState: ConnectionState
worktreeId: string
currentItem: MobileDiffReviewQueueItem | null
screenState: ReviewScreenState
setActiveHunkIndex: (index: number | null) => void
}
// Retain loaded same-item diffs through transport blips so reconnect cannot erase the reader’s context.
export function useMobileDiffReviewDiffLoading(input: DiffLoadingInput): ReviewDiffState {
const { client, connState, worktreeId, currentItem, screenState, setActiveHunkIndex } = input
const [diffState, setDiffState] = useState<ReviewDiffState>({ kind: 'idle' })
const { diffShowWhitespace } = useMobileSourceControlSettings(client, connState).settings
const hunkResetKeyRef = useRef<string | null>(null)
// Depend on fields read, not screen-state identity, to avoid duplicate diff requests.
const screenReady = screenState.kind === 'ready'
const branchCompare = screenState.kind === 'ready' ? screenState.branchCompare : null
useEffect(() => {
// Only item changes reset hunk position; reconnect also reruns this effect.
const hunkKey = currentItem?.key ?? null
if (hunkResetKeyRef.current !== hunkKey) {
hunkResetKeyRef.current = hunkKey
setActiveHunkIndex(null)
}
if (!currentItem || !screenReady) {
setDiffState({ kind: 'idle' })
return
}
const itemKey = currentItem.key
const keepLoadedDiff = (fallback: ReviewDiffState) => (prev: ReviewDiffState) =>
prev.kind === 'ready' && prev.itemKey === itemKey ? prev : fallback
if (!client || connState !== 'connected') {
setDiffState(keepLoadedDiff({ kind: 'error', itemKey, message: 'Waiting for desktop...' }))
return
}
let stale = false
setDiffState(keepLoadedDiff({ kind: 'loading', itemKey }))
void loadMobileDiffReviewDiff({
client,
worktreeId,
item: currentItem,
branchCompare,
ignoreTrimWhitespace: shouldIgnoreTrimWhitespace(diffShowWhitespace)
})
.then((nextState) => {
if (!stale) {
setDiffState(nextState)
}
})
.catch((err: unknown) => {
if (!stale) {
// Failed reconnect reads must not erase loaded diff content.
setDiffState(
keepLoadedDiff({
kind: 'error',
itemKey,
message: err instanceof Error ? err.message : 'Unable to load diff'
})
)
}
})
return () => {
stale = true
}
}, [
client,
connState,
currentItem,
screenReady,
branchCompare,
diffShowWhitespace,
setActiveHunkIndex,
worktreeId
])
return diffState
}