add horizontal-list support + ui improvements

This commit is contained in:
Pato05 2024-04-29 00:33:32 +02:00
parent 55e7a5e7e3
commit f7283a6633
No known key found for this signature in database
GPG Key ID: F53CA394104BA0CB
12 changed files with 392 additions and 221 deletions

View File

@ -990,17 +990,17 @@ class HomePageSection {
'grid-preview-two': HomePageSectionLayout.row,
'grid': HomePageSectionLayout.grid,
'slideshow': HomePageSectionLayout.slideshow,
'horizontal-list': HomePageSectionLayout.horizontalList
}[json['layout'] ?? ''];
if (layout == null) {
_logger.warning('UNKNOWN LAYOUT: ${json['layout']}');
return null;
}
_logger.fine('LAYOUT: $layout');
final items = <HomePageItem>[];
for (var i in (json['items'] ?? [])) {
HomePageItem? hpi = HomePageItem.fromPrivateJson(i);
if (hpi != null) items.add(hpi);
}
_logger.fine(json['title']);
final items = ((json['items'] ?? []) as List)
.map((e) => HomePageItem.fromPrivateJson(e as Map))
.whereNotNull()
.toList(growable: false);
return HomePageSection(
title: json['title'],
items: items,
@ -1044,10 +1044,6 @@ class HomePageItem {
return HomePageItem(
type: HomePageItemType.ARTIST,
value: Artist.fromPrivateJson(json['data']));
case 'channel':
return HomePageItem(
type: HomePageItemType.CHANNEL,
value: DeezerChannel.fromPrivateJson(json, false));
case 'album':
return HomePageItem(
type: HomePageItemType.ALBUM,
@ -1056,10 +1052,18 @@ class HomePageItem {
return HomePageItem(
type: HomePageItemType.SHOW,
value: Show.fromPrivateJson(json['data']));
case 'channel':
return HomePageItem(
type: HomePageItemType.CHANNEL,
value: DeezerChannel.fromPrivateJson(json, false));
case 'external-link':
return HomePageItem(
type: HomePageItemType.EXTERNAL_LINK,
value: DeezerChannel.fromPrivateJson(json, true));
case 'track':
return HomePageItem(
type: HomePageItemType.TRACK,
value: Track.fromPrivateJson(json['data']));
default:
return null;
}
@ -1101,9 +1105,13 @@ class HomePageItem {
}
Map<String, dynamic> toJson() {
String type = describeEnum(this.type);
String type = this.type.name;
return {'type': type, 'value': value.toJson()};
}
String toString() {
return type.name;
}
}
@HiveType(typeId: 14)
@ -1181,6 +1189,9 @@ enum HomePageItemType {
@HiveField(6)
EXTERNAL_LINK,
@HiveField(7)
TRACK, // for track mixes
}
@HiveType(typeId: 3)
@ -1193,6 +1204,10 @@ enum HomePageSectionLayout {
/// ROW but bigger
@HiveField(2)
slideshow,
/// Homepage song radios
@HiveField(3)
horizontalList,
}
enum RepeatType { NONE, LIST, TRACK }

View File

@ -255,7 +255,7 @@ class AudioPlayerTask extends BaseAudioHandler {
// listen for connectivity changes
_subscriptions.add(Connectivity()
.onConnectivityChanged
.listen(_determineAudioQualityByResult));
.listen(_determineAudioQualityByResults));
}
if (shouldLoadQueue) {
@ -271,7 +271,7 @@ class AudioPlayerTask extends BaseAudioHandler {
try {
await Connectivity()
.checkConnectivity()
.then(_determineAudioQualityByResult);
.then(_determineAudioQualityByResults);
return true;
} catch (e) {
_isConnectivityPluginAvailable = false;
@ -282,12 +282,13 @@ class AudioPlayerTask extends BaseAudioHandler {
_logger.warning(
'Couldn\'t determine connection! Falling back to other (which may use wifi quality)');
// on error, return dummy value -- error can happen on linux if not using NetworkManager, for example
_determineAudioQualityByResult(ConnectivityResult.other);
_determineAudioQualityByResults([ConnectivityResult.other]);
return false;
}
/// Determines the [AudioQuality] to use according to [result]
void _determineAudioQualityByResult(ConnectivityResult result) {
void _determineAudioQualityByResults(List<ConnectivityResult> results) {
final result = results[0];
switch (result) {
case ConnectivityResult.mobile:
case ConnectivityResult.bluetooth:

View File

@ -31,7 +31,7 @@ import 'package:freezer/ui/search.dart';
import 'package:freezer/ui/settings_screen.dart';
import 'package:get_it/get_it.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:i18n_extension/i18n_extension.dart';
import 'package:logging/logging.dart';
import 'package:freezer/translations.i18n.dart';
import 'package:quick_actions/quick_actions.dart';
@ -287,14 +287,15 @@ class _LoginMainWrapperState extends State<LoginMainWrapper> {
super.initState();
}
Future _logOut() async {
Future<void> _logOut() async {
await GetIt.instance<DeezerAPI>().logout();
setState(() {
settings.arl = null;
settings.offlineMode = false;
});
settings.arl = null;
settings.offlineMode = false;
await settings.save();
await Cache.wipe();
setState(() {});
}
@override

View File

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -210,7 +211,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
return HomePageGridSection(section);
case HomePageSectionLayout.slideshow:
case HomePageSectionLayout.row:
default:
case HomePageSectionLayout.horizontalList:
return HomepageRowSection(section);
}
}
@ -243,72 +244,70 @@ class _HomePageWidgetState extends State<HomePageWidget> {
}
}
class HomepageRowSection extends StatefulWidget {
class HomepageRowSection extends StatelessWidget {
final HomePageSection section;
const HomepageRowSection(this.section, {super.key});
@override
State<HomepageRowSection> createState() => _HomepageRowSectionState();
}
Widget buildChild(BuildContext context, List<HomePageItem> items) {
return Row(
children: items
.map((item) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0),
child: HomePageItemWidget(item),
))
.toList(growable: false));
}
class _HomepageRowSectionState extends State<HomepageRowSection> {
final _controller = ScrollController();
List<List<T>> _sliceInNLists<T>(List<T> source, int n) {
final List<List<T>> dest = List.generate(n, (_) => [], growable: false);
@override
void dispose() {
_controller.dispose();
super.dispose();
int i = 0;
for (var item in source) {
dest[i].add(item);
if (++i == n) i = 0;
}
return dest;
}
@override
Widget build(BuildContext context) {
final Widget child = switch (section.layout) {
HomePageSectionLayout.horizontalList => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: _sliceInNLists(section.items!, 3)
.map((e) => buildChild(context, e))
.toList(growable: false)),
_ => buildChild(context, section.items!)
};
return ListTile(
title: Text(
widget.section.title ?? '',
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w900),
title: Text(
section.title ?? '',
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w900),
),
subtitle: Scrollbar(
thickness: MainScreen.of(context).isDesktop ? null : 1.0,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: child,
),
subtitle: Scrollbar(
controller: _controller,
thickness: MainScreen.of(context).isDesktop ? null : 1.0,
child: SingleChildScrollView(
controller: _controller,
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(widget.section.items!.length + 1, (j) {
//Has more items
if (j == widget.section.items!.length) {
if (widget.section.hasMore ?? false) {
return TextButton(
child: Text(
'Show more'.i18n,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
),
onPressed: () => Navigator.of(context).pushRoute(
builder: (context) => HomePageScreen(
title: widget.section.title!,
channel:
DeezerChannel(target: widget.section.pagePath),
),
),
);
}
return const SizedBox();
}
//Show item
HomePageItem item = widget.section.items![j];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0),
child: HomePageItemWidget(item),
);
}),
),
),
));
),
trailing: section.hasMore == true
? const Icon(Icons.keyboard_arrow_right)
: null,
onTap: section.hasMore == true
? () => Navigator.of(context).pushRoute(
builder: (context) => HomePageScreen(
title: section.title!,
channel: DeezerChannel(target: section.pagePath),
),
)
: null,
);
}
}
@ -368,6 +367,7 @@ class HomePageItemWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
switch (item.type) {
case HomePageItemType.SMARTTRACKLIST:
return SmartTrackListTile(
@ -444,6 +444,16 @@ class HomePageItemWidget extends StatelessWidget {
.pushRoute(builder: (context) => ShowScreen(item.value));
},
);
case HomePageItemType.TRACK:
final track = item.value as Track;
return TrackCardTile.fromTrack(
track,
onTap: () => playerHelper.playSearchMixDeferred(track),
onSecondary: (details) =>
MenuSheet(context).defaultTrackMenu(track, details: details),
width:
mediaQuery.size.width > 530 ? null : mediaQuery.size.width * 0.75,
);
default:
return const SizedBox(height: 0, width: 0);
}

