TF-37 Generate tree with Map

This commit is contained in:
Dat PHAM HOANG
2021-08-31 18:08:58 +07:00
committed by Dat H. Pham
parent 41b4e8296c
commit e63298bc29
6 changed files with 44 additions and 242 deletions
@@ -1,4 +1,3 @@
import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
@@ -8,39 +7,19 @@ class MailboxNode with EquatableMixin{
static PresentationMailbox _root = PresentationMailbox(MailboxId(Id('root')));
PresentationMailbox item;
late BuiltList<MailboxNode> childrenItems;
List<MailboxNode>? childrenItems;
factory MailboxNode.root() => MailboxNode(_root);
bool hasChildren() => childrenItems.isNotEmpty;
bool hasChildren() => childrenItems?.isNotEmpty ?? false;
MailboxNode(this.item, {List<MailboxNode> child = const []}) {
this.childrenItems = BuiltList(child);
}
MailboxNode(this.item, {this.childrenItems});
MailboxNode? addChild(PresentationMailbox mailbox) {
if (_validateChild(mailbox)) {
final node = MailboxNode(mailbox);
_addChildNode(node);
return node;
void addChildNode(MailboxNode node) {
if (childrenItems == null) {
childrenItems = [];
}
return null;
}
void _addChildNode(MailboxNode node) {
childrenItems = (ListBuilder<MailboxNode>(childrenItems)
..add(node))
.build();
}
bool _validateChild(PresentationMailbox mailbox) {
if (mailbox.parentId == item.id) {
return true;
}
if (item == _root) {
return true;
}
return false;
childrenItems?.add(node);
}
@override
@@ -1,8 +1,5 @@
import 'dart:collection';
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'mailbox_node.dart';
@@ -10,34 +7,6 @@ class MailboxTree with EquatableMixin {
MailboxNode root;
MailboxTree(this.root);
MailboxNode? findNode(MailboxId? mailboxId) {
var result;
final queue = ListQueue<MailboxNode>();
queue.addLast(root);
while (queue.isNotEmpty && mailboxId != null) {
final currentNode = queue.removeFirst();
if (mailboxId == currentNode.item.id) {
result = currentNode;
break;
}
currentNode.childrenItems.forEach((child) {
queue.addLast(child);
});
}
return result;
}
MailboxNode? insertNode(PresentationMailbox mailbox) {
if (mailbox.parentId == null) {
return root.addChild(mailbox);
}
final foundParent = findNode(mailbox.parentId);
return foundParent != null
? foundParent.addChild(mailbox)
: root.addChild(mailbox);
}
@override
List<Object?> get props => [root];
}
@@ -1,6 +1,5 @@
import 'dart:collection';
import 'package:built_collection/built_collection.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
@@ -9,50 +8,24 @@ import 'mailbox_tree.dart';
class TreeBuilder {
Future<MailboxTree> generateMailboxTree(List<PresentationMailbox> mailboxesList) async {
final Map<MailboxId, BuiltList<PresentationMailbox>> mapNotFoundParentMailbox = HashMap();
final Map<MailboxId, MailboxNode> mailboxDictionary = HashMap();
final tree = MailboxTree(MailboxNode.root());
mailboxesList.forEach((mailbox) {
if (mailbox.hasParentId()) {
final parentId = mailbox.parentId!;
final foundParent = tree.findNode(parentId);
if (foundParent != null) {
_addDescendant(tree, mailbox, maybeDescendant: mapNotFoundParentMailbox);
} else {
final siblingTrees = mapNotFoundParentMailbox[mailbox.parentId];
if (siblingTrees != null) {
mapNotFoundParentMailbox.addAll({
parentId: (ListBuilder<PresentationMailbox>(siblingTrees)..add(mailbox)).build()
});
} else {
mapNotFoundParentMailbox.addAll({parentId: (ListBuilder<PresentationMailbox>()..add(mailbox)).build()});
}
}
} else {
_addDescendant(tree, mailbox, maybeDescendant: mapNotFoundParentMailbox);
}
mailboxDictionary[mailbox.id] = MailboxNode(mailbox);
});
mapNotFoundParentMailbox.forEach((_, listMailbox) {
listMailbox.forEach((mailbox) {
_addDescendant(tree, mailbox);
});
mailboxesList.forEach((mailbox) {
final parentId = mailbox.parentId;
final parentNode = mailboxDictionary[parentId];
final node = mailboxDictionary[mailbox.id];
if (node != null) {
if (parentNode != null) {
parentNode.addChildNode(node);
} else {
tree.root.addChildNode(node);
}
}
});
return tree;
}
MailboxNode? _addDescendant(
MailboxTree tree,
PresentationMailbox mailboxChild,
{Map<MailboxId, BuiltList<PresentationMailbox>>? maybeDescendant}
) {
final queue = ListQueue<PresentationMailbox>();
queue.addLast(mailboxChild);
while (queue.isNotEmpty) {
final current = queue.removeFirst();
tree.insertNode(current);
maybeDescendant?.remove(current.id)?.forEach((child) {
queue.addLast(child);
});
}
}
}