The-Agency/lib/ui/providers/projects_provider.dart

129 lines
3.3 KiB
Dart

import "dart:io";
import "package:flutter/foundation.dart";
import "package:path/path.dart" as path;
import "package:uuid/uuid.dart";
import "../../src/project_store.dart";
class ProjectsProvider extends ChangeNotifier {
ProjectsProvider(this._projectStore) {
_projects = List<ProjectRecord>.from(_projectStore.projects);
}
final ProjectStore _projectStore;
List<ProjectRecord> _projects = <ProjectRecord>[];
String? _selectedProjectId;
List<ProjectRecord> get projects =>
List<ProjectRecord>.unmodifiable(_projects);
String? get selectedProjectId => _selectedProjectId;
ProjectRecord? get selectedProject {
final selectedId = _selectedProjectId;
if (selectedId == null) {
return null;
}
for (final project in _projects) {
if (project.id == selectedId) {
return project;
}
}
return null;
}
Future<ProjectRecord?> addProject(String workingDirectory) async {
final normalizedDirectory = workingDirectory.trim();
if (normalizedDirectory.isEmpty) {
return null;
}
final directory = Directory(normalizedDirectory);
if (!await directory.exists()) {
return null;
}
final existing = _projects.cast<ProjectRecord?>().firstWhere(
(project) => project?.workingDirectory == normalizedDirectory,
orElse: () => null,
);
if (existing != null) {
_selectedProjectId = existing.id;
notifyListeners();
return existing;
}
const uuid = Uuid();
final project = ProjectRecord(
id: uuid.v4(),
name: _projectNameForDirectory(normalizedDirectory),
workingDirectory: normalizedDirectory,
createdAt: DateTime.now().toUtc(),
);
await _projectStore.update(
(current) => <ProjectRecord>[project, ...current],
);
_projects = List<ProjectRecord>.from(_projectStore.projects);
_selectedProjectId = project.id;
notifyListeners();
return project;
}
void selectProject(String id) {
if (_selectedProjectId == id) {
return;
}
final exists = _projects.any((project) => project.id == id);
if (!exists) {
return;
}
_selectedProjectId = id;
notifyListeners();
}
void selectProjectByWorkingDirectory(String? workingDirectory) {
final normalizedDirectory = workingDirectory?.trim();
if (normalizedDirectory == null || normalizedDirectory.isEmpty) {
if (_selectedProjectId != null) {
_selectedProjectId = null;
notifyListeners();
}
return;
}
final match = _projects.cast<ProjectRecord?>().firstWhere(
(project) => project?.workingDirectory == normalizedDirectory,
orElse: () => null,
);
final nextSelectedId = match?.id;
if (_selectedProjectId == nextSelectedId) {
return;
}
_selectedProjectId = nextSelectedId;
notifyListeners();
}
Future<void> removeProject(String id) async {
await _projectStore.update(
(current) => current.where((project) => project.id != id).toList(),
);
_projects = List<ProjectRecord>.from(_projectStore.projects);
if (_selectedProjectId == id) {
_selectedProjectId = null;
}
notifyListeners();
}
String _projectNameForDirectory(String workingDirectory) {
final baseName = path.basename(workingDirectory);
return baseName.isEmpty ? workingDirectory : baseName;
}
}