View File

@ -293,7 +293,8 @@ class _LibraryTracksState extends State<LibraryTracks> {
return;
}
ConnectivityResult connectivity = await Connectivity().checkConnectivity();
ConnectivityResult connectivity =
(await Connectivity().checkConnectivity())[0];
if (connectivity != ConnectivityResult.none) {
setState(() => _loading = true);
int pos = tracks.length;

View File

@ -96,7 +96,6 @@ class _LoginOnOtherDeviceState extends State<LoginOnOtherDevice> {
}
}
print(res);
final data = res.data as Map;
if (!data['ok']) {
setState(() {

View File

@ -20,68 +20,71 @@ import 'package:url_launcher/url_launcher.dart';
class SliverTrackPersistentHeader extends SliverPersistentHeaderDelegate {
final Track track;
final double extent;
const SliverTrackPersistentHeader(this.track, {required this.extent});
static const kExtent = 84.0 + 16.0 * 2 + 2.0;
const SliverTrackPersistentHeader(this.track);
@override
bool shouldRebuild(oldDelegate) => false;
@override
double get maxExtent => extent;
double get maxExtent => kExtent;
@override
double get minExtent => extent;
double get minExtent => kExtent;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return DecoratedBox(
decoration: BoxDecoration(color: Theme.of(context).cardColor),
decoration:
BoxDecoration(color: Theme.of(context).colorScheme.background),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16.0),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(width: 16.0),
Semantics(
label: "Album art".i18n,
image: true,
child: CachedImage(
url: track.albumArt!.full,
height: 128,
width: 128,
height: 86.0,
width: 86.0,
),
),
SizedBox(
width: 240.0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
track.title!,
maxLines: 1,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 22.0, fontWeight: FontWeight.bold),
),
Text(
track.artistString,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: const TextStyle(fontSize: 20.0),
),
const SizedBox(height: 8.0),
Text(
track.album!.title!,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Text(track.durationString)
],
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
track.title!,
maxLines: 1,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
track.album!.title!,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Text(
track.artistString,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
),
],
@ -202,6 +205,7 @@ class MenuSheet {
builder: (context, scrollController) => Material(
type: MaterialType.card,
clipBehavior: Clip.antiAlias,
color: Theme.of(context).colorScheme.background,
borderRadius:
const BorderRadius.vertical(top: Radius.circular(20.0)),
child: SafeArea(
@ -210,8 +214,7 @@ class MenuSheet {
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: SliverTrackPersistentHeader(track,
extent: 128.0 + 16.0 + 16.0)),
delegate: SliverTrackPersistentHeader(track)),
SliverList(
delegate: SliverChildListDelegate.fixed(options
.map((option) => ListTile(

View File

@ -369,10 +369,7 @@ class PlayerScreenDesktop extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: PlayerScreenTopRow(
textSize: 12.h,
iconSize: 21.h,
showQueueButton: false,
),
textSize: 12.h, iconSize: 21.h, desktopMode: true),
),
Flexible(
child: ConstrainedBox(
@ -1049,7 +1046,7 @@ class _BigAlbumArtState extends State<BigAlbumArt> with WidgetsBindingObserver {
right: 16.0,
child: LyricsButton(
onTap: _pushLyrics,
size: constraints.maxHeight / 20,
size: 20.spMax,
),
);
},
@ -1121,14 +1118,15 @@ class PlayerScreenTopRow extends StatelessWidget {
final double? iconSize;
final double? textWidth;
final bool short;
final bool showQueueButton; // not needed on desktop
const PlayerScreenTopRow(
{super.key,
this.textSize,
this.iconSize,
this.textWidth,
this.short = false,
this.showQueueButton = true});
final bool desktopMode;
const PlayerScreenTopRow({
super.key,
this.textSize,
this.iconSize,
this.textWidth,
this.short = false,
this.desktopMode = false,
});
@override
Widget build(BuildContext context) {
@ -1175,20 +1173,9 @@ class PlayerScreenTopRow extends StatelessWidget {
.copyWith(fontSize: textSize ?? 38.sp)));
}),
),
showQueueButton
? IconButton(
icon: Icon(
Icons.menu,
semanticLabel: "Queue".i18n,
),
iconSize: size,
splashRadius: size * 1.5,
onPressed: () => Navigator.of(context).pushRoute(
builder: (ctx) => QueueScreen(
closePlayer: FancyScaffold.of(context)!.closePanel,
)),
)
: SizedBox.square(dimension: size + 16.0),
desktopMode
? PlayerMenuButtonDesktop(size: size)
: PlayerMenuButton(size: size)
],
);
}
@ -1329,7 +1316,19 @@ class BottomBarControls extends StatelessWidget {
textSize: size * 0.75,
),
const Expanded(child: SizedBox()),
PlayerMenuButton(size: size),
if (!desktopMode)
IconButton(
icon: Icon(
Icons.playlist_play,
semanticLabel: "Queue".i18n,
),
iconSize: size,
splashRadius: size * 1.5,
onPressed: () => Navigator.of(context).pushRoute(
builder: (ctx) => QueueScreen(
closePlayer: FancyScaffold.of(context)!.closePanel,
)),
),
],
);
}
@ -1371,9 +1370,19 @@ class BottomBarControls extends StatelessWidget {
// toastLength: Toast.LENGTH_SHORT);
// },
// ),
desktopMode
? PlayerMenuButtonDesktop(size: iconSize)
: PlayerMenuButton(size: iconSize)
if (!desktopMode)
IconButton(
icon: Icon(
Icons.playlist_play,
semanticLabel: "Queue".i18n,
),
iconSize: size,
splashRadius: size * 1.5,
onPressed: () => Navigator.of(context).pushRoute(
builder: (ctx) => QueueScreen(
closePlayer: FancyScaffold.of(context)!.closePanel,
)),
),
],
);
}

