@@ -79,7 +79,9 @@ class WorkspaceProvider extends StateHandler {
7979 Offset ? _connectorDragPosition;
8080
8181 final FileServices _fileServices = FileServices ();
82+ bool _isNodePicked = false ;
8283
84+ bool get isNodePicked => _isNodePicked;
8385 bool get isLoading => _isLoading;
8486 bool get isDrawerOpen => _isDrawerOpen;
8587 int ? get selectedTileIndex => _selectedTileIndex;
@@ -116,6 +118,18 @@ class WorkspaceProvider extends StateHandler {
116118 return _tempQuillController;
117119 }
118120
121+ IconData nodeIconProvider () {
122+ if (_currentMode != DrawMode .hand &&
123+ _currentMode != DrawMode .pointer &&
124+ _currentMode != DrawMode .stickyNote &&
125+ _currentMode != DrawMode .textBox) {
126+ _isNodePicked = true ;
127+ notifyListeners ();
128+ return _currentMode.iconData;
129+ }
130+ return PhosphorIconsRegular .circlesThreePlus;
131+ }
132+
119133 Future <void > exportWorkspaceAsJson () async {
120134 if (_currentWorkspace == null ) {
121135 print ("Cannot export: No workspace is currently loaded." );
@@ -192,8 +206,9 @@ class WorkspaceProvider extends StateHandler {
192206
193207 final backgroundPaint = Paint ()..color = _currentWorkspaceColor;
194208 canvas.drawRect (
195- Rect .fromLTWH (0 , 0 , imageBounds.width, imageBounds.height),
196- backgroundPaint);
209+ Rect .fromLTWH (0 , 0 , imageBounds.width, imageBounds.height),
210+ backgroundPaint,
211+ );
197212
198213 final painter = CanvasPainter (
199214 canvasObjects: _canvasObjects,
@@ -238,7 +253,6 @@ class WorkspaceProvider extends StateHandler {
238253 }
239254 }
240255
241-
242256 void setStickyNoteMode (Color color) {
243257 _currentMode = DrawMode .stickyNote;
244258 _nextObjectColor = color;
@@ -318,57 +332,58 @@ class WorkspaceProvider extends StateHandler {
318332
319333 void _setupRealtimeChannel (String workspaceId) {
320334 if (_canvasChannel? .topic != '${Constants .channelName }:$workspaceId ' ) {
321- _canvasChannel = _supabaseService.supabase
322- .channel ('${Constants .channelName }:$workspaceId ' )
323- .onBroadcast (
324- event: Constants .broadcastEventName,
325- callback: (payload) {
326- if (payload['workspace_id' ] == _currentWorkspace? .id) {
327- final cursor = UserCursor .fromJson (payload['cursor' ]);
328- if (cursor.id != _myId) {
329- _userCursors[cursor.id] = cursor;
330- }
331-
332- if (payload['object' ] != null ) {
333- final object = CanvasObject .fromJson (payload['object' ]);
334- _canvasObjects[object.id] = object;
335- if (object.id == _currentlySelectedObjectId &&
336- object.textDelta != null ) {
337- try {
338- final doc = Document .fromJson (
339- jsonDecode (object.textDelta! ),
340- );
341- if (! isEqual (
342- _tempQuillController.document.toDelta ().toJson (),
343- doc.toDelta ().toJson (),
344- )) {
345- _tempQuillController.document = doc;
335+ _canvasChannel =
336+ _supabaseService.supabase
337+ .channel ('${Constants .channelName }:$workspaceId ' )
338+ .onBroadcast (
339+ event: Constants .broadcastEventName,
340+ callback: (payload) {
341+ if (payload['workspace_id' ] == _currentWorkspace? .id) {
342+ final cursor = UserCursor .fromJson (payload['cursor' ]);
343+ if (cursor.id != _myId) {
344+ _userCursors[cursor.id] = cursor;
345+ }
346+
347+ if (payload['object' ] != null ) {
348+ final object = CanvasObject .fromJson (payload['object' ]);
349+ _canvasObjects[object.id] = object;
350+ if (object.id == _currentlySelectedObjectId &&
351+ object.textDelta != null ) {
352+ try {
353+ final doc = Document .fromJson (
354+ jsonDecode (object.textDelta! ),
355+ );
356+ if (! isEqual (
357+ _tempQuillController.document.toDelta ().toJson (),
358+ doc.toDelta ().toJson (),
359+ )) {
360+ _tempQuillController.document = doc;
361+ }
362+ } catch (e) {
363+ print (
364+ "Error loading textDelta into QuillController: $e " ,
365+ );
366+ }
346367 }
347- } catch (e) {
348- print (
349- "Error loading textDelta into QuillController: $e " ,
350- );
351368 }
352- }
353- }
354-
355- if ( payload['deleted_ids' ] != null ) {
356- final List < String > deletedIds = List < String >. from (
357- payload[ 'deleted_ids' ],
358- );
359- for ( final id in deletedIds ) {
360- _canvasObjects. remove (id) ;
361- if (_currentlySelectedObjectId == id) {
362- _currentlySelectedObjectId = null ;
369+
370+ if (payload[ 'deleted_ids' ] != null ) {
371+ final List < String > deletedIds = List < String >. from (
372+ payload['deleted_ids' ],
373+ );
374+ for ( final id in deletedIds) {
375+ _canvasObjects. remove (id );
376+ if (_currentlySelectedObjectId == id ) {
377+ _currentlySelectedObjectId = null ;
378+ }
379+ }
363380 }
364- }
365- }
366381
367- notifyListeners ();
368- }
369- },
370- )
371- .subscribe ();
382+ notifyListeners ();
383+ }
384+ },
385+ )
386+ .subscribe ();
372387 }
373388 }
374389
@@ -573,7 +588,9 @@ class WorkspaceProvider extends StateHandler {
573588 final object = _canvasObjects[_currentlySelectedObjectId! ];
574589 if (object == null ) return ;
575590
576- _canvasObjects[_currentlySelectedObjectId! ] = object.copyWith (color: newColor);
591+ _canvasObjects[_currentlySelectedObjectId! ] = object.copyWith (
592+ color: newColor,
593+ );
577594
578595 notifyListeners ();
579596 syncCanvasObject (_cursorPosition);
@@ -589,60 +606,68 @@ class WorkspaceProvider extends StateHandler {
589606 switch (newShapeType) {
590607 case ShapeType .square:
591608 return Square (
592- id: id,
593- color: color,
594- topLeft: bounds.topLeft,
595- bottomRight: bounds.bottomRight,
596- textDelta: textDelta);
609+ id: id,
610+ color: color,
611+ topLeft: bounds.topLeft,
612+ bottomRight: bounds.bottomRight,
613+ textDelta: textDelta,
614+ );
597615 case ShapeType .circle:
598616 return Circle (
599- id: id,
600- color: color,
601- center: bounds.center,
602- radius: max (bounds.width, bounds.height) / 2 ,
603- textDelta: textDelta);
617+ id: id,
618+ color: color,
619+ center: bounds.center,
620+ radius: max (bounds.width, bounds.height) / 2 ,
621+ textDelta: textDelta,
622+ );
604623 case ShapeType .diamond:
605624 return Diamond (
606- id: id,
607- color: color,
608- topLeft: bounds.topLeft,
609- bottomRight: bounds.bottomRight,
610- textDelta: textDelta);
625+ id: id,
626+ color: color,
627+ topLeft: bounds.topLeft,
628+ bottomRight: bounds.bottomRight,
629+ textDelta: textDelta,
630+ );
611631 case ShapeType .roundedSquare:
612632 return RoundedSquare (
613- id: id,
614- color: color,
615- topLeft: bounds.topLeft,
616- bottomRight: bounds.bottomRight,
617- textDelta: textDelta);
633+ id: id,
634+ color: color,
635+ topLeft: bounds.topLeft,
636+ bottomRight: bounds.bottomRight,
637+ textDelta: textDelta,
638+ );
618639 case ShapeType .parallelogram:
619640 return Parallelogram (
620- id: id,
621- color: color,
622- topLeft: bounds.topLeft,
623- bottomRight: bounds.bottomRight,
624- textDelta: textDelta);
641+ id: id,
642+ color: color,
643+ topLeft: bounds.topLeft,
644+ bottomRight: bounds.bottomRight,
645+ textDelta: textDelta,
646+ );
625647 case ShapeType .cylinder:
626648 return Cylinder (
627- id: id,
628- color: color,
629- topLeft: bounds.topLeft,
630- bottomRight: bounds.bottomRight,
631- textDelta: textDelta);
649+ id: id,
650+ color: color,
651+ topLeft: bounds.topLeft,
652+ bottomRight: bounds.bottomRight,
653+ textDelta: textDelta,
654+ );
632655 case ShapeType .triangle:
633656 return Triangle (
634- id: id,
635- color: color,
636- topLeft: bounds.topLeft,
637- bottomRight: bounds.bottomRight,
638- textDelta: textDelta);
657+ id: id,
658+ color: color,
659+ topLeft: bounds.topLeft,
660+ bottomRight: bounds.bottomRight,
661+ textDelta: textDelta,
662+ );
639663 case ShapeType .invertedTriangle:
640664 return InvertedTriangle (
641- id: id,
642- color: color,
643- topLeft: bounds.topLeft,
644- bottomRight: bounds.bottomRight,
645- textDelta: textDelta);
665+ id: id,
666+ color: color,
667+ topLeft: bounds.topLeft,
668+ bottomRight: bounds.bottomRight,
669+ textDelta: textDelta,
670+ );
646671 }
647672 }
648673
@@ -666,12 +691,14 @@ class WorkspaceProvider extends StateHandler {
666691 final String idToDelete = _currentlySelectedObjectId! ;
667692
668693 final List <String > idsToDelete = [idToDelete];
669- final attachedConnectors = _canvasObjects.values
670- .whereType <ConnectorObject >()
671- .where (
672- (conn) => conn.sourceId == idToDelete || conn.targetId == idToDelete,
673- )
674- .toList ();
694+ final attachedConnectors =
695+ _canvasObjects.values
696+ .whereType <ConnectorObject >()
697+ .where (
698+ (conn) =>
699+ conn.sourceId == idToDelete || conn.targetId == idToDelete,
700+ )
701+ .toList ();
675702
676703 for (final conn in attachedConnectors) {
677704 idsToDelete.add (conn.id);
@@ -749,9 +776,11 @@ class WorkspaceProvider extends StateHandler {
749776 return ;
750777 }
751778 CanvasObject ? newObject;
752- final defaultTopLeft = details.globalPosition -
779+ final defaultTopLeft =
780+ details.globalPosition -
753781 const Offset (_defaultShapeSize / 2 , _defaultShapeSize / 2 );
754- final defaultBottomRight = details.globalPosition +
782+ final defaultBottomRight =
783+ details.globalPosition +
755784 const Offset (_defaultShapeSize / 2 , _defaultShapeSize / 2 );
756785
757786 switch (_currentMode) {
@@ -815,6 +844,7 @@ class WorkspaceProvider extends StateHandler {
815844 case DrawMode .hand:
816845 break ;
817846 }
847+ _currentMode = DrawMode .pointer;
818848
819849 if (newObject != null ) {
820850 _canvasObjects[newObject.id] = newObject;
@@ -934,7 +964,8 @@ class WorkspaceProvider extends StateHandler {
934964 }
935965
936966 final now = DateTime .now ();
937- final isDoubleTap = _lastTappedObjectId == tappedObject.id &&
967+ final isDoubleTap =
968+ _lastTappedObjectId == tappedObject.id &&
938969 _lastTapTime != null &&
939970 now.difference (_lastTapTime! ) < const Duration (milliseconds: 300 );
940971
@@ -1072,4 +1103,4 @@ class WorkspaceProvider extends StateHandler {
10721103 return a == b;
10731104 }
10741105 }
1075- }
1106+ }
0 commit comments