0.6.6 - standalone track naming, artist separator
This commit is contained in:
parent
ef9ae6e2ad
commit
babd12bae2
20 changed files with 271 additions and 150 deletions
|
@ -82,6 +82,10 @@ class Cache {
|
|||
return p.join((await getApplicationDocumentsDirectory()).path, 'metacache.json');
|
||||
}
|
||||
|
||||
static Future wipe() async {
|
||||
await File(await getPath()).delete();
|
||||
}
|
||||
|
||||
static Future<Cache> load() async {
|
||||
File file = File(await Cache.getPath());
|
||||
//Doesn't exist, create new
|
||||
|
|
|
@ -156,9 +156,9 @@ class Track {
|
|||
'trackNumber': trackNumber,
|
||||
'offline': off?1:0,
|
||||
'lyrics': jsonEncode(lyrics.toJson()),
|
||||
'favorite': (favorite??0)?1:0,
|
||||
'favorite': (favorite??false) ? 1 : 0,
|
||||
'diskNumber': diskNumber,
|
||||
'explicit': explicit?1:0,
|
||||
'explicit': (explicit??false) ? 1 : 0,
|
||||
//'favoriteDate': favoriteDate
|
||||
};
|
||||
factory Track.fromSQL(Map<String, dynamic> data) => Track(
|
||||
|
@ -232,9 +232,9 @@ class Album {
|
|||
Map<String, dynamic> toSQL({off = false}) => {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'artists': artists.map<String>((dynamic a) => a.id).join(','),
|
||||
'tracks': tracks.map<String>((dynamic t) => t.id).join(','),
|
||||
'art': art.full,
|
||||
'artists': (artists??[]).map<String>((dynamic a) => a.id).join(','),
|
||||
'tracks': (tracks??[]).map<String>((dynamic t) => t.id).join(','),
|
||||
'art': art?.full??'',
|
||||
'fans': fans,
|
||||
'offline': off?1:0,
|
||||
'library': (library??false)?1:0,
|
||||
|
@ -255,7 +255,7 @@ class Album {
|
|||
fans: data['fans'],
|
||||
offline: (data['offline'] == 1) ? true:false,
|
||||
library: (data['library'] == 1) ? true:false,
|
||||
type: AlbumType.values[data['type']],
|
||||
type: AlbumType.values[(data['type'] == -1) ? 0 : data['type']],
|
||||
releaseDate: data['releaseDate'],
|
||||
//favoriteDate: data['favoriteDate']
|
||||
);
|
||||
|
@ -619,6 +619,9 @@ class HomePage {
|
|||
Map data = jsonDecode(await File(path).readAsString());
|
||||
return HomePage.fromJson(data);
|
||||
}
|
||||
Future wipe() async {
|
||||
await File(await _getPath()).delete();
|
||||
}
|
||||
|
||||
//JSON
|
||||
factory HomePage.fromPrivateJson(Map<dynamic, dynamic> json) {
|
||||
|
|
|
@ -157,7 +157,7 @@ class DownloadManager {
|
|||
return quality;
|
||||
}
|
||||
|
||||
Future<bool> addOfflineTrack(Track track, {private = true, BuildContext context}) async {
|
||||
Future<bool> addOfflineTrack(Track track, {private = true, BuildContext context, isSingleton = false}) async {
|
||||
//Permission
|
||||
if (!private && !(await checkPermission())) return false;
|
||||
|
||||
|
@ -168,6 +168,10 @@ class DownloadManager {
|
|||
if (quality == null) return false;
|
||||
}
|
||||
|
||||
//Fetch track if missing meta
|
||||
if (track.artists == null || track.artists.length == 0 || track.album == null)
|
||||
track = await deezerAPI.track(track.id);
|
||||
|
||||
//Add to DB
|
||||
if (private) {
|
||||
Batch b = db.batch();
|
||||
|
@ -180,9 +184,10 @@ class DownloadManager {
|
|||
}
|
||||
|
||||
//Get path
|
||||
String path = _generatePath(track, private);
|
||||
String path = _generatePath(track, private, isSingleton: isSingleton);
|
||||
await platform.invokeMethod('addDownloads', [await Download.jsonFromTrack(track, path, private: private, quality: quality)]);
|
||||
await start();
|
||||
return true;
|
||||
}
|
||||
|
||||
Future addOfflineAlbum(Album album, {private = true, BuildContext context}) async {
|
||||
|
@ -478,7 +483,7 @@ class DownloadManager {
|
|||
}
|
||||
|
||||
//Generate track download path
|
||||
String _generatePath(Track track, bool private, {String playlistName, int playlistTrackNumber}) {
|
||||
String _generatePath(Track track, bool private, {String playlistName, int playlistTrackNumber, bool isSingleton = false}) {
|
||||
String path;
|
||||
if (private) {
|
||||
path = p.join(offlinePath, track.id);
|
||||
|
@ -501,7 +506,7 @@ class DownloadManager {
|
|||
}
|
||||
}
|
||||
//Final path
|
||||
path = p.join(path, settings.downloadFilename);
|
||||
path = p.join(path, isSingleton ? settings.singletonFilename : settings.downloadFilename);
|
||||
//Playlist track number variable (not accessible in service)
|
||||
if (playlistTrackNumber != null) {
|
||||
path = path.replaceAll('%playlistTrackNumber%', playlistTrackNumber.toString());
|
||||
|
|
|
@ -31,6 +31,20 @@ class SpotifyAPI {
|
|||
//Get spotify embed url from uri
|
||||
String getEmbedUrl(String uri) => 'https://embed.spotify.com/?uri=$uri';
|
||||
|
||||
//https://link.tospotify.com/ or https://spotify.app.link/
|
||||
Future resolveLinkUrl(String url) async {
|
||||
http.Response response = await http.get(Uri.parse(url));
|
||||
Match match = RegExp(r'window\.top\.location = validate\("(.+)"\);').firstMatch(response.body);
|
||||
return match.group(1);
|
||||
}
|
||||
|
||||
Future resolveUrl(String url) async {
|
||||
if (url.contains("link.tospotify") || url.contains("spotify.app.link")) {
|
||||
return parseUrl(await resolveLinkUrl(url));
|
||||
}
|
||||
return parseUrl(url);
|
||||
}
|
||||
|
||||
//Extract JSON data form spotify embed page
|
||||
Future<Map> getEmbedData(String url) async {
|
||||
//Fetch
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue