Skip to content

Commit cd1cc54

Browse files
committed
fix: UX fixes
1 parent 7b8934d commit cd1cc54

File tree

4 files changed

+266
-211
lines changed

4 files changed

+266
-211
lines changed

lib/core/theme/colors.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const List<Color> secondaryColors = [
2323
Color(0xFF3B82F6), // [6] Blue
2424
Color(0xFFED6325), // [7] Orange
2525
Color(0xFF737492), // [8] Slate Gray
26-
Color(0xFF000000), // [9] Black
26+
// Color(0xFF000000), // [9] Black
2727
];
2828

2929
// List of tertiary colors

lib/features/workspace/providers/workspace_provider.dart

Lines changed: 132 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)