Sprint C#12: arrow-key prev/next on Identify face queue.
This commit is contained in:
@@ -851,6 +851,36 @@ export default function Identify() {
|
||||
return `Face ${currentIdx + 1} of ${faces.length}`
|
||||
}, [currentFace, currentIdx, faces.length])
|
||||
|
||||
const goToPrevFace = useCallback(() => {
|
||||
setCurrentIdx((i) => Math.max(0, i - 1))
|
||||
}, [])
|
||||
|
||||
const goToNextFace = useCallback(() => {
|
||||
setCurrentIdx((i) => Math.min(faces.length - 1, i + 1))
|
||||
}, [faces.length])
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTab !== 'faces' || faces.length === 0) return
|
||||
|
||||
const onKeyDown = (e: globalThis.KeyboardEvent) => {
|
||||
if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return
|
||||
if (e.altKey || e.ctrlKey || e.metaKey) return
|
||||
|
||||
const el = e.target as HTMLElement | null
|
||||
if (!el) return
|
||||
const tag = el.tagName
|
||||
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || tag === 'BUTTON') return
|
||||
if (el.isContentEditable) return
|
||||
|
||||
e.preventDefault()
|
||||
if (e.key === 'ArrowLeft') goToPrevFace()
|
||||
else goToNextFace()
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
return () => window.removeEventListener('keydown', onKeyDown)
|
||||
}, [activeTab, faces.length, goToPrevFace, goToNextFace])
|
||||
|
||||
const handleNextPage = () => {
|
||||
if (loadingFaces) return
|
||||
const nextPage = page + 1
|
||||
@@ -1336,8 +1366,9 @@ export default function Identify() {
|
||||
)}
|
||||
</div>
|
||||
<div className="space-x-2">
|
||||
<button className="px-2 py-1 text-sm border rounded" onClick={() => setCurrentIdx((i) => Math.max(0, i - 1))}>Prev</button>
|
||||
<button className="px-2 py-1 text-sm border rounded" onClick={() => setCurrentIdx((i) => Math.min(faces.length - 1, i + 1))}>Next</button>
|
||||
<button className="px-2 py-1 text-sm border rounded" onClick={goToPrevFace}>Prev</button>
|
||||
<button className="px-2 py-1 text-sm border rounded" onClick={goToNextFace}>Next</button>
|
||||
<span className="text-xs text-gray-500 align-middle">← → keys</span>
|
||||
<button
|
||||
className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed"
|
||||
onClick={() => {
|
||||
@@ -1529,8 +1560,8 @@ export default function Identify() {
|
||||
className={`px-3 py-2 rounded text-white ${canIdentify && !busy ? 'bg-indigo-600 hover:bg-indigo-700' : 'bg-gray-400 cursor-not-allowed'}`}>
|
||||
{busy ? 'Identifying...' : 'Identify'}
|
||||
</button>
|
||||
<button type="button" onClick={() => setCurrentIdx((i) => Math.max(0, i - 1))} className="px-3 py-2 rounded border">Back</button>
|
||||
<button type="button" onClick={() => setCurrentIdx((i) => Math.min(faces.length - 1, i + 1))} className="px-3 py-2 rounded border">Next</button>
|
||||
<button type="button" onClick={goToPrevFace} className="px-3 py-2 rounded border">Back</button>
|
||||
<button type="button" onClick={goToNextFace} className="px-3 py-2 rounded border">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user