import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:logic_circuits_simulator/models/projects.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; import 'package:uuid/uuid.dart'; class ProjectsState extends ChangeNotifier { ProjectsState() { _init(); } List get projects => index.projects; ProjectsIndex index = const ProjectsIndex(projects: []); Future _getProjectsDir() async { final appDir = await getApplicationDocumentsDirectory(); final result = Directory(path.join(appDir.path, 'LogicCircuitsSimulator', 'projects')); if (!await result.exists()) { await result.create(recursive: true); } return result; } Future _getIndexFile() async { final result = File(path.join((await _getProjectsDir()).path, 'index.json')); return result; } Future _updateIndex(ProjectsIndex newIndex) async { // Sort projects when updating: latest update first index = newIndex.copyWith(projects: newIndex.projects.toList()..sort((p1, p2) => p2.lastUpdate.compareTo(p1.lastUpdate))); final indexFile = await _getIndexFile(); await indexFile.writeAsString(const JsonEncoder.withIndent(" ").convert(index.toJson())); notifyListeners(); } void _init() async { final indexFile = await _getIndexFile(); if (await indexFile.exists()) { index = ProjectsIndex.fromJson(jsonDecode(await indexFile.readAsString())); notifyListeners(); } } Future newProject(String projectName) async { final id = const Uuid().v4(); final project = ProjectEntry( lastUpdate: DateTime.now(), projectName: projectName, projectId: id, ); await _updateIndex(index.copyWith(projects: index.projects + [project])); final projectDir = await Directory(path.join((await _getProjectsDir()).path, id)).create(); await Directory(path.join(projectDir.path, 'components')).create(); if (kDebugMode) { print('Created new project in ${projectDir.path}'); } } Future deleteProject(String projectId) async { await _updateIndex(index.copyWith(projects: index.projects.where((p) => p.projectId != projectId).toList())); await Directory(path.join((await _getProjectsDir()).path, projectId)).delete(recursive: true); } Future updateProject(ProjectEntry project) async { if (!index.projects.map((p) => p.projectId).contains(project.projectId)) { throw Exception('Project not in index!'); } await _updateIndex( index.copyWith( projects: index.projects .where((p) => p.projectId != project.projectId) .toList() + [project] ) ); } }