129 lines
3.3 KiB
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;
|
|
}
|
|
}
|