0.6.7 - shows in search, album art resolution

This commit is contained in:
exttex 2020-12-14 18:29:28 +01:00
parent babd12bae2
commit c3a26b0e3b
18 changed files with 369 additions and 28 deletions

View File

@ -400,8 +400,8 @@ public class Deezer {
PictureTypes.DEFAULT_ID,
ImageFormats.MIME_TYPE_JPEG,
"cover",
1400,
1400,
settings.albumArtResolution,
settings.albumArtResolution,
24,
0
));

View File

@ -489,7 +489,7 @@ public class DownloadService extends Service {
File coverFile = new File(outFile.getPath().substring(0, outFile.getPath().lastIndexOf('.')) + ".jpg");
try {
URL url = new URL("http://e-cdn-images.deezer.com/images/cover/" + trackJson.getString("md5_image") + "/1400x1400-000000-80-0-0.jpg");
URL url = new URL("http://e-cdn-images.deezer.com/images/cover/" + albumJson.getString("md5_image") + "/" + Integer.toString(settings.albumArtResolution) + "x" + Integer.toString(settings.albumArtResolution) + "-000000-80-0-0.jpg");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//Set headers
connection.setRequestMethod("GET");
@ -568,7 +568,7 @@ public class DownloadService extends Service {
//Create to lock
coverFile.createNewFile();
URL url = new URL("http://e-cdn-images.deezer.com/images/cover/" + albumJson.getString("md5_image") + "/1400x1400-000000-80-0-0.jpg");
URL url = new URL("http://e-cdn-images.deezer.com/images/cover/" + albumJson.getString("md5_image") + "/" + Integer.toString(settings.albumArtResolution) + "x" + Integer.toString(settings.albumArtResolution) + "-000000-80-0-0.jpg");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//Set headers
connection.setRequestMethod("GET");
@ -808,8 +808,9 @@ public class DownloadService extends Service {
boolean albumCover;
boolean nomediaFiles;
String artistSeparator;
int albumArtResolution;
private DownloadSettings(int downloadThreads, boolean overwriteDownload, boolean downloadLyrics, boolean trackCover, String arl, boolean albumCover, boolean nomediaFiles, String artistSeparator) {
private DownloadSettings(int downloadThreads, boolean overwriteDownload, boolean downloadLyrics, boolean trackCover, String arl, boolean albumCover, boolean nomediaFiles, String artistSeparator, int albumArtResolution) {
this.downloadThreads = downloadThreads;
this.overwriteDownload = overwriteDownload;
this.downloadLyrics = downloadLyrics;
@ -818,6 +819,7 @@ public class DownloadService extends Service {
this.albumCover = albumCover;
this.nomediaFiles = nomediaFiles;
this.artistSeparator = artistSeparator;
this.albumArtResolution = albumArtResolution;
}
//Parse settings from bundle sent from UI
@ -833,7 +835,8 @@ public class DownloadService extends Service {
json.getString("arl"),
json.getBoolean("albumCover"),
json.getBoolean("nomediaFiles"),
json.getString("artistSeparator")
json.getString("artistSeparator"),
json.getInt("albumArtResolution")
);
} catch (Exception e) {
//Shouldn't happen

View File

@ -51,6 +51,9 @@ class Cache {
@JsonKey(defaultValue: 0)
int lastUpdateCheck;
@JsonKey(ignore: true)
bool wakelock = false;
Cache({this.libraryTracks});
//Wrapper to test if track is favorite against cache

View File

@ -392,7 +392,7 @@ class Playlist {
id: json['PLAYLIST_ID'].toString(),
title: json['TITLE'],
trackCount: json['NB_SONG']??songsJson['total'],
image: ImageDetails.fromPrivateString(json['PLAYLIST_PICTURE'], type: 'playlist'),
image: ImageDetails.fromPrivateString(json['PLAYLIST_PICTURE'], type: json['PICTURE_TYPE']),
fans: json['NB_FAN'],
duration: Duration(seconds: json['DURATION']??0),
description: json['DESCRIPTION'],
@ -464,7 +464,7 @@ class ImageDetails {
//JSON
factory ImageDetails.fromPrivateString(String art, {String type='cover'}) => ImageDetails(
fullUrl: 'https://e-cdns-images.dzcdn.net/images/$type/$art/1400x1400-000000-80-0-0.jpg',
fullUrl: 'https://e-cdns-images.dzcdn.net/images/$type/$art/1000x1000-000000-80-0-0.jpg',
thumbUrl: 'https://e-cdns-images.dzcdn.net/images/$type/$art/140x140-000000-80-0-0.jpg'
);
factory ImageDetails.fromPrivateJson(Map<dynamic, dynamic> json) => ImageDetails.fromPrivateString(
@ -481,22 +481,28 @@ class SearchResults {
List<Album> albums;
List<Artist> artists;
List<Playlist> playlists;
List<Show> shows;
List<ShowEpisode> episodes;
SearchResults({this.tracks, this.albums, this.artists, this.playlists});
SearchResults({this.tracks, this.albums, this.artists, this.playlists, this.shows, this.episodes});
//Check if no search results
bool get empty {
return ((tracks == null || tracks.length == 0) &&
(albums == null || albums.length == 0) &&
(artists == null || artists.length == 0) &&
(playlists == null || playlists.length == 0));
(playlists == null || playlists.length == 0) &&
(shows == null || shows.length == 0) &&
(episodes == null || episodes.length == 0));
}
factory SearchResults.fromPrivateJson(Map<dynamic, dynamic> json) => SearchResults(
tracks: json['TRACK']['data'].map<Track>((dynamic data) => Track.fromPrivateJson(data)).toList(),
albums: json['ALBUM']['data'].map<Album>((dynamic data) => Album.fromPrivateJson(data)).toList(),
artists: json['ARTIST']['data'].map<Artist>((dynamic data) => Artist.fromPrivateJson(data)).toList(),
playlists: json['PLAYLIST']['data'].map<Playlist>((dynamic data) => Playlist.fromPrivateJson(data)).toList()
playlists: json['PLAYLIST']['data'].map<Playlist>((dynamic data) => Playlist.fromPrivateJson(data)).toList(),
shows: json['SHOW']['data'].map<Show>((dynamic data) => Show.fromPrivateJson(data)).toList(),
episodes: json['EPISODE']['data'].map<ShowEpisode>((dynamic data) => ShowEpisode.fromPrivateJson(data)).toList()
);
}
@ -897,8 +903,10 @@ class ShowEpisode {
String url;
Duration duration;
String publishedDate;
//Might not be fully available
Show show;
ShowEpisode({this.id, this.title, this.description, this.url, this.duration, this.publishedDate});
ShowEpisode({this.id, this.title, this.description, this.url, this.duration, this.publishedDate, this.show});
String get durationString => "${duration.inMinutes}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}";
@ -917,7 +925,7 @@ class ShowEpisode {
},
displayDescription: description,
duration: duration,
artUri: show.art.full
artUri: show.art.full,
);
}
factory ShowEpisode.fromMediaItem(MediaItem mi) {
@ -927,6 +935,7 @@ class ShowEpisode {
description: mi.displayDescription,
url: mi.extras['showUrl'],
duration: mi.duration,
show: Show.fromPrivateJson(mi.extras['show'])
);
}
@ -937,7 +946,8 @@ class ShowEpisode {
description: json['EPISODE_DESCRIPTION'],
url: json['EPISODE_DIRECT_STREAM_URL'],
duration: Duration(seconds: int.parse(json['DURATION'].toString())),
publishedDate: json['EPISODE_PUBLISHED_TIMESTAMP']
publishedDate: json['EPISODE_PUBLISHED_TIMESTAMP'],
show: Show.fromPrivateJson(json)
);
factory ShowEpisode.fromJson(Map<String, dynamic> json) => _$ShowEpisodeFromJson(json);

View File

@ -453,6 +453,9 @@ ShowEpisode _$ShowEpisodeFromJson(Map<String, dynamic> json) {
? null
: Duration(microseconds: json['duration'] as int),
publishedDate: json['publishedDate'] as String,
show: json['show'] == null
? null
: Show.fromJson(json['show'] as Map<String, dynamic>),
);
}
@ -464,4 +467,5 @@ Map<String, dynamic> _$ShowEpisodeToJson(ShowEpisode instance) =>
'url': instance.url,
'duration': instance.duration?.inMicroseconds,
'publishedDate': instance.publishedDate,
'show': instance.show,
};

View File

@ -45,6 +45,7 @@ class PlayerHelper {
if (event['action'] == 'onRestore') {
//Load queueSource from isolate
this.queueSource = QueueSource.fromJson(event['queueSource']);
repeatType = LoopMode.values[event['loopMode']];
}
if (event['action'] == 'queueEnd') {
//If last song is played, load more queue
@ -332,6 +333,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
int wifiQuality;
QueueSource queueSource;
Duration _lastPosition;
LoopMode _loopMode = LoopMode.off;
Completer _androidAutoCallback;
@ -439,6 +441,19 @@ class AudioPlayerTask extends BackgroundAudioTask {
@override
Future<void> onSeekBackward(bool begin) async => _seekContinuously(begin, -1);
//Remove item from queue
@override
Future<void> onRemoveQueueItem(MediaItem mediaItem) async {
int index = _queue.indexWhere((m) => m.id == mediaItem.id);
_queue.removeAt(index);
if (index <= _queueIndex) {
_queueIndex--;
}
_audioSource.removeAt(index);
AudioServiceBackground.setQueue(_queue);
}
@override
Future<void> onSkipToNext() async {
if (_queueIndex == _queue.length-1) return;
@ -630,7 +645,8 @@ class AudioPlayerTask extends BackgroundAudioTask {
}
//Looping
if (name == 'repeatType') {
_player.setLoopMode(LoopMode.values[args]);
_loopMode = LoopMode.values[args];
_player.setLoopMode(_loopMode);
}
if (name == 'saveQueue')
await this._saveQueue();
@ -708,6 +724,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
'queue': _queue.map<Map<String, dynamic>>((mi) => mi.toJson()).toList(),
'position': _player.position.inMilliseconds,
'queueSource': (queueSource??QueueSource()).toJson(),
'loopMode': LoopMode.values.indexOf(_loopMode??LoopMode.off)
};
await f.writeAsString(jsonEncode(data));
}
@ -721,6 +738,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
this._queueIndex = json['index'] ?? 0;
this._lastPosition = Duration(milliseconds: json['position']??0);
this.queueSource = QueueSource.fromJson(json['queueSource']??{});
this._loopMode = LoopMode.values[(json['loopMode']??0)];
//Restore queue
if (_queue != null) {
await AudioServiceBackground.setQueue(_queue);
@ -731,7 +749,8 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Send restored queue source to ui
AudioServiceBackground.sendCustomEvent({
'action': 'onRestore',
'queueSource': (queueSource??QueueSource()).toJson()
'queueSource': (queueSource??QueueSource()).toJson(),
'loopMode': LoopMode.values.indexOf(_loopMode)
});
return true;
}

File diff suppressed because one or more lines are too long

View File

@ -297,6 +297,16 @@ const language_en_us = {
//0.6.6
"Restart of app is required to properly log out!": "Restart of app is required to properly log out!",
"Artist separator": "Artist separator",
"Singleton naming": "Standalone tracks filename"
"Singleton naming": "Standalone tracks filename",
//0.6.7
"Keep the screen on": "Keep the screen on",
"Wakelock enabled!": "Wakelock enabled!",
"Wakelock disabled!": "Wakelock disabled!",
"Show all shows": "Show all shows",
"Episodes": "Episodes",
"Show all episodes": "Show all episodes",
"Album cover resolution": "Album cover resolution",
"WARNING: Resolutions above 1200 aren't officially supported": "WARNING: Resolutions above 1200 aren't officially supported"
}
};

View File

@ -71,6 +71,8 @@ class Settings {
String artistSeparator;
@JsonKey(defaultValue: "%artist% - %title%")
String singletonFilename;
@JsonKey(defaultValue: 1400)
int albumArtResolution;
//Appearance
@JsonKey(defaultValue: Themes.Dark)

View File

@ -40,6 +40,7 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) {
..artistSeparator = json['artistSeparator'] as String ?? ', '
..singletonFilename =
json['singletonFilename'] as String ?? '%artist% - %title%'
..albumArtResolution = json['albumArtResolution'] as int ?? 1400
..theme =
_$enumDecodeNullable(_$ThemesEnumMap, json['theme']) ?? Themes.Dark
..useSystemTheme = json['useSystemTheme'] as bool ?? false
@ -76,6 +77,7 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
'nomediaFiles': instance.nomediaFiles,
'artistSeparator': instance.artistSeparator,
'singletonFilename': instance.singletonFilename,
'albumArtResolution': instance.albumArtResolution,
'theme': _$ThemesEnumMap[instance.theme],
'useSystemTheme': instance.useSystemTheme,
'colorGradientBackground': instance.colorGradientBackground,

View File

@ -28,6 +28,8 @@ const supportedLocales = [
const Locale('sk', 'SK'),
const Locale('cs', 'CZ'),
const Locale('vi', 'VI'),
const Locale('nl', 'NL'),
const Locale('sl', 'SL'),
const Locale('fil', 'PH'),
const Locale('uwu', 'UWU')
];

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:wakelock/wakelock.dart';
import 'package:flutter/material.dart';
import 'package:audio_service/audio_service.dart';
import 'package:fluttertoast/fluttertoast.dart';
@ -585,6 +586,33 @@ class MenuSheet {
},
);
Widget wakelock() => ListTile(
title: Text('Keep the screen on'.i18n),
leading: Icon(Icons.screen_lock_portrait),
onTap: () async {
_close();
if (cache.wakelock == null)
cache.wakelock = false;
//Enable
if (!cache.wakelock) {
Wakelock.enable();
Fluttertoast.showToast(
msg: 'Wakelock enabled!'.i18n,
gravity: ToastGravity.BOTTOM
);
cache.wakelock = true;
return;
}
//Disable
Wakelock.disable();
Fluttertoast.showToast(
msg: 'Wakelock disabled!'.i18n,
gravity: ToastGravity.BOTTOM
);
cache.wakelock = false;
},
);
void _close() => Navigator.of(context).pop();
}

View File

@ -280,7 +280,7 @@ class _PlayerScreenVerticalState extends State<PlayerScreenVertical> {
children: <Widget>[
Container(
height: ScreenUtil().setSp(64),
child: AudioService.currentMediaItem.displayTitle.length >= 24 ?
child: AudioService.currentMediaItem.displayTitle.length >= 26 ?
Marquee(
text: AudioService.currentMediaItem.displayTitle,
style: TextStyle(
@ -410,12 +410,12 @@ class PlayerMenuButton extends StatelessWidget {
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
MenuSheet m = MenuSheet(context);
if (AudioService.currentMediaItem.extras['show'] == null)
m.defaultTrackMenu(t, options: [m.sleepTimer()]);
m.defaultTrackMenu(t, options: [m.sleepTimer(), m.wakelock()]);
else
m.defaultShowEpisodeMenu(
Show.fromJson(jsonDecode(AudioService.currentMediaItem.extras['show'])),
ShowEpisode.fromMediaItem(AudioService.currentMediaItem),
options: [m.sleepTimer()]
options: [m.sleepTimer(), m.wakelock()]
);
},
);
@ -771,6 +771,13 @@ class _QueueScreenState extends State<QueueScreen> {
Navigator.of(context).pop();
},
key: Key(t.id),
trailing: IconButton(
icon: Icon(Icons.close),
onPressed: () async {
await AudioService.removeQueueItem(t.toMediaItem());
setState(() {});
},
),
);
}),
)

View File

@ -7,6 +7,7 @@ import 'package:flutter/src/services/keyboard_key.dart';
import 'package:freezer/api/cache.dart';
import 'package:freezer/api/download.dart';
import 'package:freezer/api/player.dart';
import 'package:freezer/main.dart';
import 'package:freezer/ui/details_screens.dart';
import 'package:freezer/ui/elements.dart';
import 'package:freezer/ui/home_screen.dart';
@ -657,6 +658,91 @@ class SearchResultsScreen extends StatelessWidget {
MaterialPageRoute(builder: (context) => SearchResultPlaylists(results.playlists))
);
},
),
FreezerDivider()
];
}
//Shows
List<Widget> shows = [];
if (results.shows != null && results.shows.length != 0) {
shows = [
Padding(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
child: Text(
'Shows'.i18n,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold
),
),
),
...List.generate(3, (i) {
if (results.shows.length <= i) return Container(height: 0, width: 0,);
Show s = results.shows[i];
return ShowTile(
s,
onTap: () async {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ShowScreen(s)
));
},
);
}),
ListTile(
title: Text('Show all shows'.i18n),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ShowListScreen(results.shows))
);
},
),
FreezerDivider()
];
}
//Episodes
List<Widget> episodes = [];
if (results.episodes != null && results.episodes.length != 0) {
episodes = [
Padding(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
child: Text(
'Episodes'.i18n,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold
),
),
),
...List.generate(3, (i) {
if (results.episodes.length <= i) return Container(height: 0, width: 0,);
ShowEpisode e = results.episodes[i];
return ShowEpisodeTile(
e,
trailing: IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {
MenuSheet m = MenuSheet(context);
m.defaultShowEpisodeMenu(e.show, e);
},
),
onTap: () async {
//Load entire show, then play
List<ShowEpisode> episodes = await deezerAPI.allShowEpisodes(e.show.id);
await playerHelper.playShowEpisode(e.show, episodes, index: episodes.indexWhere((ep) => e.id == ep.id));
},
);
}),
ListTile(
title: Text('Show all episodes'.i18n),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => EpisodeListScreen(results.episodes))
);
}
)
];
}
@ -670,7 +756,11 @@ class SearchResultsScreen extends StatelessWidget {
Container(height: 8.0,),
...artists,
Container(height: 8.0,),
...playlists
...playlists,
Container(height: 8.0,),
...shows,
Container(height: 8.0,),
...episodes
],
);
},
@ -773,3 +863,64 @@ class SearchResultPlaylists extends StatelessWidget {
);
}
}
class ShowListScreen extends StatelessWidget {
final List<Show> shows;
ShowListScreen(this.shows);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: FreezerAppBar('Shows'.i18n),
body: ListView.builder(
itemCount: shows.length,
itemBuilder: (context, i) {
Show s = shows[i];
return ShowTile(
s,
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ShowScreen(s)
));
},
);
},
),
);
}
}
class EpisodeListScreen extends StatelessWidget {
final List<ShowEpisode> episodes;
EpisodeListScreen(this.episodes);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: FreezerAppBar('Episodes'.i18n),
body: ListView.builder(
itemCount: episodes.length,
itemBuilder: (context, i) {
ShowEpisode e = episodes[i];
return ShowEpisodeTile(
e,
trailing: IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {
MenuSheet m = MenuSheet(context);
m.defaultShowEpisodeMenu(e.show, e);
},
),
onTap: () async {
//Load entire show, then play
List<ShowEpisode> episodes = await deezerAPI.allShowEpisodes(e.show.id);
await playerHelper.playShowEpisode(e.show, episodes, index: episodes.indexWhere((ep) => e.id == ep.id));
},
);
},
)
);
}
}