View File

@ -23,6 +23,102 @@ VoidCallback? normalizeSecondary(SecondaryTapCallback? callback) {
return () => callback.call(null);
}
class TrackCardTile extends StatelessWidget {
static const _kDefaultWidth = 424.0;
final VoidCallback onTap;
/// Hold or Right Click
final SecondaryTapCallback? onSecondary;
final Widget? trailing;
final String trackId;
final String title;
final String artist;
final String artUri;
final bool explicit;
final double? width;
const TrackCardTile({
required this.trackId,
required this.title,
required this.artist,
required this.artUri,
required this.explicit,
required this.onTap,
this.onSecondary,
this.trailing,
this.width,
super.key,
});
factory TrackCardTile.fromTrack(
Track track, {
required VoidCallback onTap,
SecondaryTapCallback? onSecondary,
Widget? trailing,
double? width,
}) =>
TrackCardTile(
trackId: track.id,
title: track.title!,
artist: track.artistString,
artUri: track.albumArt!.thumb,
explicit: track.explicit ?? false,
onSecondary: onSecondary,
onTap: onTap,
width: width,
trailing: trailing,
);
@override
Widget build(BuildContext context) {
return SizedBox(
width: width ?? _kDefaultWidth,
height: 64.0,
child: Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: onTap,
onLongPress: normalizeSecondary(onSecondary),
onSecondaryTapUp: onSecondary,
child: Row(mainAxisSize: MainAxisSize.min, children: [
CachedImage(url: artUri),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, overflow: TextOverflow.ellipsis, maxLines: 1),
Text(
artist,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(color: Theme.of(context).disabledColor),
)
]),
),
),
]),
),
),
);
ListTile(
title: Text(title),
subtitle: Text(artist),
leading: Stack(
children: [CachedImage(url: artUri), PlayItemButton(onTap: onTap)],
),
contentPadding: const EdgeInsets.only(left: 16.0, right: 124.0),
onTap: onTap,
);
}
}
class TrackTile extends StatelessWidget {
final VoidCallback? onTap;
@ -399,21 +495,34 @@ class PlaylistCardTile extends StatelessWidget {
class PlayItemButton extends StatelessWidget {
final FutureOr<void> Function() onTap;
final double size;
const PlayItemButton({required this.onTap, this.size = 32.0, super.key});
final bool filled;
const PlayItemButton({
required this.onTap,
this.size = 32.0,
this.filled = true,
super.key,
});
@override
Widget build(BuildContext context) {
return SizedBox.square(
dimension: size,
child: DecoratedBox(
decoration: const BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
decoration: filled
? const BoxDecoration(
shape: BoxShape.circle, color: Colors.white)
: const BoxDecoration(),
child: Center(
child: AwaitingButton(
onTap: onTap,
child: Icon(
Icons.play_arrow,
color: Colors.black,
color: filled ? Colors.black : Colors.white,
shadows: filled
? null
: const [
Shadow(blurRadius: 2.0, color: Colors.black)
],
size: size / 1.5,
)))));
}

View File

@ -26,7 +26,7 @@ import window_manager
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin"))
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))

View File

@ -5,26 +5,26 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
url: "https://pub.dev"
source: hosted
version: "61.0.0"
version: "67.0.0"
analyzer:
dependency: "direct dev"
description:
name: analyzer
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
url: "https://pub.dev"
source: hosted
version: "5.13.0"
version: "6.4.1"
archive:
dependency: transitive
description:
name: archive
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
sha256: "0763b45fa9294197a2885c8567927e2830ade852e5c896fd4ab7e0e348d0f373"
url: "https://pub.dev"
source: hosted
version: "3.4.10"
version: "3.5.0"
args:
dependency: transitive
description:
@ -229,18 +229,18 @@ packages:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0"
sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "6.0.3"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
sha256: b6a56efe1e6675be240de39107281d4034b64ac23438026355b4234042a35adb
url: "https://pub.dev"
source: hosted
version: "1.2.4"
version: "2.0.0"
convert:
dependency: transitive
description:
@ -269,10 +269,10 @@ packages:
dependency: transitive
description:
name: cross_file
sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
url: "https://pub.dev"
source: hosted
version: "0.3.3+8"
version: "0.3.4+1"
crypto:
dependency: "direct main"
description:
@ -475,10 +475,10 @@ packages:
dependency: "direct main"
description:
name: flutter_cache_manager
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
sha256: "395d6b7831f21f3b989ebedbb785545932adb9afe2622c1ffacf7f4b53a7e544"
url: "https://pub.dev"
source: hosted
version: "3.3.1"
version: "3.3.2"
flutter_cache_manager_hive:
dependency: "direct main"
description:
@ -508,10 +508,10 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: "55b9b229307a10974b26296ff29f2e132256ba4bd74266939118eaefa941cb00"
sha256: "8cdc719114ab1c86c64bb7a86d3a679674c3637edd229e3a994797d4a1504ce4"
url: "https://pub.dev"
source: hosted
version: "16.3.3"
version: "17.1.0"
flutter_local_notifications_linux:
dependency: transitive
description:
@ -683,10 +683,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.2.1"
http_multi_server:
dependency: transitive
description:
@ -707,10 +707,18 @@ packages:
dependency: "direct main"
description:
name: i18n_extension
sha256: "813da89a434e617e3065a5d729f148a4d2d93d227e4d1ed4e77660eda6fa58c2"
sha256: "514fca4f34e8eb73cd29d2938225bf139b1ff3cede462c0b2875f60f470e64b2"
url: "https://pub.dev"
source: hosted
version: "10.0.3"
version: "11.0.12"
i18n_extension_core:
dependency: transitive
description:
name: i18n_extension_core
sha256: f45157bcd04d4fd88811e8e7c104a66ffbf77d16a6cf8526197c30cb78cbf1c4
url: "https://pub.dev"
source: hosted
version: "2.0.6"
i18n_extension_importer:
dependency: "direct main"
description:
@ -755,26 +763,26 @@ packages:
dependency: "direct main"
description:
name: isar
sha256: "99165dadb2cf2329d3140198363a7e7bff9bbd441871898a87e26914d25cf1ea"
url: "https://pub.dev"
sha256: "01de08cdea6e2060987e75bdedea46f244d9657fcd0e73b4372d6309b0e60f73"
url: "https://pub.isar-community.dev"
source: hosted
version: "3.1.0+1"
version: "3.1.6"
isar_flutter_libs:
dependency: "direct main"
description:
name: isar_flutter_libs
sha256: bc6768cc4b9c61aabff77152e7f33b4b17d2fc93134f7af1c3dd51500fe8d5e8
url: "https://pub.dev"
sha256: "268ef3fa93f213096f34e8f7f91ad16d920b33631fbdae317f3eb29f90e95b85"
url: "https://pub.isar-community.dev"
source: hosted
version: "3.1.0+1"
version: "3.1.6"
isar_generator:
dependency: "direct dev"
description:
name: isar_generator
sha256: "76c121e1295a30423604f2f819bc255bc79f852f3bc8743a24017df6068ad133"
url: "https://pub.dev"
sha256: d2bbd77573c60ae1eddc323a20020223ba161e5a06e84143ea659411fb73b574
url: "https://pub.isar-community.dev"
source: hosted
version: "3.1.0+1"
version: "3.1.6"
js:
dependency: transitive
description:
@ -943,6 +951,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
mini_music_visualizer:
dependency: "direct main"
description:
name: mini_music_visualizer
sha256: "095b3c5e12f4c045544432829a044a7fe1c5a7789a6d0003347c73d9bf3170cc"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
move_to_background:
dependency: "direct main"
description:
@ -963,18 +979,18 @@ packages:
dependency: "direct main"
description:
name: network_info_plus
sha256: "4601b815b1c6a46d84839f65cd774a7d999738471d910fae00d813e9e98b04e1"
sha256: "5bd4b86e28fed5ed4e6ac7764133c031dfb7d3f46aa2a81b46f55038aa78ecc0"
url: "https://pub.dev"
source: hosted
version: "4.1.0+1"
version: "5.0.3"
network_info_plus_platform_interface:
dependency: transitive
description:
name: network_info_plus_platform_interface
sha256: "881f5029c5edaf19c616c201d3d8b366c5b1384afd5c1da5a49e4345de82fb8b"
sha256: "2e193d61d3072ac17824638793d3b89c6d581ce90c11604f4ca87311b42f2706"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
version: "2.0.0"
nm:
dependency: transitive
description:
@ -1027,18 +1043,18 @@ packages:
dependency: "direct main"
description:
name: package_info_plus
sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
sha256: "2c582551839386fa7ddbc7770658be7c0f87f388a4bff72066478f597c34d17f"
url: "https://pub.dev"
source: hosted
version: "5.0.1"
version: "7.0.0"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "3.0.0"
palette_generator:
dependency: "direct main"
description:
@ -1171,10 +1187,10 @@ packages:
dependency: "direct main"
description:
name: photo_view
sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb"
sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e"
url: "https://pub.dev"
source: hosted
version: "0.14.0"
version: "0.15.0"
platform:
dependency: transitive
description:
@ -1308,18 +1324,18 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900"
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
url: "https://pub.dev"
source: hosted
version: "7.2.2"
version: "9.0.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496"
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
url: "https://pub.dev"
source: hosted
version: "3.4.0"
version: "4.0.0"
shelf:
dependency: transitive
description:
@ -1377,10 +1393,10 @@ packages:
dependency: "direct main"
description:
name: spotify
sha256: "50bd5a07b580ee441d0b4d81227185ada768332c353671aa7555ea47cc68eb9e"
sha256: d8effb9fa14731fe98fc5d111e0e1a0aac27b34366b5dcb8db79e6dd2219c000
url: "https://pub.dev"
source: hosted
version: "0.13.5"
version: "0.13.6+1"
sprintf:
dependency: transitive
description:
@ -1601,10 +1617,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.3.1"
url_launcher_windows:
dependency: transitive
description:
@ -1649,10 +1665,10 @@ packages:
dependency: "direct main"
description:
name: wakelock_plus
sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d
sha256: c8b7cc80f045533b40a0e6c9109905494e3cf32c0fbd5c62616998e0de44003f
url: "https://pub.dev"
source: hosted
version: "1.1.4"
version: "1.2.4"
wakelock_plus_platform_interface:
dependency: transitive
description:
@ -1673,18 +1689,18 @@ packages:
dependency: transitive
description:
name: web
sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev"
source: hosted
version: "0.4.2"
version: "0.5.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23"
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
url: "https://pub.dev"
source: hosted
version: "2.4.3"
version: "2.4.5"
webview_flutter:
dependency: "direct main"
description:

View File

@ -35,45 +35,45 @@ dependencies:
path: ^1.6.4
sqflite: ^2.0.0+3
permission_handler: ^11.2.0
intl: ^0.18.0
intl: ^0.18.1
filesize: ^2.0.1
fluttertoast: ^8.0.8
palette_generator: ^0.3.0
flutter_material_color_picker: ^1.0.5
country_pickers: ^2.0.0
move_to_background: ^1.0.1
flutter_local_notifications: ^16.3.2
flutter_local_notifications: ^17.1.0
collection: ^1.17.1
random_string: ^2.0.1
async: ^2.6.1
html: ^0.15.0
flutter_screenutil: ^5.0.0+2
marquee: ^2.2.0
flutter_cache_manager: ^3.0.0
flutter_cache_manager: ^3.3.2
cached_network_image: ^3.1.0
i18n_extension: ^10.0.3
i18n_extension: ^11.0.12
url_launcher: ^6.0.5
uni_links: ^0.5.1
numberpicker: ^2.1.1
quick_actions: ^1.0.5
photo_view: ^0.14.0
photo_view: ^0.15.0
scrobblenaut:
git:
url: https://github.com/Pato05/Scrobblenaut.git
ref: main
open_file: ^3.0.3
version: ^3.0.2
wakelock_plus: ^1.1.1
wakelock_plus: ^1.2.4
google_fonts: ^6.1.0
audio_session: ^0.1.6
audio_service: ^0.18.1
provider: ^6.0.0
hive_flutter: ^1.1.0
connectivity_plus: ^5.0.2
share_plus: ^7.0.2
connectivity_plus: ^6.0.3
share_plus: ^9.0.0
disk_space_plus: ^0.2.3
dynamic_color: ^1.6.6
package_info_plus: ^5.0.1
package_info_plus: ^7.0.0
encrypt: ^5.0.1
dart_blowfish:
git:
@ -93,8 +93,12 @@ dependencies:
audio_service_mpris: ^0.1.3
rxdart: ^0.27.7
isar: ^3.1.0+1
isar_flutter_libs: ^3.1.0+1
isar:
hosted: https://pub.isar-community.dev
version: ^3.1.6
isar_flutter_libs:
hosted: https://pub.isar-community.dev
version: ^3.1.6
flutter_background_service: ^5.0.1
dio: ^5.3.3
dio_cookie_manager: ^3.1.1
@ -102,7 +106,7 @@ dependencies:
git: https://github.com/Pato05/flutter_cache_manager_hive.git
flex_color_picker: ^3.3.0
webview_flutter: ^4.4.4
network_info_plus: ^4.1.0+1
network_info_plus: ^5.0.3
pointycastle: ^3.7.4
i18n_extension_importer: ^0.0.6
tray_manager: ^0.2.1
@ -110,18 +114,21 @@ dependencies:
get_it: ^7.6.7
freezed_annotation:
^2.4.1
mini_music_visualizer: ^1.1.0
#deezcryptor:
#path: deezcryptor/
dev_dependencies:
flutter_test:
sdk: flutter
analyzer: ^5.13.0
analyzer: ^6.4.1
json_serializable: ^6.0.1
build_runner: ^2.4.6
hive_generator: ^2.0.0
flutter_lints: ^3.0.1
isar_generator: ^3.1.0+1
isar_generator:
hosted: https://pub.isar-community.dev
version: ^3.1.0
freezed: ^2.4.7
# For information on the generic Dart part of this file, see the