yumi-flutter/lib/services/music/room_music_repository.dart
2026-04-29 14:52:09 +08:00

63 lines
1.7 KiB
Dart

import 'dart:convert';
import 'package:yumi/shared/data_sources/models/sc_music_mode.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
class RoomMusicRepository {
List<SCMusicMode> loadSongs() {
final raw = DataPersistence.getUserRoomMusic();
if (raw.trim().isEmpty) {
return <SCMusicMode>[];
}
try {
final decoded = jsonDecode(raw);
if (decoded is! List) {
return <SCMusicMode>[];
}
final songs =
decoded
.map((item) => SCMusicMode.fromJson(item))
.where((item) => item.hasPlayablePath)
.toList()
..sort((a, b) {
final sort = a.sortIndex.compareTo(b.sortIndex);
if (sort != 0) {
return sort;
}
return a.addedAt.compareTo(b.addedAt);
});
return _normalizeSort(songs);
} catch (_) {
return <SCMusicMode>[];
}
}
Future<bool> saveSongs(List<SCMusicMode> songs) {
final normalized = _normalizeSort(_dedupeSongs(songs));
return DataPersistence.setUserRoomMusic(
jsonEncode(normalized.map((item) => item.toJson()).toList()),
);
}
List<SCMusicMode> _dedupeSongs(List<SCMusicMode> songs) {
final seen = <String>{};
final result = <SCMusicMode>[];
for (final song in songs) {
final key = song.id.isNotEmpty ? song.id : song.localPath;
if (key.isEmpty || !seen.add(key)) {
continue;
}
result.add(song);
}
return result;
}
List<SCMusicMode> _normalizeSort(List<SCMusicMode> songs) {
return List<SCMusicMode>.generate(
songs.length,
(index) => songs[index].copyWith(sortIndex: index),
growable: true,
);
}
}