mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 20:43:04 +00:00
Fix mobile app submodule initialization and cleanup
- Removed incorrect swingmusic_mobile directory - Properly initialized swingmusic_mobile submodule from swingmusic-mobile.git - Clean submodule configuration for unified release workflow
This commit is contained in:
@@ -1,236 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'track_model.dart';
|
||||
|
||||
class AlbumModel extends Equatable {
|
||||
final List<ArtistModel> albumartists;
|
||||
final String albumhash;
|
||||
final List<String> artisthashes;
|
||||
final String baseTitle;
|
||||
final String color;
|
||||
final int createdDate;
|
||||
final int date;
|
||||
final int duration;
|
||||
final List<GenreModel> genres;
|
||||
final List<String> genrehashes;
|
||||
final String originalTitle;
|
||||
final String title;
|
||||
final int trackcount;
|
||||
final int lastplayed;
|
||||
final int playcount;
|
||||
final int playduration;
|
||||
final Map<String, dynamic> extra;
|
||||
final String pathhash;
|
||||
final int id;
|
||||
final String type;
|
||||
final String image;
|
||||
final double score;
|
||||
final List<String> versions;
|
||||
final List<int> favUserids;
|
||||
final String weakHash;
|
||||
final bool isFavorite;
|
||||
|
||||
const AlbumModel({
|
||||
required this.albumartists,
|
||||
required this.albumhash,
|
||||
required this.artisthashes,
|
||||
required this.baseTitle,
|
||||
this.color = '#6750A4',
|
||||
required this.createdDate,
|
||||
required this.date,
|
||||
required this.duration,
|
||||
required this.genres,
|
||||
required this.genrehashes,
|
||||
this.originalTitle = '',
|
||||
required this.title,
|
||||
required this.trackcount,
|
||||
this.lastplayed = 0,
|
||||
this.playcount = 0,
|
||||
this.playduration = 0,
|
||||
this.extra = const {},
|
||||
this.pathhash = '',
|
||||
this.id = -1,
|
||||
this.type = 'album',
|
||||
this.image = '',
|
||||
this.score = 0.0,
|
||||
this.versions = const [],
|
||||
this.favUserids = const [],
|
||||
this.weakHash = '',
|
||||
this.isFavorite = false,
|
||||
});
|
||||
|
||||
AlbumModel copyWith({
|
||||
List<ArtistModel>? albumartists,
|
||||
String? albumhash,
|
||||
List<String>? artisthashes,
|
||||
String? baseTitle,
|
||||
String? color,
|
||||
int? createdDate,
|
||||
int? date,
|
||||
int? duration,
|
||||
List<GenreModel>? genres,
|
||||
List<String>? genrehashes,
|
||||
String? originalTitle,
|
||||
String? title,
|
||||
int? trackcount,
|
||||
int? lastplayed,
|
||||
int? playcount,
|
||||
int? playduration,
|
||||
Map<String, dynamic>? extra,
|
||||
String? pathhash,
|
||||
int? id,
|
||||
String? type,
|
||||
String? image,
|
||||
double? score,
|
||||
List<String>? versions,
|
||||
List<int>? favUserids,
|
||||
String? weakHash,
|
||||
bool? isFavorite,
|
||||
}) {
|
||||
return AlbumModel(
|
||||
albumartists: albumartists ?? this.albumartists,
|
||||
albumhash: albumhash ?? this.albumhash,
|
||||
artisthashes: artisthashes ?? this.artisthashes,
|
||||
baseTitle: baseTitle ?? this.baseTitle,
|
||||
color: color ?? this.color,
|
||||
createdDate: createdDate ?? this.createdDate,
|
||||
date: date ?? this.date,
|
||||
duration: duration ?? this.duration,
|
||||
genres: genres ?? this.genres,
|
||||
genrehashes: genrehashes ?? this.genrehashes,
|
||||
originalTitle: originalTitle ?? this.originalTitle,
|
||||
title: title ?? this.title,
|
||||
trackcount: trackcount ?? this.trackcount,
|
||||
lastplayed: lastplayed ?? this.lastplayed,
|
||||
playcount: playcount ?? this.playcount,
|
||||
playduration: playduration ?? this.playduration,
|
||||
extra: extra ?? this.extra,
|
||||
pathhash: pathhash ?? this.pathhash,
|
||||
id: id ?? this.id,
|
||||
type: type ?? this.type,
|
||||
image: image ?? this.image,
|
||||
score: score ?? this.score,
|
||||
versions: versions ?? this.versions,
|
||||
favUserids: favUserids ?? this.favUserids,
|
||||
weakHash: weakHash ?? this.weakHash,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
albumartists,
|
||||
albumhash,
|
||||
artisthashes,
|
||||
baseTitle,
|
||||
color,
|
||||
createdDate,
|
||||
date,
|
||||
duration,
|
||||
genres,
|
||||
genrehashes,
|
||||
originalTitle,
|
||||
title,
|
||||
trackcount,
|
||||
lastplayed,
|
||||
playcount,
|
||||
playduration,
|
||||
extra,
|
||||
pathhash,
|
||||
id,
|
||||
type,
|
||||
image,
|
||||
score,
|
||||
versions,
|
||||
favUserids,
|
||||
weakHash,
|
||||
isFavorite,
|
||||
];
|
||||
|
||||
String get displayTitle => originalTitle.isNotEmpty ? originalTitle : title;
|
||||
|
||||
String get artistNames => albumartists.map((artist) => artist.name).join(', ');
|
||||
|
||||
String get durationFormatted {
|
||||
final hours = duration ~/ 3600;
|
||||
final minutes = (duration % 3600) ~/ 60;
|
||||
final seconds = duration % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return '${hours}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
} else {
|
||||
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
}
|
||||
}
|
||||
|
||||
String get year {
|
||||
if (date == 0) return '';
|
||||
final dateTime = DateTime.fromMillisecondsSinceEpoch(date * 1000);
|
||||
return dateTime.year.toString();
|
||||
}
|
||||
|
||||
factory AlbumModel.fromJson(Map<String, dynamic> json) {
|
||||
return AlbumModel(
|
||||
albumartists: (json['albumartists'] as List<dynamic>?)
|
||||
?.map((artist) => ArtistModel.fromJson(artist))
|
||||
.toList() ?? [],
|
||||
albumhash: json['albumhash'] ?? '',
|
||||
artisthashes: List<String>.from(json['artisthashes'] ?? []),
|
||||
baseTitle: json['base_title'] ?? '',
|
||||
color: json['color'] ?? '#6750A4',
|
||||
createdDate: json['created_date'] ?? 0,
|
||||
date: json['date'] ?? 0,
|
||||
duration: json['duration'] ?? 0,
|
||||
genres: (json['genres'] as List<dynamic>?)
|
||||
?.map((genre) => GenreModel.fromJson(genre))
|
||||
.toList() ?? [],
|
||||
genrehashes: List<String>.from(json['genrehashes'] ?? []),
|
||||
originalTitle: json['original_title'] ?? '',
|
||||
title: json['title'] ?? '',
|
||||
trackcount: json['trackcount'] ?? 0,
|
||||
lastplayed: json['lastplayed'] ?? 0,
|
||||
playcount: json['playcount'] ?? 0,
|
||||
playduration: json['playduration'] ?? 0,
|
||||
extra: json['extra'] ?? {},
|
||||
pathhash: json['pathhash'] ?? '',
|
||||
id: json['id'] ?? -1,
|
||||
type: json['type'] ?? 'album',
|
||||
image: json['image'] ?? '',
|
||||
score: (json['score'] ?? 0).toDouble(),
|
||||
versions: List<String>.from(json['versions'] ?? []),
|
||||
favUserids: List<int>.from(json['fav_userids'] ?? []),
|
||||
weakHash: json['weak_hash'] ?? '',
|
||||
isFavorite: json['is_favorite'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'albumartists': albumartists.map((artist) => artist.toJson()).toList(),
|
||||
'albumhash': albumhash,
|
||||
'artisthashes': artisthashes,
|
||||
'base_title': baseTitle,
|
||||
'color': color,
|
||||
'created_date': createdDate,
|
||||
'date': date,
|
||||
'duration': duration,
|
||||
'genres': genres.map((genre) => genre.toJson()).toList(),
|
||||
'genrehashes': genrehashes,
|
||||
'original_title': originalTitle,
|
||||
'title': title,
|
||||
'trackcount': trackcount,
|
||||
'lastplayed': lastplayed,
|
||||
'playcount': playcount,
|
||||
'playduration': playduration,
|
||||
'extra': extra,
|
||||
'pathhash': pathhash,
|
||||
'id': id,
|
||||
'type': type,
|
||||
'image': image,
|
||||
'score': score,
|
||||
'versions': versions,
|
||||
'fav_userids': favUserids,
|
||||
'weak_hash': weakHash,
|
||||
'is_favorite': isFavorite,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'album_model.dart';
|
||||
import 'track_model.dart';
|
||||
|
||||
class ArtistModel extends Equatable {
|
||||
final String name;
|
||||
final String artisthash;
|
||||
final String image;
|
||||
final int trackcount;
|
||||
final int albumcount;
|
||||
final int duration;
|
||||
final int lastplayed;
|
||||
final int playcount;
|
||||
final int playduration;
|
||||
final List<int> favUserids;
|
||||
final bool isFavorite;
|
||||
final List<AlbumModel> albums;
|
||||
final List<TrackModel> tracks;
|
||||
|
||||
const ArtistModel({
|
||||
required this.name,
|
||||
required this.artisthash,
|
||||
this.image = '',
|
||||
this.trackcount = 0,
|
||||
this.albumcount = 0,
|
||||
this.duration = 0,
|
||||
this.lastplayed = 0,
|
||||
this.playcount = 0,
|
||||
this.playduration = 0,
|
||||
this.favUserids = const [],
|
||||
this.isFavorite = false,
|
||||
this.albums = const [],
|
||||
this.tracks = const [],
|
||||
});
|
||||
|
||||
ArtistModel copyWith({
|
||||
String? name,
|
||||
String? artisthash,
|
||||
String? image,
|
||||
int? trackcount,
|
||||
int? albumcount,
|
||||
int? duration,
|
||||
int? lastplayed,
|
||||
int? playcount,
|
||||
int? playduration,
|
||||
List<int>? favUserids,
|
||||
bool? isFavorite,
|
||||
List<AlbumModel>? albums,
|
||||
List<TrackModel>? tracks,
|
||||
}) {
|
||||
return ArtistModel(
|
||||
name: name ?? this.name,
|
||||
artisthash: artisthash ?? this.artisthash,
|
||||
image: image ?? this.image,
|
||||
trackcount: trackcount ?? this.trackcount,
|
||||
albumcount: albumcount ?? this.albumcount,
|
||||
duration: duration ?? this.duration,
|
||||
lastplayed: lastplayed ?? this.lastplayed,
|
||||
playcount: playcount ?? this.playcount,
|
||||
playduration: playduration ?? this.playduration,
|
||||
favUserids: favUserids ?? this.favUserids,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
albums: albums ?? this.albums,
|
||||
tracks: tracks ?? this.tracks,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
name,
|
||||
artisthash,
|
||||
image,
|
||||
trackcount,
|
||||
albumcount,
|
||||
duration,
|
||||
lastplayed,
|
||||
playcount,
|
||||
playduration,
|
||||
favUserids,
|
||||
isFavorite,
|
||||
albums,
|
||||
tracks,
|
||||
];
|
||||
|
||||
String get durationFormatted {
|
||||
final hours = duration ~/ 3600;
|
||||
final minutes = (duration % 3600) ~/ 60;
|
||||
final seconds = duration % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return '${hours}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
} else {
|
||||
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'track_model.dart';
|
||||
|
||||
class FolderModel extends Equatable {
|
||||
final String name;
|
||||
final String path;
|
||||
final String? parent;
|
||||
final int trackcount;
|
||||
final List<FolderModel> subfolders;
|
||||
final List<TrackModel> tracks;
|
||||
final String? image;
|
||||
final bool isFavorite;
|
||||
|
||||
const FolderModel({
|
||||
required this.name,
|
||||
required this.path,
|
||||
this.parent,
|
||||
this.trackcount = 0,
|
||||
this.subfolders = const [],
|
||||
this.tracks = const [],
|
||||
this.image,
|
||||
this.isFavorite = false,
|
||||
});
|
||||
|
||||
FolderModel copyWith({
|
||||
String? name,
|
||||
String? path,
|
||||
String? parent,
|
||||
int? trackcount,
|
||||
List<FolderModel>? subfolders,
|
||||
List<TrackModel>? tracks,
|
||||
String? image,
|
||||
bool? isFavorite,
|
||||
}) {
|
||||
return FolderModel(
|
||||
name: name ?? this.name,
|
||||
path: path ?? this.path,
|
||||
parent: parent ?? this.parent,
|
||||
trackcount: trackcount ?? this.trackcount,
|
||||
subfolders: subfolders ?? this.subfolders,
|
||||
tracks: tracks ?? this.tracks,
|
||||
image: image ?? this.image,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
);
|
||||
}
|
||||
|
||||
factory FolderModel.fromJson(Map<String, dynamic> json) {
|
||||
return FolderModel(
|
||||
name: json['name'] ?? '',
|
||||
path: json['path'] ?? '',
|
||||
parent: json['parent'],
|
||||
trackcount: json['trackcount'] ?? 0,
|
||||
subfolders: (json['subfolders'] as List<dynamic>?)
|
||||
?.map((folder) => FolderModel.fromJson(folder))
|
||||
.toList() ?? [],
|
||||
tracks: (json['tracks'] as List<dynamic>?)
|
||||
?.map((track) => TrackModel.fromJson(track))
|
||||
.toList() ?? [],
|
||||
image: json['image'],
|
||||
isFavorite: json['is_favorite'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'path': path,
|
||||
'parent': parent,
|
||||
'trackcount': trackcount,
|
||||
'subfolders': subfolders.map((folder) => folder.toJson()).toList(),
|
||||
'tracks': tracks.map((track) => track.toJson()).toList(),
|
||||
'image': image,
|
||||
'is_favorite': isFavorite,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
name,
|
||||
path,
|
||||
parent,
|
||||
trackcount,
|
||||
subfolders,
|
||||
tracks,
|
||||
image,
|
||||
isFavorite,
|
||||
];
|
||||
}
|
||||
|
||||
class FoldersAndTracksModel extends Equatable {
|
||||
final List<FolderModel> folders;
|
||||
final List<TrackModel> tracks;
|
||||
final String currentPath;
|
||||
|
||||
const FoldersAndTracksModel({
|
||||
required this.folders,
|
||||
required this.tracks,
|
||||
required this.currentPath,
|
||||
});
|
||||
|
||||
factory FoldersAndTracksModel.fromJson(Map<String, dynamic> json) {
|
||||
return FoldersAndTracksModel(
|
||||
folders: (json['folders'] as List<dynamic>?)
|
||||
?.map((folder) => FolderModel.fromJson(folder))
|
||||
.toList() ?? [],
|
||||
tracks: (json['tracks'] as List<dynamic>?)
|
||||
?.map((track) => TrackModel.fromJson(track))
|
||||
.toList() ?? [],
|
||||
currentPath: json['current_path'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'folders': folders.map((folder) => folder.toJson()).toList(),
|
||||
'tracks': tracks.map((track) => track.toJson()).toList(),
|
||||
'current_path': currentPath,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [folders, tracks, currentPath];
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'track_model.dart';
|
||||
|
||||
class PlaylistModel extends Equatable {
|
||||
final String id;
|
||||
final String name;
|
||||
final String description;
|
||||
final String image;
|
||||
final List<TrackModel> tracks;
|
||||
final int trackcount;
|
||||
final int duration;
|
||||
final DateTime createdDate;
|
||||
final DateTime lastModified;
|
||||
final bool isPublic;
|
||||
final bool isCollaborative;
|
||||
final String owner;
|
||||
final List<String> collaboratorIds;
|
||||
final Map<String, dynamic> extra;
|
||||
|
||||
const PlaylistModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.description = '',
|
||||
this.image = '',
|
||||
this.tracks = const [],
|
||||
this.trackcount = 0,
|
||||
this.duration = 0,
|
||||
required this.createdDate,
|
||||
required this.lastModified,
|
||||
this.isPublic = false,
|
||||
this.isCollaborative = false,
|
||||
this.owner = '',
|
||||
this.collaboratorIds = const [],
|
||||
this.extra = const {},
|
||||
});
|
||||
|
||||
PlaylistModel copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? description,
|
||||
String? image,
|
||||
List<TrackModel>? tracks,
|
||||
int? trackcount,
|
||||
int? duration,
|
||||
DateTime? createdDate,
|
||||
DateTime? lastModified,
|
||||
bool? isPublic,
|
||||
bool? isCollaborative,
|
||||
String? owner,
|
||||
List<String>? collaboratorIds,
|
||||
Map<String, dynamic>? extra,
|
||||
}) {
|
||||
return PlaylistModel(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
image: image ?? this.image,
|
||||
tracks: tracks ?? this.tracks,
|
||||
trackcount: trackcount ?? this.trackcount,
|
||||
duration: duration ?? this.duration,
|
||||
createdDate: createdDate ?? this.createdDate,
|
||||
lastModified: lastModified ?? this.lastModified,
|
||||
isPublic: isPublic ?? this.isPublic,
|
||||
isCollaborative: isCollaborative ?? this.isCollaborative,
|
||||
owner: owner ?? this.owner,
|
||||
collaboratorIds: collaboratorIds ?? this.collaboratorIds,
|
||||
extra: extra ?? this.extra,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
image,
|
||||
tracks,
|
||||
trackcount,
|
||||
duration,
|
||||
createdDate,
|
||||
lastModified,
|
||||
isPublic,
|
||||
isCollaborative,
|
||||
owner,
|
||||
collaboratorIds,
|
||||
extra,
|
||||
];
|
||||
|
||||
String get durationFormatted {
|
||||
final hours = duration ~/ 3600;
|
||||
final minutes = (duration % 3600) ~/ 60;
|
||||
final seconds = duration % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return '${hours}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
} else {
|
||||
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
}
|
||||
}
|
||||
|
||||
String get createdDateFormatted {
|
||||
return '${createdDate.day.toString().padLeft(2, '0')}/${createdDate.month.toString().padLeft(2, '0')}/${createdDate.year}';
|
||||
}
|
||||
|
||||
String get lastModifiedFormatted {
|
||||
return '${lastModified.day.toString().padLeft(2, '0')}/${lastModified.month.toString().padLeft(2, '0')}/${lastModified.year}';
|
||||
}
|
||||
|
||||
factory PlaylistModel.fromJson(Map<String, dynamic> json) {
|
||||
return PlaylistModel(
|
||||
id: json['id'] ?? '',
|
||||
name: json['name'] ?? '',
|
||||
description: json['description'] ?? '',
|
||||
image: json['image'] ?? '',
|
||||
tracks: (json['tracks'] as List<dynamic>?)
|
||||
?.map((track) => TrackModel.fromJson(track))
|
||||
.toList() ?? [],
|
||||
trackcount: json['trackcount'] ?? 0,
|
||||
duration: json['duration'] ?? 0,
|
||||
createdDate: json['created_date'] != null
|
||||
? DateTime.parse(json['created_date'])
|
||||
: DateTime.now(),
|
||||
lastModified: json['last_modified'] != null
|
||||
? DateTime.parse(json['last_modified'])
|
||||
: DateTime.now(),
|
||||
isPublic: json['is_public'] ?? false,
|
||||
isCollaborative: json['is_collaborative'] ?? false,
|
||||
owner: json['owner'] ?? '',
|
||||
collaboratorIds: List<String>.from(json['collaborator_ids'] ?? []),
|
||||
extra: json['extra'] ?? {},
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'image': image,
|
||||
'tracks': tracks.map((track) => track.toJson()).toList(),
|
||||
'trackcount': trackcount,
|
||||
'duration': duration,
|
||||
'created_date': createdDate.toIso8601String(),
|
||||
'last_modified': lastModified.toIso8601String(),
|
||||
'is_public': isPublic,
|
||||
'is_collaborative': isCollaborative,
|
||||
'owner': owner,
|
||||
'collaborator_ids': collaboratorIds,
|
||||
'extra': extra,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'album_model.dart';
|
||||
import 'folder_model.dart';
|
||||
import 'playlist_model.dart';
|
||||
import 'track_model.dart';
|
||||
|
||||
class SearchResultsModel extends Equatable {
|
||||
final List<TrackModel> tracks;
|
||||
final List<AlbumModel> albums;
|
||||
final List<ArtistModel> artists;
|
||||
final List<FolderModel> folders;
|
||||
final List<PlaylistModel> playlists;
|
||||
|
||||
const SearchResultsModel({
|
||||
this.tracks = const [],
|
||||
this.albums = const [],
|
||||
this.artists = const [],
|
||||
this.folders = const [],
|
||||
this.playlists = const [],
|
||||
});
|
||||
|
||||
SearchResultsModel copyWith({
|
||||
List<TrackModel>? tracks,
|
||||
List<AlbumModel>? albums,
|
||||
List<ArtistModel>? artists,
|
||||
List<FolderModel>? folders,
|
||||
List<PlaylistModel>? playlists,
|
||||
}) {
|
||||
return SearchResultsModel(
|
||||
tracks: tracks ?? this.tracks,
|
||||
albums: albums ?? this.albums,
|
||||
artists: artists ?? this.artists,
|
||||
folders: folders ?? this.folders,
|
||||
playlists: playlists ?? this.playlists,
|
||||
);
|
||||
}
|
||||
|
||||
factory SearchResultsModel.fromJson(Map<String, dynamic> json) {
|
||||
return SearchResultsModel(
|
||||
tracks: (json['tracks'] as List<dynamic>?)
|
||||
?.map((track) => TrackModel.fromJson(track))
|
||||
.toList() ?? [],
|
||||
albums: (json['albums'] as List<dynamic>?)
|
||||
?.map((album) => AlbumModel.fromJson(album))
|
||||
.toList() ?? [],
|
||||
artists: (json['artists'] as List<dynamic>?)
|
||||
?.map((artist) => ArtistModel.fromJson(artist))
|
||||
.toList() ?? [],
|
||||
folders: (json['folders'] as List<dynamic>?)
|
||||
?.map((folder) => FolderModel.fromJson(folder))
|
||||
.toList() ?? [],
|
||||
playlists: (json['playlists'] as List<dynamic>?)
|
||||
?.map((playlist) => PlaylistModel.fromJson(playlist))
|
||||
.toList() ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'tracks': tracks.map((track) => track.toJson()).toList(),
|
||||
'albums': albums.map((album) => album.toJson()).toList(),
|
||||
'artists': artists.map((artist) => artist.toJson()).toList(),
|
||||
'folders': folders.map((folder) => folder.toJson()).toList(),
|
||||
'playlists': playlists.map((playlist) => playlist.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
||||
bool get isEmpty =>
|
||||
tracks.isEmpty &&
|
||||
albums.isEmpty &&
|
||||
artists.isEmpty &&
|
||||
folders.isEmpty &&
|
||||
playlists.isEmpty;
|
||||
|
||||
bool get isNotEmpty => !isEmpty;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
tracks,
|
||||
albums,
|
||||
artists,
|
||||
folders,
|
||||
playlists,
|
||||
];
|
||||
}
|
||||
|
||||
class TopSearchResultsModel extends Equatable {
|
||||
final List<TopResultItemModel> topResults;
|
||||
final SearchResultsModel allResults;
|
||||
|
||||
const TopSearchResultsModel({
|
||||
required this.topResults,
|
||||
required this.allResults,
|
||||
});
|
||||
|
||||
factory TopSearchResultsModel.fromJson(Map<String, dynamic> json) {
|
||||
return TopSearchResultsModel(
|
||||
topResults: (json['top_results'] as List<dynamic>?)
|
||||
?.map((item) => TopResultItemModel.fromJson(item))
|
||||
.toList() ?? [],
|
||||
allResults: SearchResultsModel.fromJson(json['all_results'] ?? {}),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'top_results': topResults.map((item) => item.toJson()).toList(),
|
||||
'all_results': allResults.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [topResults, allResults];
|
||||
}
|
||||
|
||||
class TopResultItemModel extends Equatable {
|
||||
final String type; // 'track', 'album', 'artist', 'folder', 'playlist'
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final String? image;
|
||||
final dynamic data; // The actual model object
|
||||
|
||||
const TopResultItemModel({
|
||||
required this.type,
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
this.image,
|
||||
this.data,
|
||||
});
|
||||
|
||||
factory TopResultItemModel.fromJson(Map<String, dynamic> json) {
|
||||
return TopResultItemModel(
|
||||
type: json['type'] ?? '',
|
||||
title: json['title'] ?? '',
|
||||
subtitle: json['subtitle'] ?? '',
|
||||
image: json['image'],
|
||||
data: json['data'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'type': type,
|
||||
'title': title,
|
||||
'subtitle': subtitle,
|
||||
'image': image,
|
||||
'data': data,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [type, title, subtitle, image, data];
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
class SearchSuggestion {
|
||||
final String id;
|
||||
final String title;
|
||||
final String? imageUrl;
|
||||
final String type; // 'track', 'album', 'artist', 'playlist'
|
||||
final dynamic data;
|
||||
|
||||
SearchSuggestion({
|
||||
required this.id,
|
||||
required this.title,
|
||||
this.imageUrl,
|
||||
required this.type,
|
||||
this.data,
|
||||
});
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class TrackModel extends Equatable {
|
||||
final int id;
|
||||
final String title;
|
||||
final String album;
|
||||
final String originalTitle;
|
||||
final String albumhash;
|
||||
final String originalAlbum;
|
||||
final List<ArtistModel> artists;
|
||||
final List<ArtistModel> albumartists;
|
||||
final List<String> artisthashes;
|
||||
final int track;
|
||||
final int disc;
|
||||
final int duration;
|
||||
final int bitrate;
|
||||
final String filepath;
|
||||
final String folder;
|
||||
final List<GenreModel> genres;
|
||||
final List<String> genrehashes;
|
||||
final String copyright;
|
||||
final int date;
|
||||
final int lastModified;
|
||||
final String trackhash;
|
||||
final String image;
|
||||
final String weakHash;
|
||||
final Map<String, dynamic> extra;
|
||||
final int lastplayed;
|
||||
final int playcount;
|
||||
final int playduration;
|
||||
final bool explicit;
|
||||
final List<int> favUserids;
|
||||
final bool isFavorite;
|
||||
final double score;
|
||||
|
||||
const TrackModel({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.album,
|
||||
this.originalTitle = '',
|
||||
required this.albumhash,
|
||||
this.originalAlbum = '',
|
||||
required this.artists,
|
||||
required this.albumartists,
|
||||
required this.artisthashes,
|
||||
required this.track,
|
||||
required this.disc,
|
||||
required this.duration,
|
||||
required this.bitrate,
|
||||
required this.filepath,
|
||||
required this.folder,
|
||||
required this.genres,
|
||||
required this.genrehashes,
|
||||
this.copyright = '',
|
||||
required this.date,
|
||||
required this.lastModified,
|
||||
required this.trackhash,
|
||||
this.image = '',
|
||||
this.weakHash = '',
|
||||
required this.extra,
|
||||
this.lastplayed = 0,
|
||||
this.playcount = 0,
|
||||
this.playduration = 0,
|
||||
this.explicit = false,
|
||||
this.favUserids = const [],
|
||||
this.isFavorite = false,
|
||||
this.score = 0.0,
|
||||
});
|
||||
|
||||
TrackModel copyWith({
|
||||
int? id,
|
||||
String? title,
|
||||
String? album,
|
||||
String? originalTitle,
|
||||
String? albumhash,
|
||||
String? originalAlbum,
|
||||
List<ArtistModel>? artists,
|
||||
List<ArtistModel>? albumartists,
|
||||
List<String>? artisthashes,
|
||||
int? track,
|
||||
int? disc,
|
||||
int? duration,
|
||||
int? bitrate,
|
||||
String? filepath,
|
||||
String? folder,
|
||||
List<GenreModel>? genres,
|
||||
List<String>? genrehashes,
|
||||
String? copyright,
|
||||
int? date,
|
||||
int? lastModified,
|
||||
String? trackhash,
|
||||
String? image,
|
||||
String? weakHash,
|
||||
Map<String, dynamic>? extra,
|
||||
int? lastplayed,
|
||||
int? playcount,
|
||||
int? playduration,
|
||||
bool? explicit,
|
||||
List<int>? favUserids,
|
||||
bool? isFavorite,
|
||||
double? score,
|
||||
}) {
|
||||
return TrackModel(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
album: album ?? this.album,
|
||||
originalTitle: originalTitle ?? this.originalTitle,
|
||||
albumhash: albumhash ?? this.albumhash,
|
||||
originalAlbum: originalAlbum ?? this.originalAlbum,
|
||||
artists: artists ?? this.artists,
|
||||
albumartists: albumartists ?? this.albumartists,
|
||||
artisthashes: artisthashes ?? this.artisthashes,
|
||||
track: track ?? this.track,
|
||||
disc: disc ?? this.disc,
|
||||
duration: duration ?? this.duration,
|
||||
bitrate: bitrate ?? this.bitrate,
|
||||
filepath: filepath ?? this.filepath,
|
||||
folder: folder ?? this.folder,
|
||||
genres: genres ?? this.genres,
|
||||
genrehashes: genrehashes ?? this.genrehashes,
|
||||
copyright: copyright ?? this.copyright,
|
||||
date: date ?? this.date,
|
||||
lastModified: lastModified ?? this.lastModified,
|
||||
trackhash: trackhash ?? this.trackhash,
|
||||
image: image ?? this.image,
|
||||
weakHash: weakHash ?? this.weakHash,
|
||||
extra: extra ?? this.extra,
|
||||
lastplayed: lastplayed ?? this.lastplayed,
|
||||
playcount: playcount ?? this.playcount,
|
||||
playduration: playduration ?? this.playduration,
|
||||
explicit: explicit ?? this.explicit,
|
||||
favUserids: favUserids ?? this.favUserids,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
score: score ?? this.score,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
title,
|
||||
album,
|
||||
originalTitle,
|
||||
albumhash,
|
||||
originalAlbum,
|
||||
artists,
|
||||
albumartists,
|
||||
artisthashes,
|
||||
track,
|
||||
disc,
|
||||
duration,
|
||||
bitrate,
|
||||
filepath,
|
||||
folder,
|
||||
genres,
|
||||
genrehashes,
|
||||
copyright,
|
||||
date,
|
||||
lastModified,
|
||||
trackhash,
|
||||
image,
|
||||
weakHash,
|
||||
extra,
|
||||
lastplayed,
|
||||
playcount,
|
||||
playduration,
|
||||
explicit,
|
||||
favUserids,
|
||||
isFavorite,
|
||||
score,
|
||||
];
|
||||
|
||||
String get displayTitle => originalTitle.isNotEmpty ? originalTitle : title;
|
||||
|
||||
String get displayAlbum => originalAlbum.isNotEmpty ? originalAlbum : album;
|
||||
|
||||
String get artistNames => artists.map((artist) => artist.name).join(', ');
|
||||
|
||||
String get durationFormatted {
|
||||
final minutes = duration ~/ 60;
|
||||
final seconds = duration % 60;
|
||||
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
factory TrackModel.fromJson(Map<String, dynamic> json) {
|
||||
return TrackModel(
|
||||
id: json['id'] ?? 0,
|
||||
title: json['title'] ?? '',
|
||||
album: json['album'] ?? '',
|
||||
originalTitle: json['original_title'] ?? '',
|
||||
albumhash: json['albumhash'] ?? '',
|
||||
originalAlbum: json['original_album'] ?? '',
|
||||
artists: (json['artists'] as List<dynamic>?)
|
||||
?.map((artist) => ArtistModel.fromJson(artist))
|
||||
.toList() ?? [],
|
||||
albumartists: (json['albumartists'] as List<dynamic>?)
|
||||
?.map((artist) => ArtistModel.fromJson(artist))
|
||||
.toList() ?? [],
|
||||
artisthashes: List<String>.from(json['artisthashes'] ?? []),
|
||||
track: json['track'] ?? 0,
|
||||
disc: json['disc'] ?? 1,
|
||||
duration: json['duration'] ?? 0,
|
||||
bitrate: json['bitrate'] ?? 0,
|
||||
filepath: json['filepath'] ?? '',
|
||||
folder: json['folder'] ?? '',
|
||||
genres: (json['genres'] as List<dynamic>?)
|
||||
?.map((genre) => GenreModel.fromJson(genre))
|
||||
.toList() ?? [],
|
||||
genrehashes: List<String>.from(json['genrehashes'] ?? []),
|
||||
copyright: json['copyright'] ?? '',
|
||||
date: json['date'] ?? 0,
|
||||
lastModified: json['last_modified'] ?? 0,
|
||||
trackhash: json['trackhash'] ?? '',
|
||||
image: json['image'] ?? '',
|
||||
weakHash: json['weak_hash'] ?? '',
|
||||
extra: json['extra'] ?? {},
|
||||
lastplayed: json['lastplayed'] ?? 0,
|
||||
playcount: json['playcount'] ?? 0,
|
||||
playduration: json['playduration'] ?? 0,
|
||||
explicit: json['explicit'] ?? false,
|
||||
favUserids: List<int>.from(json['fav_userids'] ?? []),
|
||||
isFavorite: json['is_favorite'] ?? false,
|
||||
score: (json['score'] ?? 0).toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'album': album,
|
||||
'original_title': originalTitle,
|
||||
'albumhash': albumhash,
|
||||
'original_album': originalAlbum,
|
||||
'artists': artists.map((artist) => artist.toJson()).toList(),
|
||||
'albumartists': albumartists.map((artist) => artist.toJson()).toList(),
|
||||
'artisthashes': artisthashes,
|
||||
'track': track,
|
||||
'disc': disc,
|
||||
'duration': duration,
|
||||
'bitrate': bitrate,
|
||||
'filepath': filepath,
|
||||
'folder': folder,
|
||||
'genres': genres.map((genre) => genre.toJson()).toList(),
|
||||
'genrehashes': genrehashes,
|
||||
'copyright': copyright,
|
||||
'date': date,
|
||||
'last_modified': lastModified,
|
||||
'trackhash': trackhash,
|
||||
'image': image,
|
||||
'weak_hash': weakHash,
|
||||
'extra': extra,
|
||||
'lastplayed': lastplayed,
|
||||
'playcount': playcount,
|
||||
'playduration': playduration,
|
||||
'explicit': explicit,
|
||||
'fav_userids': favUserids,
|
||||
'is_favorite': isFavorite,
|
||||
'score': score,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ArtistModel extends Equatable {
|
||||
final String name;
|
||||
final String artisthash;
|
||||
|
||||
const ArtistModel({
|
||||
required this.name,
|
||||
required this.artisthash,
|
||||
});
|
||||
|
||||
factory ArtistModel.fromJson(Map<String, dynamic> json) {
|
||||
return ArtistModel(
|
||||
name: json['name'] ?? '',
|
||||
artisthash: json['artisthash'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'artisthash': artisthash,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [name, artisthash];
|
||||
}
|
||||
|
||||
class GenreModel extends Equatable {
|
||||
final String name;
|
||||
final String genrehash;
|
||||
|
||||
const GenreModel({
|
||||
required this.name,
|
||||
required this.genrehash,
|
||||
});
|
||||
|
||||
factory GenreModel.fromJson(Map<String, dynamic> json) {
|
||||
return GenreModel(
|
||||
name: json['name'] ?? '',
|
||||
genrehash: json['genrehash'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'genrehash': genrehash,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [name, genrehash];
|
||||
}
|
||||
Reference in New Issue
Block a user