f1e0f6b5ef
- Add complete server infrastructure with Gitea, API, PostgreSQL - Implement Obsidian-compatible markdown mindmap converter - Add Flutter service for server synchronization - Configure GitHub Actions for automated build and deploy - Add production docker-compose with health checks - Include VPS setup and deployment scripts - Add comprehensive deployment documentation
89 lines
2.5 KiB
Dart
89 lines
2.5 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
class MindMapModel {
|
|
final String id;
|
|
final String title;
|
|
final String description;
|
|
final String ownerEmail;
|
|
final bool isMain; // Основные карты (админские) vs Личные
|
|
final List<Map<String, dynamic>> nodes;
|
|
final Map<String, dynamic> settings;
|
|
final DateTime createdAt;
|
|
final DateTime updatedAt;
|
|
|
|
MindMapModel({
|
|
required this.id,
|
|
required this.title,
|
|
this.description = '',
|
|
required this.ownerEmail,
|
|
this.isMain = false,
|
|
this.nodes = const [],
|
|
this.settings = const {},
|
|
required this.createdAt,
|
|
required this.updatedAt,
|
|
});
|
|
|
|
factory MindMapModel.fromFirestore(DocumentSnapshot doc) {
|
|
final data = doc.data() as Map<String, dynamic>;
|
|
return MindMapModel.fromMap(doc.id, data);
|
|
}
|
|
|
|
factory MindMapModel.fromMap(String id, Map<String, dynamic> data) {
|
|
return MindMapModel(
|
|
id: id,
|
|
title: data['title'] ?? '',
|
|
description: data['description'] ?? '',
|
|
ownerEmail: data['ownerEmail'] ?? '',
|
|
isMain: data['isMain'] ?? false,
|
|
nodes: List<Map<String, dynamic>>.from(data['nodes'] ?? []),
|
|
settings: data['settings'] ?? {},
|
|
createdAt: (data['createdAt'] as Timestamp).toDate(),
|
|
updatedAt: (data['updatedAt'] as Timestamp).toDate(),
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toFirestore() {
|
|
return {
|
|
'title': title,
|
|
'description': description,
|
|
'ownerEmail': ownerEmail,
|
|
'isMain': isMain,
|
|
'nodes': nodes,
|
|
'settings': settings,
|
|
'createdAt': Timestamp.fromDate(createdAt),
|
|
'updatedAt': Timestamp.fromDate(updatedAt),
|
|
};
|
|
}
|
|
|
|
MindMapModel copyWith({
|
|
String? id,
|
|
String? title,
|
|
String? description,
|
|
String? ownerEmail,
|
|
bool? isMain,
|
|
List<Map<String, dynamic>>? nodes,
|
|
Map<String, dynamic>? settings,
|
|
DateTime? createdAt,
|
|
DateTime? updatedAt,
|
|
}) {
|
|
return MindMapModel(
|
|
id: id ?? this.id,
|
|
title: title ?? this.title,
|
|
description: description ?? this.description,
|
|
ownerEmail: ownerEmail ?? this.ownerEmail,
|
|
isMain: isMain ?? this.isMain,
|
|
nodes: nodes ?? this.nodes,
|
|
settings: settings ?? this.settings,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
updatedAt: updatedAt ?? this.updatedAt,
|
|
);
|
|
}
|
|
|
|
int get nodeCount => nodes.length;
|
|
int get maxLevel {
|
|
if (nodes.isEmpty) return 0;
|
|
return nodes.fold(
|
|
0, (max, node) => max > (node['level'] ?? 0) ? max : (node['level'] ?? 0));
|
|
}
|
|
}
|