0.6.8 - bug fixes

This commit is contained in:
exttex 2020-12-27 19:33:59 +01:00
parent c3a26b0e3b
commit ff239aaf86
13 changed files with 534 additions and 402 deletions

View File

@ -247,17 +247,28 @@ public class Deezer {
return original + ".mp3"; return original + ".mp3";
} }
public static String generateUserUploadedMP3Filename(String original, JSONObject privateJson) throws Exception { // public static String generateUserUploadedMP3Filename(String original, JSONObject privateJson) throws Exception {
//Remove unavailable tags // //Remove unavailable tags
String[] ignored = {"%feats%", "%trackNumber%", "%0trackNumber%", "%year%", "%date%"}; // String[] ignored = {"%feats%", "%trackNumber%", "%0trackNumber%", "%year%", "%date%"};
// for (String i : ignored) {
// original = original.replaceAll(i, "");
// }
// //Basic tags
// original = original.replaceAll("%title%", privateJson.getString("SNG_TITLE"));
// original = original.replaceAll("%album%", privateJson.getString("ALB_TITLE"));
// original = original.replaceAll("%artist%", privateJson.getString("ART_NAME"));
// original = original.replaceAll("%artists%", privateJson.getString("ART_NAME"));
// return original;
// }
//Deezer patched something so getting metadata of user uploaded MP3s is not working anymore
public static String generateUserUploadedMP3Filename(String original, String title) throws Exception {
String[] ignored = {"%feats%", "%trackNumber%", "%0trackNumber%", "%year%", "%date%", "%album%", "%artist%", "%artists%"};
for (String i : ignored) { for (String i : ignored) {
original = original.replaceAll(i, ""); original = original.replaceAll(i, "");
} }
//Basic tags
original = original.replaceAll("%title%", privateJson.getString("SNG_TITLE")); original = original.replace("%title%", sanitize(title));
original = original.replaceAll("%album%", privateJson.getString("ALB_TITLE"));
original = original.replaceAll("%artist%", privateJson.getString("ART_NAME"));
original = original.replaceAll("%artists%", privateJson.getString("ART_NAME"));
return original; return original;
} }

View File

