181 lines
5.6 KiB
Dart
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();
|
|
}
|
|
}
|