test
This commit is contained in:
@@ -27,6 +27,7 @@ class Dashboard extends ChangeNotifier {
|
||||
GlobalKey<FlowChartLeftMenuState> selectedLeftMenuKey = GlobalKey<FlowChartLeftMenuState>();
|
||||
GlobalKey<FlowChartMenuState> chartMenuKey = GlobalKey<FlowChartMenuState>();
|
||||
GlobalKey<ChartWidgetState> chartKey = GlobalKey<ChartWidgetState>();
|
||||
GlobalKey<FlowChartState> flutterChartKey = GlobalKey<FlowChartState>();
|
||||
List<Map<String, dynamic>> tempHistory = [];
|
||||
List<Map<String, dynamic>> history = [];
|
||||
Map<String, dynamic> scheduler = {};
|
||||
@@ -50,12 +51,23 @@ class Dashboard extends ChangeNotifier {
|
||||
FlowData? Function(Map<String, dynamic> json)? transformToData;
|
||||
bool addChange = false;
|
||||
bool shouldSave = true;
|
||||
Color dashColor = Colors.grey;
|
||||
Color midDashColor = Colors.grey.shade300;
|
||||
|
||||
/// The dashboard position
|
||||
/// This is used to move the dashboard on the screen
|
||||
double widthOffset = 0;
|
||||
double heightOffset = 0;
|
||||
///
|
||||
Dashboard({
|
||||
this.id,
|
||||
this.widthOffset = 0,
|
||||
this.heightOffset = 0,
|
||||
this.transformToData,
|
||||
required this.name,
|
||||
this.save,
|
||||
this.dashColor = Colors.grey,
|
||||
this.midDashColor = Colors.blueGrey,
|
||||
this.scheduler = const {},
|
||||
Offset? handlerFeedbackOffset,
|
||||
this.isMenu = true,
|
||||
@@ -384,7 +396,6 @@ class Dashboard extends ChangeNotifier {
|
||||
|
||||
FlowElement? getElement(String id, {bool notify = true}) {
|
||||
try { return elements.firstWhere((element) {
|
||||
print(element.id + " - " + id);
|
||||
return element.id == id;
|
||||
}); }
|
||||
catch (e) { return null; }
|
||||
@@ -523,6 +534,9 @@ class Dashboard extends ChangeNotifier {
|
||||
void removeAllElements({bool notify = true}) {
|
||||
elements.clear();
|
||||
if (notify) notifyListeners();
|
||||
if (save != null) {
|
||||
save!(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// remove the [handler] connection of [element]
|
||||
@@ -564,8 +578,10 @@ class Dashboard extends ChangeNotifier {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (notify) notifyListeners();
|
||||
if (save != null) {
|
||||
save!(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// dissect an element connection
|
||||
@@ -658,6 +674,9 @@ class Dashboard extends ChangeNotifier {
|
||||
void removeElementConnections(FlowElement element, {bool notify = true}) {
|
||||
element.next.clear();
|
||||
if (notify) notifyListeners();
|
||||
if (save != null) {
|
||||
save!(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// remove all the elements with [id] from the dashboard
|
||||
@@ -678,6 +697,9 @@ class Dashboard extends ChangeNotifier {
|
||||
});
|
||||
}
|
||||
if (notify) notifyListeners();
|
||||
if (save != null) {
|
||||
save!(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// remove element
|
||||
@@ -698,6 +720,9 @@ class Dashboard extends ChangeNotifier {
|
||||
);
|
||||
}
|
||||
if (notify) notifyListeners();
|
||||
if (save != null) {
|
||||
save!(id);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class FlowElement<T extends FlowData> extends ChangeNotifier {
|
||||
FlowElement({
|
||||
required this.dashboard,
|
||||
Offset position = Offset.zero,
|
||||
String? id,
|
||||
String? id,
|
||||
this.element,
|
||||
this.size = Size.zero,
|
||||
this.text = '',
|
||||
|
||||
@@ -60,6 +60,8 @@ class FlowChart<T extends FlowData> extends StatefulWidget {
|
||||
this.menuWidget,
|
||||
this.current,
|
||||
this.menuExtension,
|
||||
this.itemLeftBottomBadges,
|
||||
this.itemrightTopBadges,
|
||||
}) {}
|
||||
final String? current;
|
||||
final List<String> categories;
|
||||
@@ -74,6 +76,8 @@ class FlowChart<T extends FlowData> extends StatefulWidget {
|
||||
double zoom = 1;
|
||||
|
||||
final Widget Function(T data) itemWidget;
|
||||
final Widget? Function(T data)? itemLeftBottomBadges;
|
||||
final Widget? Function(T data)? itemrightTopBadges;
|
||||
final Widget Function(T data)? itemWidgetTooltip;
|
||||
final List<T> Function(String cat) draggableItemBuilder;
|
||||
|
||||
@@ -274,7 +278,7 @@ class HoverMenuState extends State<HoverMenu> {
|
||||
return OverlayEntry(
|
||||
maintainState: true,
|
||||
builder: (context) => Positioned(
|
||||
left: offset.dx,
|
||||
left: offset.dx - 300,
|
||||
top: offset.dy + size.height,
|
||||
width: 300,
|
||||
child: TextButton(
|
||||
@@ -451,7 +455,10 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
String newID = const Uuid().v4();
|
||||
double ratio = 1;
|
||||
if (e.getWidth() != null && e.getHeight() != null) {
|
||||
ratio = (e.getHeight()! / (e.getWidth()!));
|
||||
print("${e.getWidth()} ${e.getHeight()}");
|
||||
var h = e.getHeight()! < e.getWidth()! ? e.getHeight()! + 20 : e.getHeight()!;
|
||||
var w = e.getWidth()! < e.getHeight()! ? e.getWidth()! + 20 : e.getWidth()!;
|
||||
ratio = (h / w);
|
||||
}
|
||||
FlowElement<T> el = FlowElement<T>(
|
||||
dashboard: widget.dashboard,
|
||||
@@ -474,25 +481,22 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
},
|
||||
))]
|
||||
),
|
||||
widget.dashboard.isMenu ? Positioned(top: 50, child: FlowChartLeftMenu<T>(
|
||||
key: widget.dashboard.selectedLeftMenuKey,
|
||||
widget.dashboard.isMenu ? Positioned(top: 50, child: FlowChartSelectedMenu(
|
||||
key: widget.dashboard.selectedMenuKey,
|
||||
dashboard: widget.dashboard,
|
||||
menuExtension: widget.menuExtension,
|
||||
categories: widget.categories,
|
||||
height: widget.height,
|
||||
innerMenuWidth: widget.innerMenuWidth,
|
||||
itemWidth: widget.itemWidth,
|
||||
draggableItemBuilder: widget.draggableItemBuilder as List<T> Function(String cat),
|
||||
getDraggable: getDraggable,
|
||||
) )
|
||||
: Container(),
|
||||
height: widget.height - 50) ) : Container(),
|
||||
widget.dashboard.isInfo ? Positioned(top: 50, right: 0, child:
|
||||
FlowChartSelectedMenu(
|
||||
key: widget.dashboard.selectedMenuKey,
|
||||
dashboard: widget.dashboard,
|
||||
height: MediaQuery.of(context).size.height - 100
|
||||
)
|
||||
) : Container()
|
||||
FlowChartLeftMenu<T>(
|
||||
key: widget.dashboard.selectedLeftMenuKey,
|
||||
dashboard: widget.dashboard,
|
||||
menuExtension: widget.menuExtension,
|
||||
categories: widget.categories,
|
||||
height: widget.height,
|
||||
innerMenuWidth: widget.innerMenuWidth,
|
||||
itemWidth: widget.itemWidth,
|
||||
draggableItemBuilder: widget.draggableItemBuilder as List<T> Function(String cat),
|
||||
getDraggable: getDraggable,
|
||||
)) : Container()
|
||||
])
|
||||
));
|
||||
}
|
||||
@@ -509,19 +513,16 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
onDragEnd: (d) => node.requestFocus(),
|
||||
childWhenDragging: Opacity(opacity: .5,
|
||||
child: Padding( padding: const EdgeInsets.all(10),
|
||||
child: Container( child: widget.itemWidget(e),
|
||||
constraints: BoxConstraints(maxHeight: realSize - 20, maxWidth: realSize - 20), ))),
|
||||
feedback: Container( constraints: BoxConstraints(maxHeight: realSize, maxWidth: realSize),
|
||||
child: Container( child: widget.itemWidget(e), alignment: Alignment.center,
|
||||
constraints: BoxConstraints(maxHeight: realSize - 10, maxWidth: realSize - 10), ))),
|
||||
feedback: Container( alignment: Alignment.center, constraints: BoxConstraints(maxHeight: realSize, maxWidth: realSize),
|
||||
child: widget.itemWidget(e) ),
|
||||
child: InkWell( mouseCursor: SystemMouseCursors.grab, child: Padding( padding: const EdgeInsets.all(10),
|
||||
child: widget.itemWidgetTooltip != null ? HoverMenu( key: hoverKey, width: 400, title: Container(
|
||||
constraints: BoxConstraints( maxHeight: realSize - 20, maxWidth: realSize - 20),
|
||||
child: widget.itemWidget(e) ),
|
||||
items: [
|
||||
Container(child: widget.itemWidgetTooltip!(e)),
|
||||
]
|
||||
) : Container(
|
||||
constraints: BoxConstraints(maxHeight: realSize - 20, maxWidth: realSize - 20), child: widget.itemWidget(e)
|
||||
child: widget.itemWidgetTooltip != null ? HoverMenu( key: hoverKey, width: 400, title: Container( alignment: Alignment.center,
|
||||
constraints: BoxConstraints( maxHeight: realSize - 10, maxWidth: realSize - 10), child: widget.itemWidget(e) ),
|
||||
items: [ Container(child: widget.itemWidgetTooltip!(e)) ]
|
||||
) : Container( alignment: Alignment.center,
|
||||
constraints: BoxConstraints(maxHeight: realSize - 10, maxWidth: realSize - 10), child: widget.itemWidget(e)
|
||||
)
|
||||
) )));
|
||||
}
|
||||
@@ -824,6 +825,10 @@ class ChartWidgetState<T extends FlowData> extends State<ChartWidget> {
|
||||
for (int i = 0; i < widget.dashboard.elements.length; i++)
|
||||
ElementWidget<T>(
|
||||
key: UniqueKey(),
|
||||
bottomLeftBadge: widget.flowChart.widget.itemLeftBottomBadges != null ?
|
||||
widget.flowChart.widget.itemLeftBottomBadges!(widget.dashboard.elements[i].element as T) : null,
|
||||
topRightBadge: widget.flowChart.widget.itemrightTopBadges != null ?
|
||||
widget.flowChart.widget.itemrightTopBadges!(widget.dashboard.elements[i].element as T) : null,
|
||||
dashboard: widget.dashboard,
|
||||
element: widget.dashboard.elements.elementAt(i),
|
||||
onElementPressed: widget.onElementPressed == null
|
||||
@@ -924,7 +929,7 @@ class ChartWidgetState<T extends FlowData> extends State<ChartWidget> {
|
||||
chart: this,
|
||||
menuExtension: widget.menuWidget != null ? widget.menuWidget!(widget.dashboard) : null,
|
||||
dashboard: widget.dashboard,
|
||||
width: MediaQuery.of(context).size.width)
|
||||
width: widget.flowChart.widget.width)
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ class FlowChartLeftMenuState<T extends FlowData> extends State<FlowChartLeftMenu
|
||||
widget.dashboard.isMenu && widget.innerMenuWidth < 200 ? Wrap( alignment: WrapAlignment.start,
|
||||
children: widget.getDraggable(items))
|
||||
: Theme(
|
||||
data: Theme.of(context).copyWith(dividerColor: Colors.grey.shade300),
|
||||
data: Theme.of(context).copyWith(dividerColor: widget.dashboard.midDashColor),
|
||||
child: ExpansionTile(
|
||||
collapsedShape: RoundedRectangleBorder(
|
||||
side: BorderSide.none,
|
||||
@@ -70,25 +70,27 @@ class FlowChartLeftMenuState<T extends FlowData> extends State<FlowChartLeftMenu
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
height: widget.height - 50,
|
||||
color: Colors.grey.shade300,
|
||||
height: widget.height,
|
||||
color: widget.dashboard.midDashColor,
|
||||
child: Stack( children: [
|
||||
Container(
|
||||
width: widget.innerMenuWidth,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(border: Border(
|
||||
right: BorderSide(color: Colors.grey.shade300),
|
||||
bottom: BorderSide(color: Colors.grey.shade400),
|
||||
right: BorderSide(color: widget.dashboard.midDashColor),
|
||||
left: BorderSide(color: Colors.white))),
|
||||
child: TextFormField(
|
||||
style: const TextStyle(color: Colors.black, fontSize: 15),
|
||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
||||
cursorColor: widget.dashboard.dashColor,
|
||||
controller: widget.ctrl,
|
||||
onChanged: (value) { setState(() { }); },
|
||||
decoration: InputDecoration(
|
||||
hintText: "search item...",
|
||||
fillColor: Colors.white,
|
||||
prefixIcon: const Icon(Icons.search, color: Colors.grey),
|
||||
fillColor: widget.dashboard.midDashColor,
|
||||
filled: true,
|
||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5),
|
||||
contentPadding: const EdgeInsets.only(left: 50, right: 50, top: 15, bottom: 15),
|
||||
hintStyle: TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 15,
|
||||
@@ -100,10 +102,10 @@ class FlowChartLeftMenuState<T extends FlowData> extends State<FlowChartLeftMenu
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 50),
|
||||
height: widget.height - 150,
|
||||
height: widget.height - 100,
|
||||
constraints: BoxConstraints(minWidth: widget.itemWidth),
|
||||
width: widget.dashboard.isMenu ? widget.innerMenuWidth : 0,
|
||||
color: Colors.grey.shade300,
|
||||
color: widget.dashboard.midDashColor,
|
||||
child: SingleChildScrollView( child: Column( children: [
|
||||
...menuItems
|
||||
]) )
|
||||
|
||||
@@ -18,13 +18,13 @@ class FlowChartMenu extends StatefulWidget {
|
||||
}
|
||||
class FlowChartMenuState extends State<FlowChartMenu> {
|
||||
@override Widget build(BuildContext context) {
|
||||
bool isLow = MediaQuery.of(context).size.width < 600;
|
||||
bool isLow = widget.chart.widget.flowChart.widget.width < 600;
|
||||
GlobalKey<FormFieldState> zoomKey = GlobalKey<FormFieldState>();
|
||||
return Container( // SHORTCUT
|
||||
return Row( mainAxisAlignment: MainAxisAlignment.end, children : [ Container( // SHORTCUT
|
||||
width: widget.width,
|
||||
height: 50,
|
||||
padding: EdgeInsets.only(left: 20),
|
||||
color: const Color.fromRGBO(38, 166, 154, 1),
|
||||
color: widget.dashboard.dashColor,
|
||||
child: Row( children : [ Expanded(flex: 2, child: Row( children: [
|
||||
widget.chart.widget.flowChart.widget.onDashboardAlertOpened == null ? Container() : Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -49,7 +49,7 @@ class FlowChartMenuState extends State<FlowChartMenu> {
|
||||
context, widget.dashboard));
|
||||
});
|
||||
},
|
||||
child: Icon(Icons.folder_open, color: Colors.white))))),
|
||||
child: Icon(Icons.folder, color: Colors.white))))),
|
||||
])),
|
||||
InkWell( mouseCursor: SystemMouseCursors.click, child: Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -109,7 +109,7 @@ class FlowChartMenuState extends State<FlowChartMenu> {
|
||||
child: Wrap( alignment: WrapAlignment.center, children: [
|
||||
Padding( padding: EdgeInsets.only(left: 10, top: 10, bottom: 10) , child: TextFormField(
|
||||
key: zoomKey,
|
||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
||||
cursorColor: widget.dashboard.dashColor,
|
||||
onChanged: (value) { },
|
||||
validator: (value) {
|
||||
try {
|
||||
@@ -224,7 +224,7 @@ class FlowChartMenuState extends State<FlowChartMenu> {
|
||||
}
|
||||
},
|
||||
mouseCursor: !widget.dashboard.canBack() ? MouseCursor.defer : SystemMouseCursors.click,
|
||||
child: Icon(Icons.undo, color: !widget.dashboard.canBack() ? Colors.grey.shade300 : Colors.white)),),
|
||||
child: Icon(Icons.undo, color: !widget.dashboard.canBack() ? widget.dashboard.midDashColor : Colors.white)),),
|
||||
Padding( padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
@@ -233,22 +233,22 @@ class FlowChartMenuState extends State<FlowChartMenu> {
|
||||
}
|
||||
},
|
||||
mouseCursor: !widget.dashboard.canForward() ? MouseCursor.defer : SystemMouseCursors.click, child: Icon(Icons.redo,
|
||||
color: !widget.dashboard.canForward() ? Colors.grey.shade300 : Colors.white))),
|
||||
color: !widget.dashboard.canForward() ? widget.dashboard.midDashColor : Colors.white))),
|
||||
|
||||
])),
|
||||
Expanded(
|
||||
child: Padding( child: Text("file opened : ${widget.dashboard.name}", overflow: TextOverflow.ellipsis,
|
||||
child: Padding( child: Text("current workflow : ${widget.dashboard.name}", overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Colors.white, fontSize: 14), textAlign: TextAlign.start),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20))),
|
||||
])),
|
||||
widget.menuExtension != null && MediaQuery.of(context).size.width > 600 ? Container(
|
||||
widget.menuExtension != null && widget.chart.widget.flowChart.widget.width > 600 ? Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(left: BorderSide(color: Colors.white, width: 1))
|
||||
),
|
||||
child: widget.menuExtension
|
||||
) : Container()
|
||||
])
|
||||
);
|
||||
) ]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Widget? w;
|
||||
if (widget.isDashboardInfo && widget.dashboard.elementSelected.length == 1) {
|
||||
w = Container(
|
||||
width: 250,
|
||||
width: 200,
|
||||
height: widget.height,
|
||||
color: Colors.grey.shade300,
|
||||
child: Column( children: [ ...widget.dashboard.infoItemWidget != null ?
|
||||
color: widget.dashboard.midDashColor,
|
||||
child: SingleChildScrollView( child: Column( children: [ ...widget.dashboard.infoItemWidget != null ?
|
||||
widget.dashboard.infoItemWidget!(widget.dashboard.elementSelected.first.element, widget.dashboard.elementSelected.first.id) : [],
|
||||
widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
||||
width: 250,
|
||||
width: 200,
|
||||
margin: EdgeInsets.only(top: 15),
|
||||
decoration: BoxDecoration(border: Border(
|
||||
top: BorderSide(color: Colors.grey, width: 1))),
|
||||
@@ -66,44 +66,44 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
])
|
||||
) : Container()
|
||||
])
|
||||
);
|
||||
));
|
||||
} else if (widget.isDashboardInfo && widget.dashboard.infoWidget != null) {
|
||||
w = Container(
|
||||
width: 250,
|
||||
width: 200,
|
||||
height: widget.height,
|
||||
color: Colors.grey.shade300,
|
||||
color: widget.dashboard.midDashColor,
|
||||
child: Column( children: widget.dashboard.infoWidget != null ? widget.dashboard.infoWidget!() : [])
|
||||
);
|
||||
} else {
|
||||
w = Container( // SHORTCUT
|
||||
width: 250,
|
||||
width: 200,
|
||||
height: widget.height,
|
||||
color: Colors.grey.shade300,
|
||||
color: widget.dashboard.midDashColor,
|
||||
child: Column( children: [
|
||||
Container( padding: EdgeInsets.all(10), width: 250, height: 60,
|
||||
Container( padding: EdgeInsets.all(10), width: 200, height: 60,
|
||||
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Text("STYLE ${widget.dashboard.elementSelected.isNotEmpty ? "ELEMENT" : "ARROW"}", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
||||
Text("<${widget.dashboard.arrowsSelected.isEmpty && widget.dashboard.elementSelected.isEmpty ? "general" : "selected"}>", style: TextStyle(fontSize: 12), textAlign: TextAlign.center),
|
||||
])),
|
||||
Container( width: 250, height: widget.height - 60, child: SingleChildScrollView( child: Column( children: [
|
||||
Container( width: 200, height: widget.height - 60, child: SingleChildScrollView( child: Column( children: [
|
||||
widget.dashboard.elementSelected.isNotEmpty ? Container() : Container( padding: EdgeInsets.symmetric(horizontal: 10, vertical: 20),
|
||||
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Column( children: [
|
||||
Row( children: [
|
||||
InkWell( mouseCursor: SystemMouseCursors.click, child: Container(
|
||||
child: Padding( padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Padding( padding: EdgeInsets.only(left: 10, right: 10),
|
||||
child: PopupMenuButton<ArrowDash>(
|
||||
tooltip: "line defaults",
|
||||
constraints: BoxConstraints(maxWidth: 100),
|
||||
child: Row( children: [
|
||||
MySeparator(
|
||||
width: 65,
|
||||
width: 35,
|
||||
dashWidth: widget.dashboard.defaultDashWidth,
|
||||
dashSpace: widget.dashboard.defaultDashSpace,
|
||||
color: Colors.black
|
||||
),
|
||||
Container(height: 25, width: 10),
|
||||
SizedBox(height: 25, width: 10),
|
||||
Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]),
|
||||
initialValue: null,
|
||||
onSelected: (ArrowDash value) {
|
||||
@@ -122,44 +122,44 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.line,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.line),
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.line),
|
||||
dashSpace: spaceArrowDash(ArrowDash.line),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.largeDash,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.largeDash), dashSpace: spaceArrowDash(ArrowDash.largeDash),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.largeDash), dashSpace: spaceArrowDash(ArrowDash.largeDash),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.mediumDash,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.mediumDash), dashSpace: spaceArrowDash(ArrowDash.mediumDash),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.mediumDash), dashSpace: spaceArrowDash(ArrowDash.mediumDash),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.smallDash,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.smallDash), dashSpace: spaceArrowDash(ArrowDash.smallDash),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.smallDash), dashSpace: spaceArrowDash(ArrowDash.smallDash),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.heavyDotted,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.heavyDotted), dashSpace: spaceArrowDash(ArrowDash.heavyDotted),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.heavyDotted), dashSpace: spaceArrowDash(ArrowDash.heavyDotted),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.mediumDotted,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.mediumDotted), dashSpace: spaceArrowDash(ArrowDash.mediumDotted),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.mediumDotted), dashSpace: spaceArrowDash(ArrowDash.mediumDotted),)
|
||||
]),
|
||||
),
|
||||
PopupMenuItem<ArrowDash>(
|
||||
value: ArrowDash.lightDotted,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
MySeparator(width: 50, dashWidth: widthArrowDash(ArrowDash.lightDotted), dashSpace: spaceArrowDash(ArrowDash.lightDotted),)
|
||||
MySeparator(width: 25, dashWidth: widthArrowDash(ArrowDash.lightDotted), dashSpace: spaceArrowDash(ArrowDash.lightDotted),)
|
||||
]),
|
||||
),
|
||||
]
|
||||
@@ -191,7 +191,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Tooltip( message: "stroke width",
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 10),
|
||||
width: 75, height: 25,
|
||||
width: 55, height: 25,
|
||||
child: TextFormField( textAlign: TextAlign.center,
|
||||
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
||||
initialValue: "${widget.dashboard.defaultStroke}",
|
||||
@@ -278,7 +278,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Tooltip( message: "space dash",
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
width: 155 / 2, height: 25,
|
||||
width: 105 / 2, height: 25,
|
||||
child: TextFormField( textAlign: TextAlign.center,
|
||||
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
||||
initialValue: "${widget.dashboard.defaultDashWidth}",
|
||||
@@ -291,7 +291,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? Colors.grey.shade300 : Colors.white,
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white,
|
||||
filled: true,
|
||||
labelText: "dash",
|
||||
labelStyle: TextStyle(fontSize: 10),
|
||||
@@ -316,7 +316,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Tooltip( message: "space width",
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 10, top: 10),
|
||||
width: 155 / 2, height: 25,
|
||||
width: 105 / 2, height: 25,
|
||||
child: TextFormField( textAlign: TextAlign.center,
|
||||
initialValue: "${widget.dashboard.defaultDashSpace}",
|
||||
onChanged: (value) {
|
||||
@@ -328,7 +328,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? Colors.grey.shade300 : Colors.white,
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white,
|
||||
filled: true,
|
||||
labelText: "space",
|
||||
labelStyle: TextStyle(fontSize: 10),
|
||||
@@ -411,8 +411,8 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Row(children: [
|
||||
Tooltip( message: "forward size",
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 10, top: 10),
|
||||
width: 185, height: 25,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
width: 150, height: 25,
|
||||
child: TextFormField( textAlign: TextAlign.center,
|
||||
initialValue: "${widget.dashboard.defaultForwardWidth}",
|
||||
onChanged: (value) {
|
||||
@@ -436,7 +436,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? Colors.grey.shade300 : Colors.white,
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white,
|
||||
filled: true,
|
||||
labelText: "forward size",
|
||||
labelStyle: TextStyle(fontSize: 10),
|
||||
@@ -463,8 +463,8 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
Row(children: [
|
||||
Tooltip( message: "back size",
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 10, top: 10),
|
||||
width: 185, height: 25,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
width: 150, height: 25,
|
||||
child: TextFormField( textAlign: TextAlign.center,
|
||||
initialValue: "${widget.dashboard.defaultBackWidth}",
|
||||
onChanged: (value) {
|
||||
@@ -488,7 +488,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? Colors.grey.shade300 : Colors.white,
|
||||
fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white,
|
||||
filled: true,
|
||||
labelText: "back size",
|
||||
labelStyle: TextStyle(fontSize: 10),
|
||||
@@ -514,7 +514,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
])
|
||||
])),
|
||||
widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
||||
width: 250,
|
||||
width: 200,
|
||||
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
Tooltip( message: "remove",
|
||||
@@ -560,9 +560,9 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
}
|
||||
return Column( children: [
|
||||
Container( // SHORTCUT
|
||||
width: 250,
|
||||
width: 200,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(color: Colors.grey.shade300, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
decoration: BoxDecoration(color: widget.dashboard.midDashColor, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Row( children: [
|
||||
Tooltip(
|
||||
message: "dashboard information",
|
||||
@@ -570,8 +570,8 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
mouseCursor: SystemMouseCursors.click,
|
||||
child: Container( alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(vertical: 10),
|
||||
color: widget.isDashboardInfo ? Colors.grey : Colors.grey.shade300,
|
||||
width: 125, child: Icon(Icons.info, color: Colors.white))
|
||||
color: widget.isDashboardInfo ? Colors.grey : widget.dashboard.midDashColor,
|
||||
width: 200 / 2, child: Icon(Icons.info, color: Colors.white))
|
||||
)
|
||||
),
|
||||
Tooltip(
|
||||
@@ -580,8 +580,8 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
||||
mouseCursor: SystemMouseCursors.click,
|
||||
child: Container( alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(vertical: 10),
|
||||
color: !widget.isDashboardInfo ? Colors.grey : Colors.grey.shade300,
|
||||
width: 125, child: Icon(Icons.format_paint, color: Colors.white)),
|
||||
color: !widget.isDashboardInfo ? Colors.grey : widget.dashboard.midDashColor,
|
||||
width: 200 / 2, child: Icon(Icons.format_paint, color: Colors.white)),
|
||||
))
|
||||
])),
|
||||
w
|
||||
|
||||
@@ -390,7 +390,7 @@ class GraphParamsWidgetState extends State<GraphParamsWidget> {
|
||||
child: Row(children: [
|
||||
IconButton(onPressed: () {
|
||||
widget.comp.setState(() {
|
||||
widget.comp.widget.dashboard.arrows.removeWhere((el) => el.fromID == "${widget.element.id}${widget.index}");
|
||||
widget.comp.widget.dashboard.removeArrows((el) => el.fromID == "${widget.element.id}${widget.index}");
|
||||
widget.element.next.removeAt(widget.index);
|
||||
});
|
||||
}, icon: Icon(Icons.delete))
|
||||
@@ -399,17 +399,18 @@ class GraphParamsWidgetState extends State<GraphParamsWidget> {
|
||||
}
|
||||
|
||||
class ArrowInfoWidget extends StatefulWidget {
|
||||
ArrowInfoWidget ({ Key? key, }): super(key: key);
|
||||
Dashboard dashboard;
|
||||
ArrowInfoWidget ({ Key? key, required this.dashboard }): super(key: key);
|
||||
@override ArrowInfoWidgetState createState() => ArrowInfoWidgetState();
|
||||
}
|
||||
class ArrowInfoWidgetState extends State<ArrowInfoWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
return SingleChildScrollView( child: Column(children: [
|
||||
Container(height: 50,
|
||||
decoration: BoxDecoration(color: Colors.grey.shade300, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
decoration: BoxDecoration(color: widget.dashboard.midDashColor, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Center( child: Text("<Arrow> Style", style: TextStyle(fontSize: 20)))),
|
||||
Container(height: 50,
|
||||
decoration: BoxDecoration(color: Colors.grey.shade300, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
decoration: BoxDecoration(color: widget.dashboard.midDashColor, border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||
child: Row(children: [],)
|
||||
),
|
||||
],) );
|
||||
@@ -731,8 +732,8 @@ class ArrowPainter extends CustomPainter {
|
||||
|
||||
|
||||
bool isLine(Offset position) {
|
||||
for (double i=-20; i < 20; i++) {
|
||||
for (double y=-20; y < 20; y++) {
|
||||
for (double i=-5; i < 5; i++) {
|
||||
for (double y=-5; y < 5; y++) {
|
||||
var pos = position + Offset(i, y);
|
||||
if (path.contains(pos)) {
|
||||
return true;
|
||||
|
||||
@@ -210,7 +210,7 @@ class _ElementHandler extends StatelessWidget {
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTapDown: (details) =>
|
||||
tapDown = details.globalPosition - dashboard.position,
|
||||
tapDown = details.globalPosition - dashboard.position ,
|
||||
onSecondaryTapDown: (details) => secondaryTapDown =
|
||||
details.globalPosition - dashboard.position,
|
||||
onTap: () {
|
||||
@@ -266,10 +266,10 @@ class _ElementHandler extends StatelessWidget {
|
||||
forwardWidth: dashboard.defaultForwardWidth,
|
||||
);
|
||||
DrawingArrow.instance.from =
|
||||
details.globalPosition - Offset(-10, 45);
|
||||
details.globalPosition - Offset(dashboard.widthOffset - 10, 45 + dashboard.heightOffset); // todo change
|
||||
isDragging = true;
|
||||
}
|
||||
DrawingArrow.instance.to = details.globalPosition - Offset(-10, 50);
|
||||
DrawingArrow.instance.to = details.globalPosition - Offset(dashboard.widthOffset - 10, 50 + dashboard.heightOffset); // todo change
|
||||
DrawingArrow.instance.setParams(
|
||||
DrawingArrow.instance.params.copyWith(
|
||||
endArrowPosition: Alignment.center,
|
||||
|
||||
@@ -13,11 +13,19 @@ import 'package:flutter_flow_chart/src/objects/any_widget.dart';
|
||||
|
||||
/// Widget that use [element] properties to display it on the dashboard scene
|
||||
class ElementWidget<T extends FlowData> extends StatefulWidget {
|
||||
Widget? bottomLeftBadge;
|
||||
Widget? bottomRightBadge;
|
||||
Widget? topLeftBadge;
|
||||
Widget? topRightBadge;
|
||||
///
|
||||
ElementWidget({
|
||||
required this.dashboard,
|
||||
required this.element,
|
||||
super.key,
|
||||
this.bottomLeftBadge,
|
||||
this.bottomRightBadge,
|
||||
this.topLeftBadge,
|
||||
this.topRightBadge,
|
||||
this.onElementPressed,
|
||||
this.onElementSecondaryTapped,
|
||||
this.onElementLongPressed,
|
||||
@@ -27,7 +35,7 @@ class ElementWidget<T extends FlowData> extends StatefulWidget {
|
||||
this.onHandlerLongPressed,
|
||||
this.onHandlerSecondaryLongTapped,
|
||||
});
|
||||
|
||||
Color? dashColor;
|
||||
///
|
||||
final Dashboard dashboard;
|
||||
|
||||
@@ -153,8 +161,7 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
widget.onElementLongPressed?.call(context, tapLocation);
|
||||
},
|
||||
onSecondaryLongPress: () {
|
||||
widget.onElementSecondaryLongTapped
|
||||
?.call(context, secondaryTapDownPos);
|
||||
widget.onElementSecondaryLongTapped?.call(context, secondaryTapDownPos);
|
||||
},
|
||||
child: Listener(
|
||||
onPointerDown: (event) {
|
||||
@@ -168,8 +175,7 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
color: Colors.transparent,
|
||||
child: Padding( padding: EdgeInsets.all(6),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(border: Border.all(
|
||||
color: Colors.red, width: 2)),
|
||||
decoration: BoxDecoration(border: Border.all( color: Colors.red, width: 2)),
|
||||
width: widget.element.size.width - 12,
|
||||
height: widget.element.size.height - 12, child: element)
|
||||
),
|
||||
@@ -183,9 +189,9 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
onHandlerLongPressed: widget.onHandlerLongPressed,
|
||||
onHandlerSecondaryLongTapped: widget.onHandlerSecondaryLongTapped,
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(6),
|
||||
margin: EdgeInsets.all(10), // why some change
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: widget.element.isSelected ? Colors.red : Colors.grey.shade300,
|
||||
border: Border.all(color: widget.element.isSelected ? Colors.red : widget.dashboard.midDashColor,
|
||||
width: widget.element.isSelected ? 2 : 1),
|
||||
),
|
||||
child: InkWell( mouseCursor: SystemMouseCursors.grab, child: element )
|
||||
@@ -199,7 +205,8 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
var diff = Offset(widget.element.position.dx, widget.element.position.dy);
|
||||
widget.element.isSelected = true;
|
||||
widget.element.changePosition(
|
||||
details.globalPosition - delta - Offset(0, 50),
|
||||
details.globalPosition - delta - Offset(
|
||||
widget.dashboard.widthOffset, 50 + widget.dashboard.heightOffset), // todo change
|
||||
);
|
||||
diff = widget.element.position - diff;
|
||||
if (widget.element.isSelected) {
|
||||
@@ -211,7 +218,9 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
},
|
||||
onDragEnd: (details) {
|
||||
var diff = Offset(widget.element.position.dx, widget.element.position.dy);
|
||||
widget.element.changePosition(details.offset - Offset(0, 50));
|
||||
widget.element.changePosition(details.offset - Offset(
|
||||
widget.dashboard.widthOffset, 50 + widget.dashboard.heightOffset
|
||||
)); // todo change
|
||||
diff = widget.element.position - diff;
|
||||
if (widget.element.isSelected) {
|
||||
for (var sel in widget.dashboard.elementSelected) {
|
||||
@@ -226,9 +235,13 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
);
|
||||
w = ResizeWidget(
|
||||
comp: this,
|
||||
bottomLeftBadge: widget.bottomLeftBadge,
|
||||
bottomRightBadge: widget.bottomRightBadge,
|
||||
topLeftBadge: widget.topLeftBadge,
|
||||
topRightBadge: widget.topRightBadge,
|
||||
element: widget.element,
|
||||
dashboard: widget.dashboard,
|
||||
handlerColor: widget.isHovered ? Color.fromRGBO(38, 166, 154, 1) : Colors.transparent,
|
||||
handlerColor: widget.isHovered ? widget.dashboard.dashColor : Colors.transparent,
|
||||
child: w
|
||||
);
|
||||
return Transform.translate(
|
||||
@@ -237,8 +250,8 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
child: MouseRegion(
|
||||
onEnter: (event) { setState(() { widget.isHovered = true; }); },
|
||||
onExit: (event) { setState(() { widget.isHovered = false; }); },
|
||||
child: Wrap( direction: Axis.vertical, children: [
|
||||
w,
|
||||
child: Wrap( direction: Axis.vertical, children: [
|
||||
w,
|
||||
Container(
|
||||
constraints: BoxConstraints( minWidth: widget.element.size.width ),
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -258,7 +271,7 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
widget.dashboard.addElement(newElement);
|
||||
}, icon: Icon(Icons.copy, size: 20)),
|
||||
]))
|
||||
)
|
||||
),
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
@@ -5,15 +5,21 @@ import 'package:flutter_flow_chart/src/ui/handler_widget.dart';
|
||||
|
||||
/// The widget to press and drag to resize the element
|
||||
class ResizeWidget extends StatefulWidget {
|
||||
Widget? bottomLeftBadge;
|
||||
Widget? bottomRightBadge;
|
||||
Widget? topLeftBadge;
|
||||
Widget? topRightBadge;
|
||||
///
|
||||
ResizeWidget({
|
||||
required this.comp,
|
||||
required this.element,
|
||||
required this.dashboard,
|
||||
required this.child,
|
||||
this.bottomLeftBadge,
|
||||
this.bottomRightBadge,
|
||||
this.topLeftBadge,
|
||||
this.topRightBadge,
|
||||
this.handlerColor =const Color.fromRGBO(38, 166, 154, 1),
|
||||
this.additionnalHeight = 0,
|
||||
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -27,10 +33,6 @@ class ResizeWidget extends StatefulWidget {
|
||||
|
||||
///
|
||||
final Widget child;
|
||||
|
||||
///
|
||||
final double additionnalHeight;
|
||||
|
||||
@override
|
||||
State<ResizeWidget> createState() => _ResizeWidgetState();
|
||||
}
|
||||
@@ -40,12 +42,16 @@ class _ResizeWidgetState extends State<ResizeWidget> {
|
||||
late Offset elementStartPosition;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
return Container(
|
||||
width: widget.element.size.width,
|
||||
height: widget.element.size.height + widget.additionnalHeight,
|
||||
height: widget.element.size.height,
|
||||
child: Stack(
|
||||
children: [
|
||||
widget.child,
|
||||
widget.topLeftBadge == null ? Container() : Positioned(top: 0, left: 0, child: widget.topLeftBadge!),
|
||||
widget.topRightBadge == null ? Container() : Positioned(top: 0, right: 0, child: widget.topRightBadge!),
|
||||
widget.bottomRightBadge == null ? Container() : Positioned(bottom: 0, right: 0, child: widget.bottomRightBadge!),
|
||||
widget.bottomLeftBadge == null ? Container() : Positioned(bottom: 0, left: 0, child: widget.bottomLeftBadge!),
|
||||
_handler(Alignment.topLeft),
|
||||
_handler(Alignment.topRight),
|
||||
_handler(Alignment.bottomLeft),
|
||||
|
||||
@@ -63,7 +63,6 @@ class _SegmentHandlerState extends State<SegmentHandler> {
|
||||
},
|
||||
onDragEnd: (details) {
|
||||
widget.pivot.pivot = details.offset;
|
||||
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
|
||||
Reference in New Issue
Block a user