@@ -11,6 +11,7 @@ import {
1111 clearConnectionPreview
1212} from "./canvas/connection-manager.js" ;
1313import { initSocket , socket , collaborativeUpdate } from "./utils/socket-handler.js" ;
14+ import { SetupWarningDialog } from "./apps/setup-warning.js" ;
1415import {
1516 createNote ,
1617 createPhotoNoteFromActor ,
@@ -255,36 +256,16 @@ Hooks.once("ready", () => {
255256
256257 // Show setup warning to GM if enabled
257258 if ( game . user . isGM && game . settings . get ( MODULE_ID , "showSetupWarning" ) ) {
258- const drawingPerm = game . permissions . DRAWING_CREATE . includes ( 1 ) ; // PLAYER role
259- const filePerm = game . permissions . FILES_BROWSE . includes ( 1 ) ; // PLAYER role
259+ const users = game . users . filter ( u => ! u . isGM ) ;
260+ const playerRoles = [ ...new Set ( users . map ( u => u . role ) ) ] ;
261+ if ( playerRoles . length === 0 ) playerRoles . push ( 1 ) ;
262+
263+ const drawingPerm = playerRoles . every ( role => game . permissions . DRAWING_CREATE . includes ( role ) ) ;
264+ const browsePerm = playerRoles . every ( role => game . permissions . FILES_BROWSE . includes ( role ) ) ;
265+ const uploadPerm = playerRoles . every ( role => game . permissions . FILES_UPLOAD . includes ( role ) ) ;
260266
261- if ( ! drawingPerm || ! filePerm ) {
262- const { DialogV2 } = foundry . applications . api ;
263- new DialogV2 ( {
264- window : { title : "Investigation Board: Setup Recommended" } ,
265- content : `
266- <p>To allow <strong>Players</strong> to fully use the Investigation Board, consider updating these World Permissions in <b>Game Settings >> User Management >> Configure Permissions</b>:</p>
267- <ul>
268- <li><strong>Use Drawing Tools</strong>: ${ drawingPerm ? "✅ Enabled" : "❌ Disabled (Needed to create/manipulate notes and connections)" } </li>
269- <li><strong>Upload Files</strong>: ${ filePerm ? "✅ Enabled" : "❌ Disabled (Needed to create Photo and Handout notes with images)" } </li>
270- </ul>
271- <p style="color: #882222; font-style: italic;"><strong>Security Note:</strong> Enabling 'Upload Files' for players gives them access to your server's file system through the File Picker. Be careful with who you let access your files!</p>
272- <hr>
273- ` ,
274- buttons : [
275- {
276- action : "ok" ,
277- label : "Understood" ,
278- icon : "fas fa-check"
279- } ,
280- {
281- action : "disable" ,
282- label : "Don't show again" ,
283- icon : "fas fa-times" ,
284- callback : ( event , button , dialog ) => game . settings . set ( MODULE_ID , "showSetupWarning" , false )
285- }
286- ]
287- } ) . render ( true ) ;
267+ if ( ! drawingPerm || ! browsePerm || ! uploadPerm ) {
268+ new SetupWarningDialog ( ) . render ( true ) ;
288269 }
289270 }
290271} ) ;
@@ -295,11 +276,30 @@ Hooks.on("createDrawing", (drawing, options, userId) => {
295276 const noteData = drawing . flags [ MODULE_ID ] ;
296277 if ( ! noteData ) return ;
297278
279+ // Determine who should see the sheet: either the direct userId or the original requester via socket
280+ const requesterId = options . ibRequestingUser || userId ;
281+
298282 // If this is the user who created the note, open the edit dialog
299- if ( userId === game . user . id && ! options . skipAutoOpen ) {
283+ if ( requesterId === game . user . id && ! options . skipAutoOpen ) {
300284 setTimeout ( ( ) => {
301- drawing . sheet . render ( true ) ;
302- } , 150 ) ;
285+ // Calculate screen position to place dialog below the note
286+ const drawingObject = canvas . drawings . get ( drawing . id ) ;
287+ if ( drawingObject ) {
288+ const bounds = drawingObject . getBounds ( ) ;
289+ // bounds are in screen coordinates (pixels)
290+ const top = bounds . bottom + 20 ; // 20px padding below the note
291+ const left = bounds . left + ( bounds . width / 2 ) - 200 ; // Center horizontally (sheet width is 400)
292+
293+ drawing . sheet . render ( true , {
294+ position : {
295+ top : Math . max ( 0 , top ) ,
296+ left : Math . max ( 0 , left )
297+ }
298+ } ) ;
299+ } else {
300+ drawing . sheet . render ( true ) ;
301+ }
302+ } , 250 ) ;
303303 }
304304
305305 // If we're in Investigation Board mode, refresh interactivity after the drawing is rendered
@@ -373,6 +373,11 @@ Hooks.on("updateDrawing", async (drawing, changes, options, userId) => {
373373 // If flags changed, refresh the drawing to update visuals on ALL clients
374374 if ( flagsChanged && placeable ) {
375375 await placeable . refresh ( ) ;
376+
377+ // Also re-render open NotePreviewer for this drawing
378+ const appId = `note-preview-${ drawing . id } ` ;
379+ const app = foundry . applications . instances . get ( appId ) ;
380+ if ( app ) app . render ( ) ;
376381 }
377382
378383 // Redraw connection lines when position OR connections change
0 commit comments