@ -96,10 +96,8 @@ public class DownloadService extends Service {
public void onDestroy() { public void onDestroy() {
//Cancel notifications //Cancel notifications
notificationManager.cancelAll(); notificationManager.cancelAll();
//Logger //Logger
logger.close(); logger.close();
super.onDestroy(); super.onDestroy();
} }
@ -116,8 +114,10 @@ public class DownloadService extends Service {
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
//Get messenger //Get messenger
if (intent != null) if (intent != null) {
activityMessenger = intent.getParcelableExtra("activityMessenger"); activityMessenger = intent.getParcelableExtra("activityMessenger");
}
//return super.onStartCommand(intent, flags, startId); //return super.onStartCommand(intent, flags, startId);
//Prevent battery savers I guess //Prevent battery savers I guess
@ -295,18 +295,17 @@ public class DownloadService extends Service {
while (deezer.authorizing) while (deezer.authorizing)
try {Thread.sleep(50);} catch (Exception ignored) {} try {Thread.sleep(50);} catch (Exception ignored) {}
//Fetch metadata //Don't fetch meta if user uploaded mp3
if (!download.isUserUploaded()) {
try { try {
JSONObject privateRaw = deezer.callGWAPI("deezer.pageTrack", "{\"sng_id\": \"" + download.trackId + "\"}"); JSONObject privateRaw = deezer.callGWAPI("deezer.pageTrack", "{\"sng_id\": \"" + download.trackId + "\"}");
privateJson = privateRaw.getJSONObject("results").getJSONObject("DATA"); privateJson = privateRaw.getJSONObject("results").getJSONObject("DATA");
if (privateRaw.getJSONObject("results").has("LYRICS")) { if (privateRaw.getJSONObject("results").has("LYRICS")) {
lyricsData = privateRaw.getJSONObject("results").getJSONObject("LYRICS"); lyricsData = privateRaw.getJSONObject("results").getJSONObject("LYRICS");
} }
//Don't fetch meta if user uploaded mp3
if (!download.isUserUploaded()) {
trackJson = Deezer.callPublicAPI("track", download.trackId); trackJson = Deezer.callPublicAPI("track", download.trackId);
albumJson = Deezer.callPublicAPI("album", Integer.toString(trackJson.getJSONObject("album").getInt("id"))); albumJson = Deezer.callPublicAPI("album", Integer.toString(trackJson.getJSONObject("album").getInt("id")));
}
} catch (Exception e) { } catch (Exception e) {
logger.error("Unable to fetch track and album metadata! " + e.toString(), download); logger.error("Unable to fetch track and album metadata! " + e.toString(), download);
e.printStackTrace(); e.printStackTrace();
@ -314,6 +313,7 @@ public class DownloadService extends Service {
exit(); exit();
return; return;
} }
}
//Fallback //Fallback
Deezer.QualityInfo qualityInfo = new Deezer.QualityInfo(this.download.quality, this.download.trackId, this.download.md5origin, this.download.mediaVersion, logger); Deezer.QualityInfo qualityInfo = new Deezer.QualityInfo(this.download.quality, this.download.trackId, this.download.md5origin, this.download.mediaVersion, logger);
@ -339,7 +339,7 @@ public class DownloadService extends Service {
//Check file //Check file
try { try {
if (download.isUserUploaded()) { if (download.isUserUploaded()) {
outFile = new File(Deezer.generateUserUploadedMP3Filename(download.path, privateJson)); outFile = new File(Deezer.generateUserUploadedMP3Filename(download.path, download.title));
} else { } else {
outFile = new File(Deezer.generateFilename(download.path, trackJson, albumJson, qualityInfo.quality)); outFile = new File(Deezer.generateFilename(download.path, trackJson, albumJson, qualityInfo.quality));
} }
@ -700,6 +700,8 @@ public class DownloadService extends Service {
//Start/Resume //Start/Resume
case SERVICE_START_DOWNLOAD: case SERVICE_START_DOWNLOAD:
running = true; running = true;
if (downloads.size() == 0)
loadDownloads();
updateQueue(); updateQueue();
updateState(); updateState();
break; break;

View File

@ -144,8 +144,9 @@ public class MainActivity extends FlutterActivity {
} }
//Start/Resume downloading //Start/Resume downloading
if (call.method.equals("start")) { if (call.method.equals("start")) {
//Connected
sendMessage(DownloadService.SERVICE_START_DOWNLOAD, null); sendMessage(DownloadService.SERVICE_START_DOWNLOAD, null);
result.success(null); result.success(serviceBound);
return; return;
} }
//Stop downloading //Stop downloading
@ -239,17 +240,24 @@ public class MainActivity extends FlutterActivity {
})); }));
} }
//Start/Bind/Reconnect to download service
private void connectService() {
if (serviceBound)
return;
//Create messenger
activityMessenger = new Messenger(new IncomingHandler(this));
//Start
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("activityMessenger", activityMessenger);
startService(intent);
bindService(intent, connection, BIND_AUTO_CREATE);
}
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
//Bind downloader service connectService();
activityMessenger = new Messenger(new IncomingHandler(this));
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("activityMessenger", activityMessenger);
startService(intent);
bindService(intent, connection, 0);
//Get DB //Get DB
DownloadsDatabase dbHelper = new DownloadsDatabase(getApplicationContext()); DownloadsDatabase dbHelper = new DownloadsDatabase(getApplicationContext());
db = dbHelper.getWritableDatabase(); db = dbHelper.getWritableDatabase();
@ -274,17 +282,18 @@ public class MainActivity extends FlutterActivity {
} catch (NoSuchAlgorithmException | KeyManagementException e) { } catch (NoSuchAlgorithmException | KeyManagementException e) {
Log.e(this.getLocalClassName(), e.getMessage()); Log.e(this.getLocalClassName(), e.getMessage());
} }
}
@Override
protected void onResume() {
super.onResume();
//Try reconnect
connectService();
} }
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
//Unbind service on exit
if (serviceBound) {
unbindService(connection);
serviceBound = false;
}
db.close(); db.close();
} }
@ -294,6 +303,12 @@ public class MainActivity extends FlutterActivity {
//Stop server //Stop server
if (streamServer != null) if (streamServer != null)
streamServer.stop(); streamServer.stop();
//Unbind service on exit
if (serviceBound) {
unbindService(connection);
serviceBound = false;
}
} }
//Connection to download service //Connection to download service
@ -302,12 +317,14 @@ public class MainActivity extends FlutterActivity {
public void onServiceConnected(ComponentName componentName, IBinder iBinder) { public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
serviceMessenger = new Messenger(iBinder); serviceMessenger = new Messenger(iBinder);
serviceBound = true; serviceBound = true;
Log.d("DD", "Service Bound!");
} }
@Override @Override
public void onServiceDisconnected(ComponentName componentName) { public void onServiceDisconnected(ComponentName componentName) {
serviceMessenger = null; serviceMessenger = null;
serviceBound = false; serviceBound = false;
Log.d("DD", "Service UnBound!");
} }
}; };

