0.5.8 - queue reordering, bug and ui fixes, shortcut icon
@ -293,6 +293,7 @@ public class Deezer {
|
||||
isFlac = false;
|
||||
}
|
||||
Tag tag = f.getTag();
|
||||
tag.setEncoding("utf-8");
|
||||
|
||||
tag.setField(FieldKey.TITLE, publicTrack.getString("title"));
|
||||
tag.setField(FieldKey.ALBUM, publicTrack.getJSONObject("album").getString("title"));
|
||||
|
74
android/app/src/main/res/drawable/ic_flow_background.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
android:height="108dp"
|
||||
android:width="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
</vector>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_favorites_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_favorites_foreground"/>
|
||||
</adaptive-icon>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_favorites_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_favorites_foreground"/>
|
||||
</adaptive-icon>
|
5
android/app/src/main/res/mipmap-anydpi-v26/ic_flow.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_flow_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_flow_foreground"/>
|
||||
</adaptive-icon>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_flow_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_flow_foreground"/>
|
||||
</adaptive-icon>
|
BIN
android/app/src/main/res/mipmap-hdpi/ic_favorites_foreground.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_favorites_round.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_flow_foreground.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_flow_round.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_favorites_foreground.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_favorites_round.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_flow_foreground.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_flow_round.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 7.9 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_favorites_round.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_flow_foreground.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_flow_round.png
Normal file
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 15 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_favorites_round.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_flow_foreground.png
Normal file
After Width: | Height: | Size: 124 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_flow_round.png
Normal file
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 23 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_favorites_round.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_flow_foreground.png
Normal file
After Width: | Height: | Size: 156 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_flow_round.png
Normal file
After Width: | Height: | Size: 47 KiB |
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_favorites_background">#3DDC84</color>
|
||||
</resources>
|
@ -49,6 +49,9 @@ class Cache {
|
||||
@JsonKey(ignore: true)
|
||||
StreamSubscription sleepTimer;
|
||||
|
||||
@JsonKey(defaultValue: const [])
|
||||
List<String> searchHistory;
|
||||
|
||||
//If download threads warning was shown
|
||||
@JsonKey(defaultValue: false)
|
||||
bool threadsWarning;
|
||||
|
@ -31,6 +31,8 @@ Cache _$CacheFromJson(Map<String, dynamic> json) {
|
||||
PlaylistSortType.DEFAULT
|
||||
..trackSort = _$enumDecodeNullable(_$SortTypeEnumMap, json['trackSort']) ??
|
||||
SortType.DEFAULT
|
||||
..searchHistory =
|
||||
(json['searchHistory'] as List)?.map((e) => e as String)?.toList() ?? []
|
||||
..threadsWarning = json['threadsWarning'] as bool ?? false;
|
||||
}
|
||||
|
||||
@ -44,6 +46,7 @@ Map<String, dynamic> _$CacheToJson(Cache instance) => <String, dynamic>{
|
||||
'libraryPlaylistSort':
|
||||
_$PlaylistSortTypeEnumMap[instance.libraryPlaylistSort],
|
||||
'trackSort': _$SortTypeEnumMap[instance.trackSort],
|
||||
'searchHistory': instance.searchHistory,
|
||||
'threadsWarning': instance.threadsWarning,
|
||||
};
|
||||
|
||||
|
@ -221,7 +221,7 @@ class PlayerHelper {
|
||||
QueueSource queueSource = QueueSource(
|
||||
id: stl.id,
|
||||
source: (stl.id == 'flow')?'flow':'smarttracklist',
|
||||
text: stl.title
|
||||
text: stl.title??(stl.id == 'flow')?'Flow'.i18n:'Smart track list'.i18n
|
||||
);
|
||||
await playFromTrackList(stl.tracks, stl.tracks[0].id, queueSource);
|
||||
}
|
||||
@ -233,6 +233,11 @@ class PlayerHelper {
|
||||
await AudioService.customAction('queueSource', queueSource.toJson());
|
||||
}
|
||||
|
||||
//Reorder tracks in queue
|
||||
Future reorder(int oldIndex, int newIndex) async {
|
||||
await AudioService.customAction('reorder', [oldIndex, newIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void backgroundTaskEntrypoint() async {
|
||||
@ -562,6 +567,18 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||
if (name == 'screenAndroidAuto' && _androidAutoCallback != null) {
|
||||
_androidAutoCallback.complete(jsonDecode(args).map<MediaItem>((m) => MediaItem.fromJson(m)).toList());
|
||||
}
|
||||
//Reorder tracks, args = [old, new]
|
||||
if (name == 'reorder') {
|
||||
await _audioSource.move(args[0], args[1]);
|
||||
//Switch in queue
|
||||
List<MediaItem> newQueue = List.from(_queue);
|
||||
newQueue.removeAt(args[0]);
|
||||
newQueue.insert(args[1], _queue[args[0]]);
|
||||
_queue = newQueue;
|
||||
//Update UI
|
||||
AudioServiceBackground.setQueue(_queue);
|
||||
_broadcastState();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -245,6 +245,9 @@ const language_en_us = {
|
||||
"Minutes:": "Minutes:",
|
||||
"Hours:": "Hours:",
|
||||
"Cancel current timer": "Cancel current timer",
|
||||
"Current timer ends at": "Current timer ends at"
|
||||
"Current timer ends at": "Current timer ends at",
|
||||
|
||||
//0.5.8 Strings:
|
||||
"Smart track list": "Smart track list"
|
||||
}
|
||||
};
|
||||
|
@ -14,6 +14,7 @@ import 'package:freezer/ui/search.dart';
|
||||
import 'package:i18n_extension/i18n_widget.dart';
|
||||
import 'package:move_to_background/move_to_background.dart';
|
||||
import 'package:freezer/translations.i18n.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
|
||||
import 'api/deezer.dart';
|
||||
@ -51,6 +52,7 @@ class _FreezerAppState extends State<FreezerApp> {
|
||||
void initState() {
|
||||
//Make update theme global
|
||||
updateTheme = _updateTheme;
|
||||
_updateTheme();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -63,6 +65,9 @@ class _FreezerAppState extends State<FreezerApp> {
|
||||
setState(() {
|
||||
settings.themeData;
|
||||
});
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: settings.themeData.bottomAppBarColor,
|
||||
));
|
||||
}
|
||||
|
||||
Locale _locale() {
|
||||
@ -158,28 +163,47 @@ class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateM
|
||||
void initState() {
|
||||
navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
//Setup URLs
|
||||
setupUniLinks();
|
||||
|
||||
//Start with parameters
|
||||
_setupUniLinks();
|
||||
_loadPreloadInfo();
|
||||
_prepareQuickActions();
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _prepareQuickActions() {
|
||||
final QuickActions quickActions = QuickActions();
|
||||
quickActions.initialize((type) {
|
||||
if (type != null)
|
||||
_startPreload(type);
|
||||
});
|
||||
|
||||
//Actions
|
||||
quickActions.setShortcutItems([
|
||||
ShortcutItem(type: 'favorites', localizedTitle: 'Favorites'.i18n, icon: 'ic_favorites'),
|
||||
ShortcutItem(type: 'flow', localizedTitle: 'Flow'.i18n, icon: 'ic_flow'),
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
void _startPreload(String type) async {
|
||||
await deezerAPI.authorize();
|
||||
if (type == 'flow') {
|
||||
await playerHelper.playFromSmartTrackList(SmartTrackList(id: 'flow'));
|
||||
return;
|
||||
}
|
||||
if (type == 'favorites') {
|
||||
Playlist p = await deezerAPI.fullPlaylist(deezerAPI.favoritesPlaylistId);
|
||||
playerHelper.playFromPlaylist(p, p.tracks[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
void _loadPreloadInfo() async {
|
||||
String info = await DownloadManager.platform.invokeMethod('getPreloadInfo');
|
||||
if (info != null) {
|
||||
//Used if started from android auto
|
||||
|
||||
await deezerAPI.authorize();
|
||||
if (info == 'flow') {
|
||||
await playerHelper.playFromSmartTrackList(SmartTrackList(id: 'flow'));
|
||||
return;
|
||||
}
|
||||
if (info == 'favorites') {
|
||||
Playlist p = await deezerAPI.fullPlaylist(deezerAPI.favoritesPlaylistId);
|
||||
playerHelper.playFromPlaylist(p, p.tracks[0].id);
|
||||
}
|
||||
_startPreload(info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +214,7 @@ class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateM
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void setupUniLinks() async {
|
||||
void _setupUniLinks() async {
|
||||
//Listen to URLs
|
||||
_urlLinkStream = getUriLinksStream().listen((Uri uri) {
|
||||
openScreenByURL(context, uri.toString());
|
||||
|
@ -560,6 +560,7 @@ class _SleepTimerDialogState extends State<SleepTimerDialog> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezer/settings.dart';
|
||||
|
||||
import '../api/player.dart';
|
||||
@ -46,7 +47,12 @@ class PlayerBar extends StatelessWidget {
|
||||
Container(
|
||||
color: Theme.of(context).bottomAppBarColor,
|
||||
child: ListTile(
|
||||
onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => PlayerScreen())),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => PlayerScreen()));
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: settings.themeData.scaffoldBackgroundColor,
|
||||
));
|
||||
},
|
||||
leading: CachedImage(
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
@ -1,8 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/screenutil.dart';
|
||||
import 'package:freezer/api/deezer.dart';
|
||||
import 'package:freezer/api/player.dart';
|
||||
import 'package:freezer/settings.dart';
|
||||
import 'package:freezer/translations.i18n.dart';
|
||||
import 'package:freezer/ui/menu.dart';
|
||||
import 'package:freezer/ui/settings_screen.dart';
|
||||
@ -25,6 +27,13 @@ class PlayerScreen extends StatefulWidget {
|
||||
|
||||
class _PlayerScreenState extends State<PlayerScreen> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: settings.themeData.bottomAppBarColor,
|
||||
));
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -578,7 +587,7 @@ class PlayerScreenTopRow extends StatelessWidget {
|
||||
Container(
|
||||
width: this.textWidth??ScreenUtil().setWidth(550),
|
||||
child: Text(
|
||||
(short??false)?playerHelper.queueSource.text:'Playing from:'.i18n + ' ' + playerHelper.queueSource.text,
|
||||
(short??false)?(playerHelper.queueSource.text??''):'Playing from:'.i18n + ' ' + (playerHelper.queueSource.text??''),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.left,
|
||||
@ -779,9 +788,13 @@ class _QueueScreenState extends State<QueueScreen> {
|
||||
)
|
||||
],
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: AudioService.queue.length,
|
||||
itemBuilder: (context, i) {
|
||||
body: ReorderableListView(
|
||||
onReorder: (int oldIndex, int newIndex) async {
|
||||
if (oldIndex == playerHelper.queueIndex) return;
|
||||
await playerHelper.reorder(oldIndex, newIndex);
|
||||
setState(() {});
|
||||
},
|
||||
children: List.generate(AudioService.queue.length, (int i) {
|
||||
Track t = Track.fromMediaItem(AudioService.queue[i]);
|
||||
return TrackTile(
|
||||
t,
|
||||
@ -789,12 +802,9 @@ class _QueueScreenState extends State<QueueScreen> {
|
||||
await AudioService.playFromMediaId(t.id);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onHold: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultTrackMenu(t);
|
||||
},
|
||||
key: Key(t.id),
|
||||
);
|
||||
},
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:connectivity/connectivity.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezer/api/cache.dart';
|
||||
import 'package:freezer/api/download.dart';
|
||||
import 'package:freezer/api/player.dart';
|
||||
import 'package:freezer/ui/details_screens.dart';
|
||||
@ -63,6 +64,10 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
//Add to search history
|
||||
try {cache.searchHistory.remove(_query);} catch (_) {}
|
||||
cache.searchHistory.add(_query);
|
||||
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => SearchResultsScreen(_query, offline: _offline,))
|
||||
);
|
||||
@ -158,6 +163,19 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||
if (_loading)
|
||||
LinearProgressIndicator(),
|
||||
Divider(),
|
||||
|
||||
//History
|
||||
if (cache.searchHistory.length > 0 && (_query??'').length == 0)
|
||||
...List.generate(cache.searchHistory.length > 10 ? 10 : cache.searchHistory.length, (int i) => ListTile(
|
||||
title: Text(cache.searchHistory[i]),
|
||||
leading: Icon(Icons.history),
|
||||
onTap: () {
|
||||
setState(() => _query = cache.searchHistory[i]);
|
||||
_submit(context);
|
||||
},
|
||||
)),
|
||||
|
||||
//Suggestions
|
||||
...List.generate((_suggestions??[]).length, (i) => ListTile(
|
||||
title: Text(_suggestions[i]),
|
||||
leading: Icon(Icons.search),
|
||||
|
@ -714,6 +714,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
quick_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: quick_actions
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0+10"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -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.5.7+1
|
||||
version: 0.5.8+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.8.0 <3.0.0"
|
||||
@ -69,6 +69,7 @@ dependencies:
|
||||
uni_links: ^0.4.0
|
||||
share: ^0.6.5+2
|
||||
numberpicker: ^1.2.1
|
||||
quick_actions: ^0.4.0+10
|
||||
|
||||
audio_session: ^0.0.9
|
||||
audio_service:
|
||||
|