Enhance SkillTreeView with Asynchronous Initialization and Node Mapping

This commit refactors the SkillTreeView class to include asynchronous initialization through FutureBuilder. The new version also replaces the integer-based node IDs with string-based IDs, aligning better with the SkillTreeNode model. The code now clears previous graph nodes and edges before adding new ones, preventing duplication. Additionally, the TreeNodeView component is now populated dynamically with data from the SkillTreeNode model, making the tree view more robust and integrated.
This commit is contained in:
hunteraraujo
2023-09-13 17:50:53 -07:00
parent 01b2892775
commit a7bb335752

View File

@@ -1,3 +1,4 @@
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_node.dart';
import 'package:auto_gpt_flutter_client/viewmodels/skill_tree_viewmodel.dart';
import 'package:auto_gpt_flutter_client/views/skill_tree/tree_node_view.dart';
import 'package:flutter/material.dart';
@@ -9,62 +10,87 @@ class SkillTreeView extends StatefulWidget {
const SkillTreeView({Key? key, required this.viewModel}) : super(key: key);
@override
_TreeViewPageState createState() => _TreeViewPageState();
_SkillTreeViewState createState() => _SkillTreeViewState();
}
class _TreeViewPageState extends State<SkillTreeView> {
class _SkillTreeViewState extends State<SkillTreeView> {
Future<void>? initialization;
@override
void initState() {
super.initState();
widget.viewModel.initializeSkillTree();
// Create Node and Edge objects for GraphView
final Map<int, Node> nodeMap = {};
for (var skillTreeNode in widget.viewModel.skillTreeNodes) {
final node = Node.Id(skillTreeNode.id);
widget.viewModel.graph.addNode(node);
nodeMap[skillTreeNode.id] = node;
}
for (var skillTreeEdge in widget.viewModel.skillTreeEdges) {
final fromNode = nodeMap[int.parse(skillTreeEdge.from)];
final toNode = nodeMap[int.parse(skillTreeEdge.to)];
widget.viewModel.graph.addEdge(fromNode!, toNode!);
}
initialization = widget.viewModel.initializeSkillTree();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: InteractiveViewer(
constrained: false,
boundaryMargin: EdgeInsets.all(100),
minScale: 0.01,
maxScale: 5.6,
child: GraphView(
graph: widget.viewModel.graph,
algorithm: BuchheimWalkerAlgorithm(widget.viewModel.builder,
TreeEdgeRenderer(widget.viewModel.builder)),
paint: Paint()
..color = Colors.green
..strokeWidth = 1
..style = PaintingStyle.stroke,
builder: (Node node) {
int nodeId = node.key?.value as int;
return TreeNodeView(
nodeId: nodeId,
selected: nodeId == widget.viewModel.selectedNode?.id);
},
return FutureBuilder<void>(
future: initialization,
builder: (context, snapshot) {
widget.viewModel.graph.nodes.clear();
widget.viewModel.graph.edges.clear();
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return const Text("An error occurred");
}
// Create Node and Edge objects for GraphView
final Map<String, Node> nodeMap = {};
for (var skillTreeNode in widget.viewModel.skillTreeNodes) {
final node = Node.Id(skillTreeNode.id);
widget.viewModel.graph.addNode(node);
nodeMap[skillTreeNode.id] = node;
}
for (var skillTreeEdge in widget.viewModel.skillTreeEdges) {
final fromNode = nodeMap[skillTreeEdge.from];
final toNode = nodeMap[skillTreeEdge.to];
if (fromNode != null && toNode != null) {
widget.viewModel.graph.addEdge(fromNode, toNode);
}
}
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: InteractiveViewer(
constrained: false,
boundaryMargin: const EdgeInsets.all(100),
minScale: 0.01,
maxScale: 5.6,
child: GraphView(
graph: widget.viewModel.graph,
algorithm: BuchheimWalkerAlgorithm(widget.viewModel.builder,
TreeEdgeRenderer(widget.viewModel.builder)),
paint: Paint()
..color = Colors.green
..strokeWidth = 1
..style = PaintingStyle.stroke,
builder: (Node node) {
String nodeId = node.key?.value as String;
SkillTreeNode? skillTreeNode =
widget.viewModel.getNodeById(nodeId);
if (skillTreeNode != null) {
return TreeNodeView(
node: skillTreeNode,
selected:
nodeId == widget.viewModel.selectedNode?.id);
} else {
return const SizedBox(); // Return an empty widget if the node is not found
}
},
),
),
),
),
],
),
],
),
);
},
);
}
}