View File

@ -36,6 +36,7 @@ class DownloadManager {
//Start/Resume downloads //Start/Resume downloads
Future start() async { Future start() async {
//Returns whether service is bound or not, the delay is really shitty/hacky way, until i find a real solution
await updateServiceSettings(); await updateServiceSettings();
await platform.invokeMethod('start'); await platform.invokeMethod('start');
} }

View File

@ -319,6 +319,8 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Queue //Queue
List<MediaItem> _queue = <MediaItem>[]; List<MediaItem> _queue = <MediaItem>[];
List<MediaItem> _originalQueue;
bool _shuffle = false;
int _queueIndex = 0; int _queueIndex = 0;
ConcatenatingAudioSource _audioSource; ConcatenatingAudioSource _audioSource;
@ -471,6 +473,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Update buffering state //Update buffering state
_skipState = AudioProcessingState.skippingToPrevious; _skipState = AudioProcessingState.skippingToPrevious;
//Normal skip to previous //Normal skip to previous
_queueIndex--; _queueIndex--;
await _player.seekToPrevious(); await _player.seekToPrevious();
@ -542,7 +545,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
if (_skipState != null) return _skipState; if (_skipState != null) return _skipState;
//SRC: audio_service example //SRC: audio_service example
switch (_player.processingState) { switch (_player.processingState) {
case ProcessingState.none: case ProcessingState.idle:
return AudioProcessingState.stopped; return AudioProcessingState.stopped;
case ProcessingState.loading: case ProcessingState.loading:
return AudioProcessingState.connecting; return AudioProcessingState.connecting;
@ -586,8 +589,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
_audioSource = ConcatenatingAudioSource(children: sources); _audioSource = ConcatenatingAudioSource(children: sources);
//Load in just_audio //Load in just_audio
try { try {
await _player.load(_audioSource, initialPosition: Duration.zero, initialIndex: qi); await _player.setAudioSource(_audioSource, initialIndex: qi, initialPosition: Duration.zero);
// await _player.seek(Duration.zero, index: qi);
} catch (e) { } catch (e) {
//Error loading tracks //Error loading tracks
} }
@ -599,7 +601,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
String url = await _getTrackUrl(mi); String url = await _getTrackUrl(mi);
if (url == null) return null; if (url == null) return null;
if (url.startsWith('http')) return ProgressiveAudioSource(Uri.parse(url)); if (url.startsWith('http')) return ProgressiveAudioSource(Uri.parse(url));
return AudioSource.uri(Uri.parse(url)); return AudioSource.uri(Uri.parse(url), tag: mi.id);
} }
Future _getTrackUrl(MediaItem mediaItem, {int quality}) async { Future _getTrackUrl(MediaItem mediaItem, {int quality}) async {
@ -655,10 +657,26 @@ class AudioPlayerTask extends BackgroundAudioTask {
await this._loadQueueFile(); await this._loadQueueFile();
//Shuffle //Shuffle
if (name == 'shuffle') { if (name == 'shuffle') {
String originalId = mediaItem.id;
if (!_shuffle) {
_shuffle = true;
_originalQueue = List.from(_queue);
_queue.shuffle(); _queue.shuffle();
AudioServiceBackground.setQueue(_queue);
} else {
_shuffle = false;
_queue = _originalQueue;
_originalQueue = null;
}
//Broken
// _queueIndex = _queue.indexWhere((mi) => mi.id == originalId);
_queueIndex = 0; _queueIndex = 0;
AudioServiceBackground.setQueue(_queue);
AudioServiceBackground.setMediaItem(mediaItem);
await _player.stop();
await _loadQueue(); await _loadQueue();
await _player.play();
} }
//Android auto callback //Android auto callback
if (name == 'screenAndroidAuto' && _androidAutoCallback != null) { if (name == 'screenAndroidAuto' && _androidAutoCallback != null) {

File diff suppressed because one or more lines are too long

View File

@ -307,6 +307,11 @@ const language_en_us = {
"Episodes": "Episodes", "Episodes": "Episodes",
"Show all episodes": "Show all episodes", "Show all episodes": "Show all episodes",
"Album cover resolution": "Album cover resolution", "Album cover resolution": "Album cover resolution",
"WARNING: Resolutions above 1200 aren't officially supported": "WARNING: Resolutions above 1200 aren't officially supported" "WARNING: Resolutions above 1200 aren't officially supported": "WARNING: Resolutions above 1200 aren't officially supported",
//0.6.8:
"Album removed from library!": "Album removed from library!",
"Remove offline": "Remove offline",
"Playlist removed from library!": "Playlist removed from library!"
} }
}; };

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttericon/font_awesome5_icons.dart'; import 'package:fluttericon/font_awesome5_icons.dart';
@ -18,18 +19,35 @@ import 'cached_image.dart';
import 'tiles.dart'; import 'tiles.dart';
import 'menu.dart'; import 'menu.dart';
class AlbumDetails extends StatelessWidget { class AlbumDetails extends StatefulWidget {
Album album; Album album;
AlbumDetails(this.album, {Key key}): super(key: key);
AlbumDetails(this.album); @override
_AlbumDetailsState createState() => _AlbumDetailsState();
}
class _AlbumDetailsState extends State<AlbumDetails> {
Album album;
bool _loading = true;
bool _error = false;
Future _loadAlbum() async { Future _loadAlbum() async {
//Get album from API, if doesn't have tracks //Get album from API, if doesn't have tracks
if (this.album.tracks == null || this.album.tracks.length == 0) { if (this.album.tracks == null || this.album.tracks.length == 0) {
this.album = await deezerAPI.album(album.id); try {
Album a = await deezerAPI.album(album.id);
//Preserve library
a.library = album.library;
setState(() => album = a);
} catch (e) {
setState(() => _error = true);
} }
} }
setState(() => _loading = false);
}
//Get count of CDs in album //Get count of CDs in album
int get cdCount { int get cdCount {
@ -40,19 +58,18 @@ class AlbumDetails extends StatelessWidget {
return c; return c;
} }
@override
void initState() {
this.album = widget.album;
_loadAlbum();
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: FutureBuilder( body: _error ? ErrorScreen() : _loading ? Center(child: CircularProgressIndicator()) :
future: _loadAlbum(), ListView(
builder: (BuildContext context, AsyncSnapshot snapshot) {
//Wait for data
if (snapshot.connectionState != ConnectionState.done) return Center(child: CircularProgressIndicator(),);
//On error
if (snapshot.hasError) return ErrorScreen();
return ListView(
children: <Widget>[ children: <Widget>[
//Album art, title, artists //Album art, title, artists
Container( Container(
@ -151,18 +168,31 @@ class AlbumDetails extends StatelessWidget {
FlatButton( FlatButton(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Icon(Icons.favorite, size: 32), Icon((album.library??false)? Icons.favorite : Icons.favorite_border, size: 32),
Container(width: 4,), Container(width: 4,),
Text('Library'.i18n) Text('Library'.i18n)
], ],
), ),
onPressed: () async { onPressed: () async {
//Add to library
if (!album.library) {
await deezerAPI.addFavoriteAlbum(album.id); await deezerAPI.addFavoriteAlbum(album.id);
Fluttertoast.showToast( Fluttertoast.showToast(
msg: 'Added to library'.i18n, msg: 'Added to library'.i18n,
toastLength: Toast.LENGTH_SHORT, toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM gravity: ToastGravity.BOTTOM
); );
setState(() => album.library = true);
return;
}
//Remove
await deezerAPI.removeAlbum(album.id);
Fluttertoast.showToast(
msg: 'Album removed from library!'.i18n,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM
);
setState(() => album.library = false);
}, },
), ),
MakeAlbumOffline(album: album), MakeAlbumOffline(album: album),
@ -211,8 +241,6 @@ class AlbumDetails extends StatelessWidget {
); );
}), }),
], ],
);
},
) )
); );
} }
@ -812,7 +840,10 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: ListView( body: DraggableScrollbar.rrect(
controller: _scrollController,
backgroundColor: Theme.of(context).primaryColor,
child: ListView(
controller: _scrollController, controller: _scrollController,
children: <Widget>[ children: <Widget>[
Container(height: 4.0,), Container(height: 4.0,),
@ -908,15 +939,31 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
MakePlaylistOffline(playlist), MakePlaylistOffline(playlist),
if (playlist.user.name != deezerAPI.userName)
IconButton( IconButton(
icon: Icon(Icons.favorite, size: 32), icon: Icon(playlist.library ? Icons.favorite : Icons.favorite_outline, size: 32),
onPressed: () async { onPressed: () async {
//Add to library
if (!playlist.library) {
await deezerAPI.addPlaylist(playlist.id); await deezerAPI.addPlaylist(playlist.id);
Fluttertoast.showToast( Fluttertoast.showToast(
msg: 'Added to library'.i18n, msg: 'Added to library'.i18n,
toastLength: Toast.LENGTH_SHORT, toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM gravity: ToastGravity.BOTTOM
); );
setState(() => playlist.library = true);
return;
}
//Remove
await deezerAPI.removePlaylist(playlist.id);
Fluttertoast.showToast(
msg: 'Playlist removed from library!'.i18n,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM
);
setState(() => playlist.library = false);
}, },
), ),
IconButton( IconButton(
@ -1006,6 +1053,7 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
if (_error) if (_error)
ErrorScreen() ErrorScreen()
], ],
),
) )
); );
} }

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:freezer/main.dart';
import 'package:wakelock/wakelock.dart'; import 'package:wakelock/wakelock.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:audio_service/audio_service.dart'; import 'package:audio_service/audio_service.dart';
@ -12,18 +13,19 @@ import 'package:freezer/api/player.dart';
import 'package:freezer/ui/details_screens.dart'; import 'package:freezer/ui/details_screens.dart';
import 'package:freezer/ui/error.dart'; import 'package:freezer/ui/error.dart';
import 'package:freezer/translations.i18n.dart'; import 'package:freezer/translations.i18n.dart';
import 'package:freezer/api/definitions.dart';
import 'package:freezer/ui/cached_image.dart';
import 'package:numberpicker/numberpicker.dart'; import 'package:numberpicker/numberpicker.dart';
import 'package:share/share.dart'; import 'package:share/share.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../api/definitions.dart';
import 'cached_image.dart';
class MenuSheet { class MenuSheet {
BuildContext context; BuildContext context;
Function navigateCallback;
MenuSheet(this.context); MenuSheet(this.context, {this.navigateCallback});
//=================== //===================
// DEFAULT // DEFAULT
@ -273,9 +275,13 @@ class MenuSheet {
leading: Icon(Icons.recent_actors), leading: Icon(Icons.recent_actors),
onTap: () { onTap: () {
_close(); _close();
Navigator.of(context).push( navigatorKey.currentState.push(
MaterialPageRoute(builder: (context) => ArtistDetails(a)) MaterialPageRoute(builder: (context) => ArtistDetails(a))
); );
if (this.navigateCallback != null) {
this.navigateCallback();
}
}, },
); );
@ -288,9 +294,13 @@ class MenuSheet {
leading: Icon(Icons.album), leading: Icon(Icons.album),
onTap: () { onTap: () {
_close(); _close();
Navigator.of(context).push( navigatorKey.currentState.push(
MaterialPageRoute(builder: (context) => AlbumDetails(a)) MaterialPageRoute(builder: (context) => AlbumDetails(a))
); );
if (this.navigateCallback != null) {
this.navigateCallback();
}
}, },
); );
@ -303,14 +313,24 @@ class MenuSheet {
}, },
); );
Widget offlineTrack(Track track) => ListTile( Widget offlineTrack(Track track) => FutureBuilder(
title: Text('Offline'.i18n), future: downloadManager.checkOffline(track: track),
builder: (context, snapshot) {
bool isOffline = snapshot.data??(track.offline??false);
return ListTile(
title: Text(isOffline ? 'Remove offline'.i18n : 'Offline'.i18n),
leading: Icon(Icons.offline_pin), leading: Icon(Icons.offline_pin),
onTap: () async { onTap: () async {
if (isOffline) {
await downloadManager.removeOfflineTracks([track]);
} else {
await downloadManager.addOfflineTrack(track, private: true, context: context); await downloadManager.addOfflineTrack(track, private: true, context: context);
}
_close(); _close();
}, },
); );
},
);
//=================== //===================
// ALBUM // ALBUM

