aves_mio0.31/lib/widgets/collection/album_controller.dart
2026-07-18 13:39:22 +02:00

181 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:aves/model/db/local_media_db.dart';
import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/vaults/vaults.dart';
import 'album_sort.dart';
/// Controller che gestisce la lista degli album (basato su tabella `folders`)
class AlbumController extends ChangeNotifier {
final LocalMediaDb localMediaDb;
AlbumController({required this.localMediaDb});
bool loading = true;
// Lista completa degli album (AlbumRow)
List<AlbumRow> _allAlbums = [];
AlbumSortType _sortType = AlbumSortType.priorityThenName;
// ============================================================
// CARICAMENTO
// ============================================================
Future<void> load() async {
loading = true;
notifyListeners();
// 1) Carica tutte le righe della tabella `folders`
final rows = await localMediaDb.loadFolders();
// 2) Nessun loadEntriesMap(): thumbEntry = null
final list = <AlbumRow>[];
final entriesMap = await localMediaDb.loadEntriesMap();
for (final row in rows) {
list.add(
AlbumRow(
path: row.path,
displayName: row.displayName,
albumType: row.albumType,
priority: row.priority,
totalSize: row.totalSize,
fileCount: row.fileCount,
isRemote: row.isRemote == 1,
isVault: vaults.vaultDirectories.contains(row.path),
hybridType: row.hybridType,
hidden: row.hidden == 1,
thumbEntry: row.thumbEntryId != null ? entriesMap[row.thumbEntryId] : null,
),
);
}
// 3) Ordina
_allAlbums = sortAlbums(list, _sortType);
loading = false;
notifyListeners();
}
Future<void> refresh() async => load();
// ============================================================
// SEZIONI: PINNED + NORMAL
// ============================================================
List<AlbumRow> get pinnedAlbums {
final list = _allAlbums.where((a) => a.priority > 0 && !a.hidden).toList();
list.sort((a, b) => a.priority.compareTo(b.priority));
return list;
}
List<AlbumRow> get normalAlbums {
final list = _allAlbums.where((a) => a.priority == 0 && !a.hidden).toList();
list.sort((a, b) => a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()));
return list;
}
// ============================================================
// SORT
// ============================================================
void sortBy(AlbumSortType type) {
_sortType = type;
switch (type) {
case AlbumSortType.priorityThenName:
_allAlbums.sort((a, b) {
final aPinned = a.priority > 0;
final bPinned = b.priority > 0;
if (aPinned && !bPinned) return -1;
if (!aPinned && bPinned) return 1;
if (aPinned && bPinned) {
return a.priority.compareTo(b.priority);
}
return a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase());
});
break;
case AlbumSortType.nameAsc:
_allAlbums.sort((a, b) => a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()));
break;
case AlbumSortType.nameDesc:
_allAlbums.sort((a, b) => b.displayName.toLowerCase().compareTo(a.displayName.toLowerCase()));
break;
}
notifyListeners();
}
// ============================================================
// PIN / UNPIN
// ============================================================
Future<void> togglePin(AlbumRow album) async {
final newPriority = album.priority > 0 ? 0 : _computeNewPinPriority();
await localMediaDb.updateFolderPriority(album.path, newPriority);
await load();
}
int _computeNewPinPriority() {
final pinned = pinnedAlbums;
if (pinned.isEmpty) return 1000;
return pinned.first.priority + 1000;
}
// ============================================================
// DRAG & DROP PINNED
// ============================================================
Future<void> reorderPinned(int oldIndex, int newIndex) async {
final pinned = pinnedAlbums;
if (newIndex > oldIndex) newIndex -= 1;
final item = pinned.removeAt(oldIndex);
pinned.insert(newIndex, item);
for (int i = 0; i < pinned.length; i++) {
final album = pinned[i];
final newPriority = i + 1;
if (album.priority != newPriority) {
await localMediaDb.updateFolderPriority(album.path, newPriority);
}
}
await load();
}
// ============================================================
// NASCONDI / MOSTRA
// ============================================================
Future<void> toggleHidden(AlbumRow album) async {
final newHidden = album.hidden ? 0 : 1;
await localMediaDb.updateFolderHidden(album.path, newHidden);
await load();
}
// ============================================================
// RINOMINA
// ============================================================
Future<void> renameAlbum(AlbumRow album, String newName) async {
await localMediaDb.updateFolderDisplayName(album.path, newName);
await load();
}
// ============================================================
// CAMBIA COVER
// ============================================================
Future<void> setCover(AlbumRow album, AvesEntry entry) async {
await localMediaDb.updateFolderCover(album.path, entry.id);
await load();
}
// ============================================================
// ELIMINA ALBUM
// ============================================================
Future<void> deleteAlbum(AlbumRow album) async {
await localMediaDb.deleteFolder(album.path);
await load();
}
}