From 8b581af7adb8ec08b8737b246af80abcc0ad4d5d Mon Sep 17 00:00:00 2001 From: Momentry Studio Date: Fri, 30 Oct 2026 19:52:10 +0800 Subject: [PATCH] fix: improve face detail navigation context matching - Simplified trace matching to use only trace_id (removed file_uuid requirement) - Added debug logging to trace navigation context setup - Added pointer-events: none to modal overlay to allow arrow clicks - Moved navigation arrows outside modal overlay for proper z-index stacking --- src/views/PeopleView.vue | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/views/PeopleView.vue b/src/views/PeopleView.vue index a856d88..f82d4f0 100644 --- a/src/views/PeopleView.vue +++ b/src/views/PeopleView.vue @@ -2523,44 +2523,63 @@ async function openFaceDetailFromTrace(t: any) { } function setFaceDetailNavContext(t: any) { + console.log('[nav] setFaceDetailNavContext called for trace:', t.trace_id, 'file_uuid:', t.file_uuid) + console.log('[nav] traceGroupMap keys:', Object.keys(traceGroupMap.value).length) + console.log('[nav] clusterResults:', clusterResults.value.length) + console.log('[nav] filteredUnassignedTraces:', filteredUnassignedTraces.value.length) + // The trace's own group takes priority — navigation is limited to that group const groupName = traceGroupMap.value[String(t.trace_id)] + console.log('[nav] groupName for trace:', t.trace_id, '=', groupName) + if (groupName) { const cluster = clusterResults.value.find((c: any) => c.name === groupName) + console.log('[nav] cluster found:', !!cluster) if (cluster) { const traces = filteredGroupTraces(cluster) + console.log('[nav] filteredGroupTraces count:', traces.length) const cIdx = traces.findIndex((x: any) => x.trace_id === t.trace_id) + console.log('[nav] findIndex result:', cIdx) if (cIdx >= 0) { faceDetailNavSource.value = 'cluster' faceDetailNavIndex.value = cIdx + console.log('[nav] cluster context:', { source: 'cluster', index: cIdx, total: traces.length }) return } } } // Truly unassigned traces (already filtered out grouped ones), filter-aware + console.log('[nav] filteredUnassignedTraces sample:', filteredUnassignedTraces.value.slice(0, 2)) const uIdx = filteredUnassignedTraces.value.findIndex( - (x: any) => x.trace_id === t.trace_id && x.file_uuid === t.file_uuid + (x: any) => x.trace_id === t.trace_id ) + console.log('[nav] unassigned findIndex result:', uIdx) if (uIdx >= 0) { faceDetailNavSource.value = 'unassigned' faceDetailNavIndex.value = uIdx + console.log('[nav] unassigned context:', { source: 'unassigned', index: uIdx, total: filteredUnassignedTraces.value.length }) return } faceDetailNavSource.value = null faceDetailNavIndex.value = -1 + console.log('[nav] no context:', { source: null, index: -1, unassigned: filteredUnassignedTraces.value.length, clusterResults: clusterResults.value.length }) } function goFaceDetailPrev() { + console.log('[nav] goFaceDetailPrev called, canFaceDetailPrev:', canFaceDetailPrev.value, 'index:', faceDetailNavIndex.value, 'list:', faceDetailNavList.value.length) if (!canFaceDetailPrev.value) return faceDetailNavIndex.value-- const prev = faceDetailNavList.value[faceDetailNavIndex.value] + console.log('[nav] goFaceDetailPrev prev:', prev?.trace_id) if (prev) openFaceDetailFromTrace(prev) } function goFaceDetailNext() { + console.log('[nav] goFaceDetailNext called, canFaceDetailNext:', canFaceDetailNext.value, 'index:', faceDetailNavIndex.value, 'list:', faceDetailNavList.value.length) if (!canFaceDetailNext.value) return faceDetailNavIndex.value++ const next = faceDetailNavList.value[faceDetailNavIndex.value] + console.log('[nav] goFaceDetailNext next:', next?.trace_id) if (next) openFaceDetailFromTrace(next) } @@ -2779,6 +2798,7 @@ function faceCtxAction(action: string) { faceCtxMenu.value.show = false if (action === 'detail') { faceDetailModal.value = { show: true, candidate: c, newIdentityName: '' } + setFaceDetailNavContext(c) loadCandidateThumb(c) } } @@ -4210,8 +4230,9 @@ h1 { margin: 0; } .ms-ctx-history-btn { padding: 2px 6px !important; font-size: 12px !important; min-width: 24px; } /* Modal overlay */ -.ms-modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 9998; align-items: center; justify-content: center; } +.ms-modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 9998; align-items: center; justify-content: center; pointer-events: none; } .ms-modal-overlay.show { display: flex; } +.ms-modal-overlay .ms-modal { pointer-events: auto; } .close-btn { position: absolute; top: 16px; right: 16px; } .fs-delete-btn { position: absolute; top: 16px; right: 56px; color: var(--text-secondary); } .fs-delete-btn:hover { color: var(--danger-color); }