View File

@ -51,16 +51,16 @@ class _PlayerScreenState extends State<PlayerScreen> {
//Update notification //Update notification
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: palette.dominantColor.color.withOpacity(0.5) statusBarColor: palette.dominantColor.color.withOpacity(0.7)
)); ));
setState(() => _bgGradient = LinearGradient( setState(() => _bgGradient = LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [palette.dominantColor.color.withOpacity(0.5), Color.fromARGB(0, 0, 0, 0)], colors: [palette.dominantColor.color.withOpacity(0.7), Color.fromARGB(0, 0, 0, 0)],
stops: [ stops: [
0.0, 0.0,
0.4 0.6
] ]
)); ));
} }
@ -408,7 +408,9 @@ class PlayerMenuButton extends StatelessWidget {
icon: Icon(Icons.more_vert, size: ScreenUtil().setWidth(46)), icon: Icon(Icons.more_vert, size: ScreenUtil().setWidth(46)),
onPressed: () { onPressed: () {
Track t = Track.fromMediaItem(AudioService.currentMediaItem); Track t = Track.fromMediaItem(AudioService.currentMediaItem);
MenuSheet m = MenuSheet(context); MenuSheet m = MenuSheet(context, navigateCallback: () {
Navigator.of(context).pop();
});
if (AudioService.currentMediaItem.extras['show'] == null) if (AudioService.currentMediaItem.extras['show'] == null)
m.defaultTrackMenu(t, options: [m.sleepTimer(), m.wakelock()]); m.defaultTrackMenu(t, options: [m.sleepTimer(), m.wakelock()]);
else else

View File

@ -1362,7 +1362,7 @@ class _CreditsScreenState extends State<CreditsScreen> {
subtitle: Text('Official Discord server'.i18n), subtitle: Text('Official Discord server'.i18n),
leading: Icon(FontAwesome5.discord, color: Color(0xff7289da), size: 36.0), leading: Icon(FontAwesome5.discord, color: Color(0xff7289da), size: 36.0),
onTap: () { onTap: () {
launch('https://discord.gg/7ap654Tp3z'); launch('https://discord.gg/qwJpa3r4dQ');
}, },
), ),
ListTile( ListTile(
@ -1373,6 +1373,14 @@ class _CreditsScreenState extends State<CreditsScreen> {
launch('https://git.rip/freezer/'); launch('https://git.rip/freezer/');
}, },
), ),
ListTile(
title: Text('Donate'),
subtitle: Text('You should rather support your favorite artists, instead of this app!'),
leading: Icon(FontAwesome5.paypal, color: Colors.blue, size: 36.0),
onTap: () {
launch('https://paypal.me/exttex');
},
),
FreezerDivider(), FreezerDivider(),
ListTile( ListTile(
title: Text('exttex'), title: Text('exttex'),

View File

@ -517,21 +517,21 @@ packages:
name: just_audio name: just_audio
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.6" version: "0.6.1"
just_audio_platform_interface: just_audio_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: just_audio_platform_interface name: just_audio_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "2.0.0"
just_audio_web: just_audio_web:
dependency: transitive dependency: transitive
description: description:
name: just_audio_web name: just_audio_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.1" version: "0.2.0"
language_pickers: language_pickers:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.6.7+1 version: 0.6.8+1
environment: environment:
sdk: ">=2.8.0 <3.0.0" sdk: ">=2.8.0 <3.0.0"
@ -79,7 +79,7 @@ dependencies:
audio_session: ^0.0.9 audio_session: ^0.0.9
audio_service: audio_service:
path: ./audio_service path: ./audio_service
just_audio: ^0.5.6 just_audio: 0.6.1
# path: ./just_audio # path: ./just_audio
# cupertino_icons: ^0.1.3 # cupertino_icons: ^0.1.3