0.6.12 - bug fixes
This commit is contained in:
parent
aa7f82b399
commit
972e84c136
|
@ -214,7 +214,13 @@ public class Deezer {
|
|||
original = original.replaceAll("%title%", sanitize(publicTrack.getString("title")));
|
||||
original = original.replaceAll("%album%", sanitize(publicTrack.getJSONObject("album").getString("title")));
|
||||
original = original.replaceAll("%artist%", sanitize(publicTrack.getJSONObject("artist").getString("name")));
|
||||
// Album might not be available
|
||||
try {
|
||||
original = original.replaceAll("%albumArtist%", sanitize(publicAlbum.getJSONObject("artist").getString("name")));
|
||||
} catch (Exception e) {
|
||||
original = original.replaceAll("%albumArtist%", sanitize(publicTrack.getJSONObject("artist").getString("name")));
|
||||
}
|
||||
|
||||
//Artists
|
||||
String artists = "";
|
||||
String feats = "";
|
||||
|
@ -275,15 +281,16 @@ public class Deezer {
|
|||
if (!artists.contains(artist))
|
||||
artists += settings.artistSeparator + artist;
|
||||
}
|
||||
boolean albumAvailable = !publicAlbum.has("error");
|
||||
if (settings.tags.artist) tag.addField(FieldKey.ARTIST, artists.substring(settings.artistSeparator.length()));
|
||||
if (settings.tags.track) tag.setField(FieldKey.TRACK, String.format("%02d", publicTrack.getInt("track_position")));
|
||||
if (settings.tags.disc) tag.setField(FieldKey.DISC_NO, Integer.toString(publicTrack.getInt("disk_number")));
|
||||
if (settings.tags.albumArtist) tag.setField(FieldKey.ALBUM_ARTIST, publicAlbum.getJSONObject("artist").getString("name"));
|
||||
if (settings.tags.albumArtist && albumAvailable) tag.setField(FieldKey.ALBUM_ARTIST, publicAlbum.getJSONObject("artist").getString("name"));
|
||||
if (settings.tags.date) tag.setField(FieldKey.YEAR, publicTrack.getString("release_date").substring(0, 4));
|
||||
if (settings.tags.label) tag.setField(FieldKey.RECORD_LABEL, publicAlbum.getString("label"));
|
||||
if (settings.tags.label && albumAvailable) tag.setField(FieldKey.RECORD_LABEL, publicAlbum.getString("label"));
|
||||
if (settings.tags.isrc) tag.setField(FieldKey.ISRC, publicTrack.getString("isrc"));
|
||||
if (settings.tags.upc) tag.setField(FieldKey.BARCODE, publicAlbum.getString("upc"));
|
||||
if (settings.tags.trackTotal) tag.setField(FieldKey.TRACK_TOTAL, Integer.toString(publicAlbum.getInt("nb_tracks")));
|
||||
if (settings.tags.upc && albumAvailable) tag.setField(FieldKey.BARCODE, publicAlbum.getString("upc"));
|
||||
if (settings.tags.trackTotal && albumAvailable) tag.setField(FieldKey.TRACK_TOTAL, Integer.toString(publicAlbum.getInt("nb_tracks")));
|
||||
|
||||
//BPM
|
||||
if (publicTrack.has("bpm") && (int)publicTrack.getDouble("bpm") > 0)
|
||||
|
@ -301,6 +308,7 @@ public class Deezer {
|
|||
|
||||
//Genres
|
||||
String genres = "";
|
||||
if (albumAvailable) {
|
||||
for (int i=0; i<publicAlbum.getJSONObject("genres").getJSONArray("data").length(); i++) {
|
||||
String genre = publicAlbum.getJSONObject("genres").getJSONArray("data").getJSONObject(0).getString("name");
|
||||
if (!genres.contains(genre)) {
|
||||
|
@ -309,6 +317,7 @@ public class Deezer {
|
|||
}
|
||||
if (genres.length() > 2 && settings.tags.genre)
|
||||
tag.setField(FieldKey.GENRE, genres.substring(2));
|
||||
}
|
||||
|
||||
//Additional tags from private api
|
||||
if (settings.tags.contributors)
|
||||
|
|
|
@ -478,7 +478,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/" + albumJson.getString("md5_image") + "/" + Integer.toString(settings.albumArtResolution) + "x" + Integer.toString(settings.albumArtResolution) + "-000000-80-0-0.jpg");
|
||||
URL url = new URL("http://e-cdn-images.deezer.com/images/cover/" + trackJson.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");
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:freezer/api/deezer.dart';
|
||||
import 'package:freezer/api/definitions.dart';
|
||||
import 'package:freezer/ui/details_screens.dart';
|
||||
import 'package:freezer/ui/library.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'dart:async';
|
||||
|
||||
part 'cache.g.dart';
|
||||
|
||||
|
@ -68,6 +64,12 @@ class Cache {
|
|||
if (searchHistory == null)
|
||||
searchHistory = [];
|
||||
|
||||
// Remove duplicate
|
||||
int i = searchHistory.indexWhere((e) => e.data.id == item.id);
|
||||
if (i != -1) {
|
||||
searchHistory.removeAt(i);
|
||||
}
|
||||
|
||||
if (item is Track)
|
||||
searchHistory.add(SearchHistoryItem(item, SearchHistoryItemType.TRACK));
|
||||
if (item is Album)
|
||||
|
|
|
@ -32,7 +32,6 @@ class PlayerHelper {
|
|||
QueueSource queueSource;
|
||||
LoopMode repeatType = LoopMode.off;
|
||||
Timer _timer;
|
||||
Scrobblenaut scrobblenaut;
|
||||
int audioSession;
|
||||
int _prevAudioSession;
|
||||
bool equalizerOpen = false;
|
||||
|
@ -53,6 +52,7 @@ class PlayerHelper {
|
|||
//After audio_service is loaded, load queue, set quality
|
||||
await settings.updateAudioServiceQuality();
|
||||
await AudioService.customAction('load');
|
||||
await authorizeLastFM();
|
||||
break;
|
||||
case 'onRestore':
|
||||
//Load queueSource from isolate
|
||||
|
@ -126,15 +126,6 @@ class PlayerHelper {
|
|||
if (settings.logListen) {
|
||||
deezerAPI.logListen(AudioService.currentMediaItem.id);
|
||||
}
|
||||
|
||||
//LastFM
|
||||
if (scrobblenaut != null) {
|
||||
await scrobblenaut.track.scrobble(
|
||||
track: AudioService.currentMediaItem.title,
|
||||
artist: AudioService.currentMediaItem.artist,
|
||||
album: AudioService.currentMediaItem.album,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -163,15 +154,7 @@ class PlayerHelper {
|
|||
|
||||
Future authorizeLastFM() async {
|
||||
if (settings.lastFMUsername == null || settings.lastFMPassword == null) return;
|
||||
try {
|
||||
LastFM lastFM = await LastFM.authenticateWithPasswordHash(
|
||||
apiKey: 'b6ab5ae967bcd8b10b23f68f42493829',
|
||||
apiSecret: '861b0dff9a8a574bec747f9dab8b82bf',
|
||||
username: settings.lastFMUsername,
|
||||
passwordHash: settings.lastFMPassword
|
||||
);
|
||||
scrobblenaut = Scrobblenaut(lastFM: lastFM);
|
||||
} catch (e) {}
|
||||
await AudioService.customAction("authorizeLastFM", [settings.lastFMUsername, settings.lastFMPassword]);
|
||||
}
|
||||
|
||||
Future toggleShuffle() async {
|
||||
|
@ -390,6 +373,10 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
LoopMode _loopMode = LoopMode.off;
|
||||
|
||||
Completer _androidAutoCallback;
|
||||
Scrobblenaut _scrobblenaut;
|
||||
bool _scrobblenautReady = false;
|
||||
// Last logged track id
|
||||
String _loggedTrackId;
|
||||
|
||||
MediaItem get mediaItem => _queue[_queueIndex];
|
||||
|
||||
|
@ -473,13 +460,23 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
}
|
||||
|
||||
@override
|
||||
Future onPlay() {
|
||||
Future onPlay() async {
|
||||
_player.play();
|
||||
//Restore position on play
|
||||
if (_lastPosition != null) {
|
||||
onSeekTo(_lastPosition);
|
||||
_lastPosition = null;
|
||||
}
|
||||
|
||||
//LastFM
|
||||
if (_scrobblenautReady && mediaItem.id != _loggedTrackId) {
|
||||
_loggedTrackId = mediaItem.id;
|
||||
await _scrobblenaut.track.scrobble(
|
||||
track: mediaItem.title,
|
||||
artist: mediaItem.artist,
|
||||
album: mediaItem.album,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -515,6 +512,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
|
||||
@override
|
||||
Future<void> onSkipToNext() async {
|
||||
_lastPosition = null;
|
||||
if (_queueIndex == _queue.length-1) return;
|
||||
//Update buffering state
|
||||
_skipState = AudioProcessingState.skippingToNext;
|
||||
|
@ -618,6 +616,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
//Replace current queue
|
||||
@override
|
||||
Future onUpdateQueue(List<MediaItem> q) async {
|
||||
_lastPosition = null;
|
||||
//just_audio
|
||||
_shuffle = false;
|
||||
_originalQueue = null;
|
||||
|
@ -793,6 +792,25 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
_visualizerSubscription = null;
|
||||
}
|
||||
break;
|
||||
//Authorize lastfm
|
||||
case 'authorizeLastFM':
|
||||
String username = args[0];
|
||||
String password = args[1];
|
||||
try {
|
||||
LastFM lastFM = await LastFM.authenticateWithPasswordHash(
|
||||
apiKey: 'b6ab5ae967bcd8b10b23f68f42493829',
|
||||
apiSecret: '861b0dff9a8a574bec747f9dab8b82bf',
|
||||
username: username,
|
||||
passwordHash: password
|
||||
);
|
||||
_scrobblenaut = Scrobblenaut(lastFM: lastFM);
|
||||
_scrobblenautReady = true;
|
||||
} catch (e) { print(e); }
|
||||
break;
|
||||
case 'disableLastFM':
|
||||
_scrobblenaut = null;
|
||||
_scrobblenautReady = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -378,6 +378,35 @@ const language_en_us = {
|
|||
//0.6.11, offline text OCD lol
|
||||
"Track removed from offline!": "Track removed from offline!",
|
||||
"Removed album from offline!": "Removed album from offline!",
|
||||
"Playlist removed from offline!": "Playlist removed from offline!"
|
||||
"Playlist removed from offline!": "Playlist removed from offline!",
|
||||
|
||||
//0.6.11 - a11y by dangou
|
||||
"Repeat": "Repeat",
|
||||
"Repeat one": "Repeat one",
|
||||
"Repeat off": "Repeat off",
|
||||
"Love": "Love",
|
||||
"Unlove": "Unlove",
|
||||
"Dislike": "Dislike",
|
||||
"Close": "Close",
|
||||
"Sort playlist": "Sort playlist",
|
||||
"Sort ascending": "Sort ascending",
|
||||
"Sort descending": "Sort descending",
|
||||
"Stop": "Stop",
|
||||
"Start": "Start",
|
||||
"Clear all": "Clear all",
|
||||
"Play previous": "Play previous",
|
||||
"Play": "Play",
|
||||
"Pause": "Pause",
|
||||
"Remove": "Remove",
|
||||
"Seekbar": "Seekbar",
|
||||
"Singles": "Singles",
|
||||
"Featured": "Featured",
|
||||
"Fans": "Fans",
|
||||
"Duration": "Duration",
|
||||
"Sort": "Sort",
|
||||
|
||||
//0.6.12
|
||||
"Your ARL might be expired, try logging out and logging back in using new ARL or browser.": "Your ARL might be expired, try logging out and logging back in using new ARL or browser.",
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:freezer/translations.i18n.dart';
|
||||
|
||||
ImagesDatabase imagesDatabase = ImagesDatabase();
|
||||
|
||||
|
@ -115,12 +116,15 @@ class _ZoomableImageState extends State<ZoomableImage> {
|
|||
Widget build(BuildContext context) {
|
||||
ctx = context;
|
||||
return TextButton(
|
||||
child: Semantics(
|
||||
child: CachedImage(
|
||||
url: widget.url,
|
||||
rounded: widget.rounded,
|
||||
width: widget.width,
|
||||
fullThumb: true,
|
||||
),
|
||||
label: "Album art".i18n,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(PageRouteBuilder(
|
||||
opaque: false, // transparent background
|
||||
|
|
|
@ -127,7 +127,7 @@ class _AlbumDetailsState extends State<AlbumDetails> {
|
|||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.audiotrack, size: 32.0,),
|
||||
Icon(Icons.audiotrack, size: 32.0, semanticLabel: "Tracks".i18n,),
|
||||
Container(width: 8.0, height: 42.0,), //Height to adjust card height
|
||||
Text(
|
||||
album.tracks.length.toString(),
|
||||
|
@ -137,7 +137,7 @@ class _AlbumDetailsState extends State<AlbumDetails> {
|
|||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.timelapse, size: 32.0,),
|
||||
Icon(Icons.timelapse, size: 32.0, semanticLabel: "Duration".i18n,),
|
||||
Container(width: 8.0,),
|
||||
Text(
|
||||
album.durationString,
|
||||
|
@ -147,7 +147,7 @@ class _AlbumDetailsState extends State<AlbumDetails> {
|
|||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.people, size: 32.0,),
|
||||
Icon(Icons.people, size: 32.0, semanticLabel: "Fans".i18n),
|
||||
Container(width: 8.0,),
|
||||
Text(
|
||||
album.fansString,
|
||||
|
@ -361,6 +361,7 @@ class ArtistDetails extends StatelessWidget {
|
|||
Icon(
|
||||
Icons.people,
|
||||
size: 32.0,
|
||||
semanticLabel: "Fans".i18n,
|
||||
),
|
||||
Container(
|
||||
width: 8,
|
||||
|
@ -377,7 +378,7 @@ class ArtistDetails extends StatelessWidget {
|
|||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(Icons.album, size: 32.0),
|
||||
Icon(Icons.album, size: 32.0, semanticLabel: "Albums".i18n,),
|
||||
Container(
|
||||
width: 8.0,
|
||||
),
|
||||
|
@ -666,9 +667,9 @@ class _DiscographyScreenState extends State<DiscographyScreen> {
|
|||
'Discography'.i18n,
|
||||
bottom: TabBar(
|
||||
tabs: [
|
||||
Tab(icon: Icon(Icons.album)),
|
||||
Tab(icon: Icon(Icons.audiotrack)),
|
||||
Tab(icon: Icon(Icons.recent_actors))
|
||||
Tab(icon: Icon(Icons.album, semanticLabel: "Albums".i18n,)),
|
||||
Tab(icon: Icon(Icons.audiotrack, semanticLabel: "Singles".i18n)),
|
||||
Tab(icon: Icon(Icons.recent_actors, semanticLabel: "Featured".i18n,))
|
||||
],
|
||||
),
|
||||
height: 100.0,
|
||||
|
@ -894,6 +895,7 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
|
|||
Icon(
|
||||
Icons.audiotrack,
|
||||
size: 32.0,
|
||||
semanticLabel: "Tracks".i18n,
|
||||
),
|
||||
Container(width: 8.0,),
|
||||
Text((playlist.trackCount??playlist.tracks.length).toString(), style: TextStyle(fontSize: 16),)
|
||||
|
@ -905,6 +907,7 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
|
|||
Icon(
|
||||
Icons.timelapse,
|
||||
size: 32.0,
|
||||
semanticLabel: "Duration".i18n,
|
||||
),
|
||||
Container(width: 8.0,),
|
||||
Text(playlist.durationString, style: TextStyle(fontSize: 16),)
|
||||
|
@ -943,7 +946,8 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
|
|||
|
||||
if (playlist.user.name != deezerAPI.userName)
|
||||
IconButton(
|
||||
icon: Icon(playlist.library ? Icons.favorite : Icons.favorite_outline, size: 32),
|
||||
icon: Icon(playlist.library ? Icons.favorite : Icons.favorite_outline, size: 32,
|
||||
semanticLabel: playlist.library ? "Unlove".i18n : "Love".i18n,),
|
||||
onPressed: () async {
|
||||
//Add to library
|
||||
if (!playlist.library) {
|
||||
|
@ -968,14 +972,14 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
|
|||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.file_download, size: 32.0,),
|
||||
icon: Icon(Icons.file_download, size: 32.0, semanticLabel: "Download".i18n,),
|
||||
onPressed: () async {
|
||||
if (await downloadManager.addOfflinePlaylist(playlist, private: false, context: context) != false)
|
||||
MenuSheet(context).showDownloadStartedToast();
|
||||
},
|
||||
),
|
||||
PopupMenuButton(
|
||||
child: Icon(Icons.sort, size: 32.0),
|
||||
child: Icon(Icons.sort, size: 32.0, semanticLabel: "Sort playlist".i18n,),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
onSelected: (SortType s) async {
|
||||
if (playlist.tracks.length < playlist.trackCount) {
|
||||
|
@ -1013,7 +1017,8 @@ class _PlaylistDetailsState extends State<PlaylistDetails> {
|
|||
],
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down),
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down,
|
||||
semanticLabel: _sort.reverse ? "Sort descending".i18n : "Sort ascending".i18n,),
|
||||
onPressed: () => _reverse(),
|
||||
),
|
||||
Container(width: 4.0)
|
||||
|
@ -1230,7 +1235,7 @@ class _ShowScreenState extends State<ShowScreen> {
|
|||
return ShowEpisodeTile(
|
||||
e,
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.more_vert),
|
||||
icon: Icon(Icons.more_vert, semanticLabel: "Options".i18n,),
|
||||
onPressed: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultShowEpisodeMenu(_show, e);
|
||||
|
|
|
@ -74,7 +74,7 @@ class _DownloadsScreenState extends State<DownloadsScreen> {
|
|||
'Downloads'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.delete_sweep),
|
||||
icon: Icon(Icons.delete_sweep, semanticLabel: "Clear all".i18n,),
|
||||
onPressed: () async {
|
||||
await downloadManager.removeDownloads(DownloadState.ERROR);
|
||||
await downloadManager.removeDownloads(DownloadState.DEEZER_ERROR);
|
||||
|
@ -84,7 +84,8 @@ class _DownloadsScreenState extends State<DownloadsScreen> {
|
|||
),
|
||||
IconButton(
|
||||
icon:
|
||||
Icon(downloadManager.running ? Icons.stop : Icons.play_arrow),
|
||||
Icon(downloadManager.running ? Icons.stop : Icons.play_arrow,
|
||||
semanticLabel: downloadManager.running ? "Stop".i18n : "Start".i18n,),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
if (downloadManager.running)
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
import 'package:connectivity/connectivity.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:freezer/translations.i18n.dart';
|
||||
|
||||
class ErrorScreen extends StatelessWidget {
|
||||
int counter = 0;
|
||||
|
||||
class ErrorScreen extends StatefulWidget {
|
||||
final String message;
|
||||
const ErrorScreen({this.message, Key key}) : super(key: key);
|
||||
|
||||
ErrorScreen({this.message});
|
||||
@override
|
||||
_ErrorScreenState createState() => _ErrorScreenState();
|
||||
}
|
||||
|
||||
class _ErrorScreenState extends State<ErrorScreen> {
|
||||
|
||||
bool checkArl = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
||||
Connectivity().checkConnectivity().then((connectivity) {
|
||||
if (connectivity != ConnectivityResult.none && counter > 3) {
|
||||
setState(() {
|
||||
checkArl = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
counter += 1;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -19,7 +44,18 @@ class ErrorScreen extends StatelessWidget {
|
|||
size: 64.0,
|
||||
),
|
||||
Container(height: 4.0,),
|
||||
Text(message ?? 'Please check your connection and try again later...'.i18n)
|
||||
Text(widget.message ?? 'Please check your connection and try again later...'.i18n),
|
||||
if (checkArl)
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 32.0),
|
||||
child: Text(
|
||||
"Your ARL might be expired, try logging out and logging back in using new ARL or browser.".i18n,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -98,7 +98,7 @@ class _SpotifyImporterV1State extends State<SpotifyImporterV1> {
|
|||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.search),
|
||||
icon: Icon(Icons.search, semanticLabel: "Search".i18n,),
|
||||
onPressed: () => _load(),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -33,7 +33,7 @@ class LibraryAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
'Library'.i18n,
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.file_download),
|
||||
icon: Icon(Icons.file_download, semanticLabel: "Download".i18n,),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => DownloadsScreen())
|
||||
|
@ -41,7 +41,7 @@ class LibraryAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.settings),
|
||||
icon: Icon(Icons.settings, semanticLabel: "Settings".i18n,),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => SettingsScreen())
|
||||
|
@ -420,13 +420,14 @@ class _LibraryTracksState extends State<LibraryTracks> {
|
|||
'Tracks'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down),
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down,
|
||||
semanticLabel: _sort.reverse ? "Sort descending".i18n : "Sort ascending".i18n,),
|
||||
onPressed: () async {
|
||||
await _reverse();
|
||||
}
|
||||
),
|
||||
PopupMenuButton(
|
||||
child: Icon(Icons.sort, size: 32.0),
|
||||
child: Icon(Icons.sort, size: 32.0, semanticLabel: "Sort".i18n,),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
onSelected: (SortType s) async {
|
||||
//Preload for sorting
|
||||
|
@ -631,7 +632,8 @@ class _LibraryAlbumsState extends State<LibraryAlbums> {
|
|||
'Albums'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down),
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down,
|
||||
semanticLabel: _sort.reverse ? "Sort descending".i18n : "Sort ascending".i18n,),
|
||||
onPressed: () => _reverse(),
|
||||
),
|
||||
PopupMenuButton(
|
||||
|
@ -834,7 +836,8 @@ class _LibraryArtistsState extends State<LibraryArtists> {
|
|||
'Artists'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down),
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down,
|
||||
semanticLabel: _sort.reverse ? "Sort descending".i18n : "Sort ascending".i18n,),
|
||||
onPressed: () => _reverse(),
|
||||
),
|
||||
PopupMenuButton(
|
||||
|
@ -995,7 +998,8 @@ class _LibraryPlaylistsState extends State<LibraryPlaylists> {
|
|||
'Playlists'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down),
|
||||
icon: Icon(_sort.reverse ? FontAwesome5.sort_alpha_up : FontAwesome5.sort_alpha_down,
|
||||
semanticLabel: _sort.reverse ? "Sort descending".i18n : "Sort ascending".i18n,),
|
||||
onPressed: () => _reverse(),
|
||||
),
|
||||
PopupMenuButton(
|
||||
|
@ -1178,7 +1182,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
|
|||
'History'.i18n,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.delete_sweep),
|
||||
icon: Icon(Icons.delete_sweep, semanticLabel: "Clear all".i18n,),
|
||||
onPressed: () {
|
||||
setState(() => cache.history = []);
|
||||
cache.save();
|
||||
|
|
|
@ -67,11 +67,15 @@ class MenuSheet {
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
CachedImage(
|
||||
Semantics(
|
||||
child: CachedImage(
|
||||
url: track.albumArt.full,
|
||||
height: 128,
|
||||
width: 128,
|
||||
),
|
||||
label: "Album art".i18n,
|
||||
image: true,
|
||||
),
|
||||
Container(
|
||||
width: 240.0,
|
||||
child: Column(
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:audio_service/audio_service.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezer/settings.dart';
|
||||
import 'package:freezer/translations.i18n.dart';
|
||||
|
||||
import '../api/player.dart';
|
||||
import 'cached_image.dart';
|
||||
|
@ -122,13 +123,13 @@ class PrevNextButton extends StatelessWidget {
|
|||
if (!prev) {
|
||||
if (playerHelper.queueIndex == (AudioService.queue??[]).length - 1) {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.skip_next),
|
||||
icon: Icon(Icons.skip_next, semanticLabel: "Play next".i18n,),
|
||||
iconSize: size,
|
||||
onPressed: null,
|
||||
);
|
||||
}
|
||||
return IconButton(
|
||||
icon: Icon(Icons.skip_next),
|
||||
icon: Icon(Icons.skip_next, semanticLabel: "Play next".i18n,),
|
||||
iconSize: size,
|
||||
onPressed: () => AudioService.skipToNext(),
|
||||
);
|
||||
|
@ -139,13 +140,13 @@ class PrevNextButton extends StatelessWidget {
|
|||
return Container(height: 0, width: 0,);
|
||||
}
|
||||
return IconButton(
|
||||
icon: Icon(Icons.skip_previous),
|
||||
icon: Icon(Icons.skip_previous, semanticLabel: "Play previous".i18n,),
|
||||
iconSize: size,
|
||||
onPressed: null,
|
||||
);
|
||||
}
|
||||
return IconButton(
|
||||
icon: Icon(Icons.skip_previous),
|
||||
icon: Icon(Icons.skip_previous, semanticLabel: "Play previous".i18n,),
|
||||
iconSize: size,
|
||||
onPressed: () => AudioService.skipToPrevious(),
|
||||
);
|
||||
|
@ -203,6 +204,7 @@ class _PlayPauseButtonState extends State<PlayPauseButton> with SingleTickerProv
|
|||
icon: AnimatedIcon(
|
||||
icon: AnimatedIcons.play_pause,
|
||||
progress: _animation,
|
||||
semanticLabel: _playing ? "Pause".i18n : "Play".i18n,
|
||||
),
|
||||
iconSize: widget.size,
|
||||
onPressed: _playing
|
||||
|
|
|
@ -263,7 +263,8 @@ class _PlayerScreenHorizontalState extends State<PlayerScreenHorizontal> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.subtitles, size: ScreenUtil().setWidth(32)),
|
||||
icon: Icon(Icons.subtitles, size: ScreenUtil().setWidth(32),
|
||||
semanticLabel: "Lyrics".i18n,),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => LyricsScreen(trackId: AudioService.currentMediaItem.id)
|
||||
|
@ -365,7 +366,8 @@ class _PlayerScreenVerticalState extends State<PlayerScreenVertical> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.subtitles, size: ScreenUtil().setWidth(46)),
|
||||
icon: Icon(Icons.subtitles, size: ScreenUtil().setWidth(46),
|
||||
semanticLabel: "Lyrics".i18n,),
|
||||
onPressed: () async {
|
||||
//Fix bottom buttons
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
|
@ -381,7 +383,7 @@ class _PlayerScreenVerticalState extends State<PlayerScreenVertical> {
|
|||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.file_download),
|
||||
icon: Icon(Icons.file_download, semanticLabel: "Download".i18n,),
|
||||
onPressed: () async {
|
||||
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
||||
if (await downloadManager.addOfflineTrack(t, private: false, context: context, isSingleton: true) != false)
|
||||
|
@ -466,7 +468,8 @@ class PlayerMenuButton extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.more_vert, size: ScreenUtil().setWidth(46)),
|
||||
icon: Icon(Icons.more_vert, size: ScreenUtil().setWidth(46),
|
||||
semanticLabel: "Options".i18n,),
|
||||
onPressed: () {
|
||||
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
||||
MenuSheet m = MenuSheet(context, navigateCallback: () {
|
||||
|
@ -502,19 +505,22 @@ class _RepeatButtonState extends State<RepeatButton> {
|
|||
case LoopMode.off:
|
||||
return Icon(
|
||||
Icons.repeat,
|
||||
size: widget.iconSize
|
||||
size: widget.iconSize,
|
||||
semanticLabel: "Repeat off".i18n,
|
||||
);
|
||||
case LoopMode.all:
|
||||
return Icon(
|
||||
Icons.repeat,
|
||||
color: Theme.of(context).primaryColor,
|
||||
size: widget.iconSize
|
||||
size: widget.iconSize,
|
||||
semanticLabel: "Repeat".i18n,
|
||||
);
|
||||
case LoopMode.one:
|
||||
return Icon(
|
||||
Icons.repeat_one,
|
||||
color: Theme.of(context).primaryColor,
|
||||
size: widget.iconSize
|
||||
size: widget.iconSize,
|
||||
semanticLabel: "Repeat one".i18n,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -546,9 +552,9 @@ class _PlaybackControlsState extends State<PlaybackControls> {
|
|||
|
||||
Icon get libraryIcon {
|
||||
if (cache.checkTrackFavorite(Track.fromMediaItem(AudioService.currentMediaItem))) {
|
||||
return Icon(Icons.favorite, size: widget.iconSize * 0.64);
|
||||
return Icon(Icons.favorite, size: widget.iconSize * 0.64, semanticLabel: "Unlove".i18n,);
|
||||
}
|
||||
return Icon(Icons.favorite_border, size: widget.iconSize * 0.64);
|
||||
return Icon(Icons.favorite_border, size: widget.iconSize * 0.64, semanticLabel: "Love".i18n,);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -560,7 +566,7 @@ class _PlaybackControlsState extends State<PlaybackControls> {
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.sentiment_very_dissatisfied, size: ScreenUtil().setWidth(46)),
|
||||
icon: Icon(Icons.sentiment_very_dissatisfied, size: ScreenUtil().setWidth(46), semanticLabel: "Dislike".i18n,),
|
||||
onPressed: () async {
|
||||
await deezerAPI.dislikeTrack(AudioService.currentMediaItem.id);
|
||||
if (playerHelper.queueIndex < (AudioService.queue??[]).length - 1) {
|
||||
|
@ -678,7 +684,7 @@ class PlayerScreenTopRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.menu),
|
||||
icon: Icon(Icons.menu, semanticLabel: "Queue".i18n,),
|
||||
iconSize: this.iconSize??ScreenUtil().setSp(52),
|
||||
splashRadius: this.iconSize??ScreenUtil().setWidth(52),
|
||||
onPressed: () async {
|
||||
|
@ -823,6 +829,7 @@ class _QueueScreenState extends State<QueueScreen> {
|
|||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.shuffle,
|
||||
semanticLabel: "Shuffle".i18n,
|
||||
),
|
||||
onPressed: () async {
|
||||
await playerHelper.toggleShuffle();
|
||||
|
@ -848,7 +855,7 @@ class _QueueScreenState extends State<QueueScreen> {
|
|||
},
|
||||
key: Key(i.toString()),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: Icon(Icons.close, semanticLabel: "Close".i18n,),
|
||||
onPressed: () async {
|
||||
await AudioService.removeQueueItem(t.toMediaItem());
|
||||
setState(() {});
|
||||
|
|
|
@ -111,7 +111,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
|
||||
Widget _removeHistoryItemWidget(int index) {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: Icon(Icons.close, semanticLabel: "Remove".i18n,),
|
||||
onPressed: () async {
|
||||
if (cache.searchHistory != null)
|
||||
cache.searchHistory.removeAt(index);
|
||||
|
@ -188,7 +188,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
width: 40.0,
|
||||
child: IconButton(
|
||||
splashRadius: 20.0,
|
||||
icon: Icon(Icons.clear),
|
||||
icon: Icon(Icons.clear, semanticLabel: "Clear".i18n,),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_suggestions = [];
|
||||
|
@ -311,7 +311,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
data,
|
||||
onTap: () {
|
||||
List<Track> queue = cache.searchHistory.where((h) => h.type == SearchHistoryItemType.TRACK).map<Track>((t) => t.data).toList();
|
||||
playerHelper.playFromTrackList(queue, queue.first.id, QueueSource(
|
||||
playerHelper.playFromTrackList(queue, data.id, QueueSource(
|
||||
text: 'Search history'.i18n,
|
||||
source: 'searchhistory',
|
||||
id: 'searchhistory'
|
||||
|
@ -723,7 +723,7 @@ class SearchResultsScreen extends StatelessWidget {
|
|||
return ShowEpisodeTile(
|
||||
e,
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.more_vert),
|
||||
icon: Icon(Icons.more_vert, semanticLabel: "Options".i18n,),
|
||||
onPressed: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultShowEpisodeMenu(e.show, e);
|
||||
|
@ -907,7 +907,7 @@ class EpisodeListScreen extends StatelessWidget {
|
|||
return ShowEpisodeTile(
|
||||
e,
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.more_vert),
|
||||
icon: Icon(Icons.more_vert, semanticLabel: "Options".i18n,),
|
||||
onPressed: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultShowEpisodeMenu(e.show, e);
|
||||
|
|
|
@ -1226,8 +1226,8 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
|||
if (settings.lastFMPassword != null && settings.lastFMUsername != null) {
|
||||
settings.lastFMUsername = null;
|
||||
settings.lastFMPassword = null;
|
||||
playerHelper.scrobblenaut = null;
|
||||
await settings.save();
|
||||
await AudioService.customAction("disableLastFM");
|
||||
setState(() {});
|
||||
Fluttertoast.showToast(msg: 'Logged out!'.i18n);
|
||||
return;
|
||||
|
@ -1352,7 +1352,7 @@ class _LastFMLoginState extends State<LastFMLogin> {
|
|||
settings.lastFMUsername = last.username;
|
||||
settings.lastFMPassword = last.passwordHash;
|
||||
await settings.save();
|
||||
playerHelper.scrobblenaut = Scrobblenaut(lastFM: last);
|
||||
await playerHelper.authorizeLastFM();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
|
@ -1396,7 +1396,7 @@ class _DirectoryPickerState extends State<DirectoryPicker> {
|
|||
'Pick-a-Path'.i18n,
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.sd_card),
|
||||
icon: Icon(Icons.sd_card, semanticLabel: 'Select storage'.i18n,),
|
||||
onPressed: () {
|
||||
String path = '';
|
||||
//Chose storage
|
||||
|
|
104
pubspec.lock
104
pubspec.lock
|
@ -21,14 +21,14 @@ packages:
|
|||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.1"
|
||||
async:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.6.1"
|
||||
audio_service:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -63,14 +63,14 @@ packages:
|
|||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
version: "0.4.6"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
version: "2.1.10"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -84,28 +84,28 @@ packages:
|
|||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.11.5"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.7"
|
||||
version: "6.1.10"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "5.1.0"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "8.1.0"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -140,14 +140,14 @@ packages:
|
|||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "0.3.1"
|
||||
clipboard:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: clipboard
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+8"
|
||||
version: "0.1.3"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -161,7 +161,7 @@ packages:
|
|||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.6.0"
|
||||
version: "3.7.0"
|
||||
collection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -310,14 +310,14 @@ packages:
|
|||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "1.1.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.0"
|
||||
version: "6.1.2"
|
||||
filesize:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -331,7 +331,7 @@ packages:
|
|||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "1.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -371,7 +371,7 @@ packages:
|
|||
name: flutter_isolate
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0+14"
|
||||
version: "1.0.0+15"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -442,7 +442,7 @@ packages:
|
|||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.1"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -505,7 +505,7 @@ packages:
|
|||
name: infinite_listview
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1+1"
|
||||
version: "1.1.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -519,7 +519,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
version: "0.3.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -568,14 +568,14 @@ packages:
|
|||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
marquee:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: marquee
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.1"
|
||||
version: "1.7.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -603,21 +603,7 @@ packages:
|
|||
name: move_to_background
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.0.2"
|
||||
numberpicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -645,7 +631,7 @@ packages:
|
|||
name: open_file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.2.1"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -715,7 +701,7 @@ packages:
|
|||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.2"
|
||||
version: "1.11.1"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -764,28 +750,28 @@ packages:
|
|||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.5.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.2.1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.7"
|
||||
version: "0.1.8"
|
||||
quick_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -820,7 +806,7 @@ packages:
|
|||
name: scrobblenaut
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
share:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -841,7 +827,7 @@ packages:
|
|||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4"
|
||||
version: "0.2.4+1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -853,14 +839,14 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+1"
|
||||
version: "0.9.10+3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.1"
|
||||
spotify:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -881,14 +867,14 @@ packages:
|
|||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2+3"
|
||||
version: "1.3.2+4"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3+1"
|
||||
version: "1.0.3+3"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -909,7 +895,7 @@ packages:
|
|||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -937,7 +923,7 @@ packages:
|
|||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
version: "0.3.0"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -959,6 +945,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: universal_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1021,7 +1014,7 @@ packages:
|
|||
name: version
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
wakelock:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1049,7 +1042,7 @@ packages:
|
|||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1077,7 +1070,14 @@ packages:
|
|||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.1.0"
|
||||
zone_local:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: zone_local
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.22.2"
|
||||
|
|
|
@ -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.11+1
|
||||
version: 0.6.12+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.8.0 <3.0.0"
|
||||
|
|
Loading…
Reference in New Issue