@@ -1994,6 +1994,23 @@ function commentActivityAt(comment: PreviewComment): number {
19941994 ) ;
19951995}
19961996
1997+ function commentTargetIntersectsPreview (
1998+ target : PreviewCommentSnapshot | null ,
1999+ scale : number ,
2000+ offset : { x : number ; y : number } ,
2001+ bounds ?: PreviewCanvasSize ,
2002+ ) : boolean {
2003+ if ( ! target || ! bounds ?. width || ! bounds . height ) return true ;
2004+ const rect = overlayBoundsFromSnapshot ( target , scale , offset ) ;
2005+ const margin = 8 ;
2006+ return (
2007+ rect . left + rect . width > margin &&
2008+ rect . top + rect . height > margin &&
2009+ rect . left < bounds . width - margin &&
2010+ rect . top < bounds . height - margin
2011+ ) ;
2012+ }
2013+
19972014function commentDisplayLabel ( comment : PreviewComment , t : TranslateFn ) : string {
19982015 if ( comment . elementId . startsWith ( 'pin-' ) ) return t ( 'chat.comments.pin' ) ;
19992016 const label = String ( comment . label || '' ) . trim ( ) . toLowerCase ( ) ;
@@ -4956,7 +4973,7 @@ const [manualEditTargets, setManualEditTargets] = useState<ManualEditTarget[]>([
49564973 current
49574974 ? current . selectionKind === 'pod'
49584975 ? current
4959- : next . get ( current . elementId ) ?? null
4976+ : next . get ( current . elementId ) ?? current
49604977 : null
49614978 ) ) ;
49624979 setHoveredCommentTarget ( ( current ) => (
@@ -6017,6 +6034,16 @@ const [manualEditTargets, setManualEditTargets] = useState<ManualEditTarget[]>([
60176034 void exitManualEditModeAfterFlush ( ) ;
60186035 }
60196036
6037+ function returnToActiveCommentTarget ( ) {
6038+ if ( ! activeCommentTarget ) return ;
6039+ iframeRef . current ?. contentWindow ?. postMessage ( {
6040+ type : 'od:comment-scroll-to-target' ,
6041+ elementId : activeCommentTarget . elementId ,
6042+ selector : activeCommentTarget . selector ,
6043+ } , '*' ) ;
6044+ setHoveredCommentTarget ( activeCommentTarget ) ;
6045+ }
6046+
60206047 function queueCurrentDraft ( ) {
60216048 const note = commentDraft . trim ( ) ;
60226049 if ( ! note ) return ;
@@ -6129,6 +6156,16 @@ const [manualEditTargets, setManualEditTargets] = useState<ManualEditTarget[]>([
61296156 ? visibleSideComments . find ( ( comment ) => comment . elementId === activeCommentTarget . elementId ) ?. id ?? null
61306157 : null
61316158 ) ;
6159+ const activeCommentTargetVisible = commentTargetIntersectsPreview (
6160+ activeCommentTarget ,
6161+ overlayPreviewScale ,
6162+ { x : overlayPreviewTransform . offsetX , y : overlayPreviewTransform . offsetY } ,
6163+ previewBodySize ,
6164+ ) ;
6165+ const hoveredTargetHasSavedComment = Boolean (
6166+ hoveredCommentTarget &&
6167+ visibleSideComments . some ( ( comment ) => comment . elementId === hoveredCommentTarget . elementId ) ,
6168+ ) ;
61326169 useEffect ( ( ) => {
61336170 if ( ! boardMode || ! activePreviewCommentId ) return ;
61346171 const stillOpen = visibleSideComments . some ( ( comment ) => comment . id === activePreviewCommentId ) ;
@@ -6332,6 +6369,7 @@ const [manualEditTargets, setManualEditTargets] = useState<ManualEditTarget[]>([
63326369 offset = { { x : overlayPreviewTransform . offsetX , y : overlayPreviewTransform . offsetY } }
63336370 bounds = { previewBodySize }
63346371 docked = { false }
6372+ targetVisible = { activeCommentTargetVisible }
63356373 />
63366374 ) : null ;
63376375 const commentSidePanel = commentPanelOpen ? (
@@ -7023,7 +7061,18 @@ const [manualEditTargets, setManualEditTargets] = useState<ManualEditTarget[]>([
70237061 </ div >
70247062 ) : null }
70257063 { commentComposer }
7026- { boardMode && ! commentCreateMode && hoveredCommentTarget && ( ! activeCommentTarget || commentPortalHost ) ? (
7064+ { boardMode && activeCommentTarget && ! activeCommentTargetVisible ? (
7065+ < button
7066+ type = "button"
7067+ className = "comment-return-anchor"
7068+ data-testid = "comment-return-anchor"
7069+ onClick = { returnToActiveCommentTarget }
7070+ >
7071+ < span aria-hidden = "true" > 📍</ span >
7072+ < span > Return to element</ span >
7073+ </ button >
7074+ ) : null }
7075+ { boardMode && ! commentCreateMode && hoveredCommentTarget && ! hoveredTargetHasSavedComment && ( ! activeCommentTarget || commentPortalHost ) ? (
70277076 < AnnotationHoverPopover
70287077 target = { hoveredCommentTarget }
70297078 scale = { overlayPreviewScale }
0 commit comments