View File

@ -856,6 +856,27 @@ class _DownloadsSettingsState extends State<DownloadsSettings> {
),
leading: Icon(Icons.image)
),
ListTile(
title: Text('Album cover resolution'.i18n),
subtitle: Text("WARNING: Resolutions above 1200 aren't officially supported".i18n),
leading: Icon(Icons.image),
trailing: Container(
width: 75.0,
child: DropdownButton<int>(
value: settings.albumArtResolution,
items: [400, 800, 1000, 1200, 1400, 1600, 1800].map<DropdownMenuItem<int>>((int i) => DropdownMenuItem<int>(
value: i,
child: Text(i.toString()),
)).toList(),
onChanged: (int n) async {
setState(() {
settings.albumArtResolution = n;
});
await settings.save();
},
)
)
),
ListTile(
title: Text('Create .nomedia files'.i18n),
subtitle: Text('To prevent gallery being filled with album art'.i18n),
@ -872,7 +893,7 @@ class _DownloadsSettingsState extends State<DownloadsSettings> {
title: Text('Artist separator'.i18n),
leading: Icon(WebSymbols.tag),
trailing: Container(
width: 100.0,
width: 75.0,
child: TextField(
controller: _artistSeparatorController,
onChanged: (s) async {

View File

@ -1,6 +1,8 @@
import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:fluttericon/octicons_icons.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/download.dart';
import 'package:freezer/translations.i18n.dart';
import '../api/definitions.dart';
@ -25,6 +27,7 @@ class TrackTile extends StatefulWidget {
class _TrackTileState extends State<TrackTile> {
StreamSubscription _subscription;
bool _isOffline = false;
bool get nowPlaying {
if (AudioService.currentMediaItem == null) return false;
@ -37,6 +40,9 @@ class _TrackTileState extends State<TrackTile> {
_subscription = AudioService.currentMediaItemStream.listen((event) {
setState(() {});
});
//Check if offline
downloadManager.checkOffline(track: widget.track).then((b) => setState(() => _isOffline = b));
super.initState();
}
@ -70,9 +76,18 @@ class _TrackTileState extends State<TrackTile> {
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if ((_isOffline??false))
Padding(
padding: EdgeInsets.symmetric(horizontal: 2.0),
child: Icon(
Octicons.primitive_dot,
color: Colors.green,
size: 12.0,
),
),
if (widget.track.explicit??false)
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
padding: EdgeInsets.symmetric(horizontal: 2.0),
child: Text(
'E',
style: TextStyle(
@ -80,9 +95,12 @@ class _TrackTileState extends State<TrackTile> {
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2.0),
child: Text(widget.track.durationString),
Container(
width: 42.0,
child: Text(
widget.track.durationString,
textAlign: TextAlign.center,
),
),
widget.trailing??Container(width: 0, height: 0)
],
@ -497,6 +515,38 @@ class ShowCard extends StatelessWidget {
}
}
class ShowTile extends StatelessWidget {
final Show show;
final Function onTap;
final Function onHold;
ShowTile(this.show, {this.onTap, this.onHold});
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(
show.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
show.description,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onTap: onTap,
onLongPress: onHold,
leading: CachedImage(
url: show.art.thumb,
width: 48,
),
);
}
}
class ShowEpisodeTile extends StatelessWidget {
final ShowEpisode episode;

View File

@ -462,6 +462,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.5"
import_js_library:
dependency: transitive
description:
name: import_js_library
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
infinite_listview:
dependency: transitive
description:
@ -985,6 +992,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
wakelock:
dependency: "direct main"
description:
name: wakelock
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+1"
wakelock_platform_interface:
dependency: transitive
description:
name: wakelock_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+1"
wakelock_web:
dependency: transitive
description:
name: wakelock_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+3"
watcher:
dependency: transitive
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.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.6.6+1
version: 0.6.7+1
environment:
sdk: ">=2.8.0 <3.0.0"
@ -74,6 +74,7 @@ dependencies:
scrobblenaut: ^2.0.4
open_file: ^3.0.3
version: ^1.2.0
wakelock: ^0.2.1+1
audio_session: ^0.0.9
audio_service: