@@ -10,20 +10,51 @@ import {
1010} from 'platform-bible-react' ;
1111import { useCallback , useEffect , useMemo , useState } from 'react' ;
1212import { useLocalizedStrings , useProjectData , useProjectDataProvider } from '@papi/frontend/react' ;
13- import { isPlatformError , LegacyCommentThread } from 'platform-bible-utils' ;
13+ import { isPlatformError , LegacyCommentThread , serialize } from 'platform-bible-utils' ;
1414
1515const DEFAULT_LEGACY_COMMENT_THREADS : LegacyCommentThread [ ] = [ ] ;
1616
17+ /** Message types that can be received from the Comment List web view controller */
18+ type CommentListWebViewMessage = {
19+ method : 'scrollToThread' ;
20+ threadId : string ;
21+ } ;
22+
1723global . webViewComponent = function CommentListWebView ( {
1824 useWebViewScrollGroupScrRef,
1925 projectId,
2026} : WebViewProps ) {
2127 const [ localizedStrings ] = useLocalizedStrings ( COMMENT_LIST_STRING_KEYS ) ;
2228 const [ scrRef ] = useWebViewScrollGroupScrRef ( ) ;
2329 const [ currentUserName , setCurrentUserName ] = useState < string > ( '' ) ;
30+ const [ selectedThreadId , setSelectedThreadId ] = useState < string | undefined > ( undefined ) ;
2431
2532 const commentsPdp = useProjectDataProvider ( 'legacyCommentManager.comments' , projectId ) ;
2633
34+ // Listen for messages from the web view controller
35+ useEffect ( ( ) => {
36+ const messageListener = ( { data } : MessageEvent < CommentListWebViewMessage > ) => {
37+ if ( data . method === 'scrollToThread' ) {
38+ logger . debug ( `Comment list received scrollToThread message: ${ serialize ( data ) } ` ) ;
39+ const { threadId } = data ;
40+
41+ // Find the thread element and scroll to it
42+ const threadElement = document . getElementById ( threadId ) ;
43+ if ( threadElement ) {
44+ setSelectedThreadId ( threadId ) ;
45+ threadElement . scrollIntoView ( { behavior : 'smooth' , block : 'center' } ) ;
46+ } else {
47+ logger . warn ( `Could not find thread element with id: ${ threadId } ` ) ;
48+ }
49+ }
50+ } ;
51+
52+ window . addEventListener ( 'message' , messageListener ) ;
53+ return ( ) => {
54+ window . removeEventListener ( 'message' , messageListener ) ;
55+ } ;
56+ } , [ ] ) ;
57+
2758 // Fetch current user's registration data on mount
2859 useEffect ( ( ) => {
2960 let isMounted = true ;
@@ -59,13 +90,13 @@ global.webViewComponent = function CommentListWebView({
5990 } ,
6091 ] ,
6192 } ;
62- } , [ scrRef . book , scrRef . chapterNum , scrRef . verseNum ] ) ,
93+ } , [ scrRef . book , scrRef . chapterNum ] ) ,
6394 DEFAULT_LEGACY_COMMENT_THREADS ,
6495 ) ;
6596
6697 const fetchAssignableUsers = useCallback ( async ( ) => {
6798 if ( ! commentsPdp ) {
68- logger . error ( 'Comments PDP is not available' ) ;
99+ logger . debug ( 'Comments PDP is not yet available for fetchAssignableUsers ' ) ;
69100 return [ ] ;
70101 }
71102 return commentsPdp . findAssignableUsers ( ) ;
@@ -74,7 +105,7 @@ global.webViewComponent = function CommentListWebView({
74105
75106 const fetchCanUserAddCommentToThread = useCallback ( async ( ) => {
76107 if ( ! commentsPdp ) {
77- logger . error ( 'Comments PDP is not available' ) ;
108+ logger . debug ( 'Comments PDP is not yet available for fetchCanUserAddCommentToThread ' ) ;
78109 return false ;
79110 }
80111 return commentsPdp . canUserAddCommentToThread ( ) ;
@@ -84,7 +115,7 @@ global.webViewComponent = function CommentListWebView({
84115 const canUserAssignThreadCallback = useCallback (
85116 async ( threadId : string ) : Promise < boolean > => {
86117 if ( ! commentsPdp ) {
87- logger . error ( 'Comments PDP is not available' ) ;
118+ logger . debug ( 'Comments PDP is not yet available for canUserAssignThreadCallback ' ) ;
88119 return false ;
89120 }
90121 return commentsPdp . canUserAssignThread ( threadId ) ;
@@ -95,7 +126,7 @@ global.webViewComponent = function CommentListWebView({
95126 const canUserResolveThreadCallback = useCallback (
96127 async ( threadId : string ) : Promise < boolean > => {
97128 if ( ! commentsPdp ) {
98- logger . error ( 'Comments PDP is not available' ) ;
129+ logger . debug ( 'Comments PDP is not yet available for canUserResolveThreadCallback ' ) ;
99130 return false ;
100131 }
101132 return commentsPdp . canUserResolveThread ( threadId ) ;
@@ -106,7 +137,7 @@ global.webViewComponent = function CommentListWebView({
106137 const canUserEditOrDeleteCommentCallback = useCallback (
107138 async ( commentId : string ) : Promise < boolean > => {
108139 if ( ! commentsPdp ) {
109- logger . error ( 'Comments PDP is not available' ) ;
140+ logger . debug ( 'Comments PDP is not yet available for canUserEditOrDeleteCommentCallback ' ) ;
110141 return false ;
111142 }
112143 return commentsPdp . canUserEditOrDeleteComment ( commentId ) ;
@@ -117,7 +148,7 @@ global.webViewComponent = function CommentListWebView({
117148 const handleAddCommentToThread = useCallback (
118149 async ( options : AddCommentToThreadOptions ) : Promise < string | undefined > => {
119150 if ( ! commentsPdp ) {
120- logger . error ( 'Comments PDP is not available' ) ;
151+ logger . debug ( 'Comments PDP is not yet available for handleAddCommentToThread ' ) ;
121152 return undefined ;
122153 }
123154 try {
@@ -139,7 +170,7 @@ global.webViewComponent = function CommentListWebView({
139170 const handleUpdateComment = useCallback (
140171 async ( commentId : string , contents : string ) : Promise < boolean > => {
141172 if ( ! commentsPdp ) {
142- logger . error ( 'Comments PDP is not available' ) ;
173+ logger . debug ( 'Comments PDP is not yet available for handleUpdateComment ' ) ;
143174 return false ;
144175 }
145176 try {
@@ -156,7 +187,7 @@ global.webViewComponent = function CommentListWebView({
156187 const handleDeleteComment = useCallback (
157188 async ( commentId : string ) : Promise < boolean > => {
158189 if ( ! commentsPdp ) {
159- logger . error ( 'Comments PDP is not available' ) ;
190+ logger . debug ( 'Comments PDP is not yet available for handleDeleteComment ' ) ;
160191 return false ;
161192 }
162193 try {
@@ -204,6 +235,8 @@ global.webViewComponent = function CommentListWebView({
204235 canUserAssignThreadCallback = { canUserAssignThreadCallback }
205236 canUserResolveThreadCallback = { canUserResolveThreadCallback }
206237 canUserEditOrDeleteCommentCallback = { canUserEditOrDeleteCommentCallback }
238+ selectedThreadId = { selectedThreadId }
239+ onSelectedThreadChange = { setSelectedThreadId }
207240 />
208241 ) }
209242 </ div >
0 commit comments