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.from(_projectStore.projects); } final ProjectStore _projectStore; List _projects = []; String? _selectedProjectId; List get projects => List.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 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().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) => [project, ...current], ); _projects = List.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().firstWhere( (project) => project?.workingDirectory == normalizedDirectory, orElse: () => null, ); final nextSelectedId = match?.id; if (_selectedProjectId == nextSelectedId) { return; } _selectedProjectId = nextSelectedId; notifyListeners(); } Future removeProject(String id) async { await _projectStore.update( (current) => current.where((project) => project.id != id).toList(), ); _projects = List.from(_projectStore.projects); if (_selectedProjectId == id) { _selectedProjectId = null; } notifyListeners(); } String _projectNameForDirectory(String workingDirectory) { final baseName = path.basename(workingDirectory); return baseName.isEmpty ? workingDirectory : baseName; } }