diff --git a/lib/app/view/master_detail_page.dart b/lib/app/view/master_detail_page.dart index 649149ed9..956cee4e3 100644 --- a/lib/app/view/master_detail_page.dart +++ b/lib/app/view/master_detail_page.dart @@ -54,7 +54,7 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin { ? masterScaffoldKey.currentState?.closeEndDrawer : masterScaffoldKey.currentState?.closeDrawer, icon: Icon( - Iconz().close, + Iconz.close, ), ), ), @@ -198,7 +198,7 @@ List createMasterItems({required LibraryModel libraryModel}) { MasterItem( titleBuilder: (context) => Text(context.l10n.search), pageBuilder: (_) => const SearchPage(), - iconBuilder: (_) => Icon(Iconz().search), + iconBuilder: (_) => Icon(Iconz.search), pageId: kSearchPageId, ), MasterItem( @@ -226,7 +226,7 @@ List createMasterItems({required LibraryModel libraryModel}) { pageId: kPodcastsPageId, ), MasterItem( - iconBuilder: (selected) => Icon(Iconz().plus), + iconBuilder: (selected) => Icon(Iconz.plus), titleBuilder: (context) => Text(context.l10n.add), pageBuilder: (_) => const SizedBox.shrink(), pageId: kNewPlaylistPageId, @@ -247,7 +247,7 @@ List createMasterItems({required LibraryModel libraryModel}) { iconBuilder: (selected) => SideBarFallBackImage( color: getAlphabetColor(playlist.key), child: Icon( - Iconz().playlist, + Iconz.playlist, ), ), ), diff --git a/lib/app/view/master_tile.dart b/lib/app/view/master_tile.dart index 498a95e9d..9791271be 100644 --- a/lib/app/view/master_tile.dart +++ b/lib/app/view/master_tile.dart @@ -162,9 +162,7 @@ class __PlayAbleMasterTileState extends State<_PlayAbleMasterTile> { child: IconButton( onPressed: onPlay, icon: Icon( - isPlaying && isEnQueued - ? Iconz().pause - : Iconz().playFilled, + isPlaying && isEnQueued ? Iconz.pause : Iconz.playFilled, size: kTinyButtonIconSize, color: context.t.colorScheme.primary, ), diff --git a/lib/app/view/splash_screen.dart b/lib/app/view/splash_screen.dart index 30b0176a8..fa0eeb3e8 100644 --- a/lib/app/view/splash_screen.dart +++ b/lib/app/view/splash_screen.dart @@ -29,7 +29,7 @@ class SplashScreen extends StatelessWidget { borderRadius: BorderRadius.circular(30), ), child: Icon( - Iconz().musicNote, + Iconz.musicNote, size: 150, color: Colors.white, ), diff --git a/lib/common/data/audio.dart b/lib/common/data/audio.dart index 5f4e434cd..5fa997e86 100644 --- a/lib/common/data/audio.dart +++ b/lib/common/data/audio.dart @@ -39,7 +39,7 @@ class Audio { /// The artist(s) of the audio file or stream, for radio stations this is the language. final String? artist; - /// The album of the audio file or stream. + /// The album of the audio file or stream, for radio stations these are the tags. final String? album; /// The album artist(s) of the audio file or stream, for radio stations this is the codec. @@ -264,7 +264,7 @@ class Audio { if (other.audioType != null && other.audioType == AudioType.radio && audioType == AudioType.radio) { - return other.description == description; + return other.uuid == uuid; } return (other.url != null && other.url == url) || @@ -275,7 +275,7 @@ class Audio { } @override - int get hashCode => path.hashCode ^ url.hashCode ^ description.hashCode; + int get hashCode => path.hashCode ^ url.hashCode ^ uuid.hashCode; factory Audio.fromMetadata({ required String path, @@ -311,12 +311,19 @@ class Audio { } String? get uuid => description; - String? get language => artist; + String get language => artist ?? ''; + int get clicks => discTotal ?? 0; + int get bitRate => fileSize ?? 0; + List? get tags => album?.isNotEmpty == false + ? null + : [ + for (final tag in album?.split(',') ?? []) tag, + ]; factory Audio.fromStation(Station station) { return Audio( url: station.urlResolved, - title: station.name, + title: station.name.trim(), artist: station.language, album: station.tags ?? '', audioType: AudioType.radio, @@ -325,6 +332,7 @@ class Audio { description: station.stationUUID, fileSize: station.bitrate, albumArtist: station.codec, + discTotal: station.clickCount, ); } @@ -360,12 +368,6 @@ class Audio { return id; } - List? get tags => album?.isNotEmpty == false - ? null - : [ - for (final tag in album?.split(',') ?? []) tag, - ]; - bool get hasPathAndId => albumId?.isNotEmpty == true && path != null && diff --git a/lib/common/view/animated_like_icon.dart b/lib/common/view/animated_like_icon.dart new file mode 100644 index 000000000..6ae8c10cd --- /dev/null +++ b/lib/common/view/animated_like_icon.dart @@ -0,0 +1,67 @@ +import 'icons.dart'; +import 'package:flutter/material.dart'; +import 'package:yaru/yaru.dart'; +import 'theme.dart'; + +class AnimatedStar extends StatelessWidget { + const AnimatedStar({ + super.key, + required this.isStarred, + this.color, + }); + + final bool isStarred; + final Color? color; + + @override + Widget build(BuildContext context) { + if (yaruStyled) { + return YaruAnimatedVectorIcon( + isStarred ? YaruAnimatedIcons.star_filled : YaruAnimatedIcons.star, + initialProgress: 1.0, + color: color, + size: iconSize, + ); + } else { + return isStarred + ? Icon( + Iconz.starFilled, + size: iconSize, + color: isStarred ? color : null, + ) + : Icon( + Iconz.star, + size: iconSize, + color: isStarred ? color : null, + ); + } + } +} + +class AnimatedHeart extends StatelessWidget { + const AnimatedHeart({ + super.key, + required this.liked, + this.color, + }); + + final bool liked; + final Color? color; + + @override + Widget build(BuildContext context) { + if (yaruStyled) { + return YaruAnimatedVectorIcon( + liked ? YaruAnimatedIcons.heart_filled : YaruAnimatedIcons.heart, + initialProgress: 1.0, + color: color, + size: iconSize, + ); + } else { + return Icon( + liked ? Icons.favorite : Icons.favorite_outline, + color: color, + ); + } + } +} diff --git a/lib/common/view/audio_card.dart b/lib/common/view/audio_card.dart index eb44bea65..104ecb754 100644 --- a/lib/common/view/audio_card.dart +++ b/lib/common/view/audio_card.dart @@ -83,7 +83,7 @@ class _AudioCardState extends State { ? const EdgeInsets.only(left: 3) : EdgeInsets.zero, child: Icon( - Iconz().playFilled, + Iconz.playFilled, color: contrastColor(theme.colorScheme.primary), ), ), diff --git a/lib/common/view/audio_tile.dart b/lib/common/view/audio_tile.dart index 3fe668735..58e9879fe 100644 --- a/lib/common/view/audio_tile.dart +++ b/lib/common/view/audio_tile.dart @@ -54,6 +54,7 @@ class _AudioTileState extends State { @override Widget build(BuildContext context) { final theme = context.t; + final l10n = context.l10n; final playerModel = di(); final liked = watchPropertyValue((LibraryModel m) => m.liked(widget.audio)); final starred = watchPropertyValue( @@ -61,10 +62,9 @@ class _AudioTileState extends State { ); final selectedColor = widget.selectedColor ?? theme.contrastyPrimary; final subTitle = switch (widget.audioPageType) { - AudioPageType.artist => widget.audio.album ?? context.l10n.unknown, - AudioPageType.radioSearch => - '${widget.audio.artist ?? context.l10n.unknown}, ${widget.audio.albumArtist ?? ''}, ${widget.audio.fileSize ?? ''} kbps', - _ => widget.audio.artist ?? context.l10n.unknown, + AudioPageType.artist => widget.audio.album ?? l10n.unknown, + AudioPageType.radioSearch => _buildRadioSubTitle(widget.audio, l10n), + _ => widget.audio.artist ?? l10n.unknown, }; var leading = !widget.showLeading @@ -112,7 +112,7 @@ class _AudioTileState extends State { title: Padding( padding: const EdgeInsets.only(right: kYaruPagePadding), child: Text( - widget.audio.title ?? context.l10n.unknown, + widget.audio.title ?? l10n.unknown, overflow: TextOverflow.ellipsis, maxLines: 1, ), @@ -137,6 +137,12 @@ class _AudioTileState extends State { ), ); } + + String _buildRadioSubTitle( + Audio audio, + AppLocalizations l10n, + ) => + '${audio.albumArtist?.isNotEmpty == true ? '${audio.albumArtist}' : ''}${audio.bitRate > 0 ? ' • ${audio.fileSize} kbps' : ''}${audio.clicks > 0 ? ' • ${audio.clicks} ${l10n.clicks}' : ''}${audio.language.trim().isNotEmpty ? ' • ${audio.language}' : ''}'; } class _AudioTileTrail extends StatelessWidget with WatchItMixin { diff --git a/lib/common/view/audio_tile_image.dart b/lib/common/view/audio_tile_image.dart index c69e4a610..8452a32d7 100644 --- a/lib/common/view/audio_tile_image.dart +++ b/lib/common/view/audio_tile_image.dart @@ -19,9 +19,9 @@ class AudioTileImage extends StatelessWidget { Widget build(BuildContext context) { final icon = Icon( switch (audio?.audioType) { - AudioType.radio => Iconz().radio, - AudioType.podcast => Iconz().podcast, - _ => Iconz().musicNote, + AudioType.radio => Iconz.radio, + AudioType.podcast => Iconz.podcast, + _ => Iconz.musicNote, }, size: size / (1.65), ); diff --git a/lib/common/view/audio_tile_option_button.dart b/lib/common/view/audio_tile_option_button.dart index 388a47e98..0b54892d7 100644 --- a/lib/common/view/audio_tile_option_button.dart +++ b/lib/common/view/audio_tile_option_button.dart @@ -51,7 +51,7 @@ class AudioTileOptionButton extends StatelessWidget { ); }, child: YaruTile( - leading: Icon(Iconz().insertIntoQueue), + leading: Icon(Iconz.insertIntoQueue), title: Text(context.l10n.playNext), ), ), @@ -61,7 +61,7 @@ class AudioTileOptionButton extends StatelessWidget { onTap: () => libraryModel.removeAudioFromPlaylist(playlistId, audio), child: YaruTile( - leading: Icon(Iconz().remove), + leading: Icon(Iconz.remove), title: Text('${context.l10n.removeFrom} $playlistId'), ), ), @@ -77,7 +77,7 @@ class AudioTileOptionButton extends StatelessWidget { }, ), child: YaruTile( - leading: Icon(Iconz().plus), + leading: Icon(Iconz.plus), title: Text( '${context.l10n.addToPlaylist} ...', ), @@ -91,7 +91,7 @@ class AudioTileOptionButton extends StatelessWidget { }, ), child: YaruTile( - leading: Icon(Iconz().info), + leading: Icon(Iconz.info), title: Text( '${context.l10n.showMetaData} ...', ), @@ -117,7 +117,7 @@ class AudioTileOptionButton extends StatelessWidget { ), ]; }, - icon: Icon(Iconz().viewMore), + icon: Icon(Iconz.viewMore), ); } } @@ -129,39 +129,44 @@ class MetaDataDialog extends StatelessWidget { @override Widget build(BuildContext context) { + final radio = audio.audioType == AudioType.radio; + final items = <(String, String)>{ ( - context.l10n.title, + radio ? context.l10n.stationName : context.l10n.title, '${audio.title}', ), ( - context.l10n.album, - '${audio.album}', + radio ? context.l10n.tags : context.l10n.album, + '${radio ? audio.album?.replaceAll(',', ', ') : audio.album}', ), ( - context.l10n.artist, - '${audio.artist}', + radio ? context.l10n.language : context.l10n.artist, + '${radio ? audio.language : audio.artist}', ), ( - context.l10n.albumArtists, + radio ? context.l10n.quality : context.l10n.albumArtists, '${audio.albumArtist}', ), + if (!radio) + ( + context.l10n.trackNumber, + '${audio.trackNumber}', + ), + if (!radio) + ( + context.l10n.diskNumber, + '${audio.discNumber}', + ), ( - context.l10n.trackNumber, - '${audio.trackNumber}', - ), - ( - context.l10n.diskNumber, - '${audio.discNumber}', - ), - ( - context.l10n.totalDisks, - '${audio.discTotal}', - ), - ( - context.l10n.genre, - '${audio.genre}', + radio ? context.l10n.clicks : context.l10n.totalDisks, + '${radio ? audio.clicks : audio.discTotal}', ), + if (!radio) + ( + context.l10n.genre, + '${audio.genre}', + ), ( context.l10n.url, (audio.url ?? ''), diff --git a/lib/common/view/avatar_play_button.dart b/lib/common/view/avatar_play_button.dart index 91c2994cc..36b78ae63 100644 --- a/lib/common/view/avatar_play_button.dart +++ b/lib/common/view/avatar_play_button.dart @@ -27,7 +27,7 @@ class AvatarPlayButton extends StatelessWidget with WatchItMixin { (PlayerModel m) => m.queueName != null && m.queueName == pageId, ); final iconData = - isPlayerPlaying && pageIsQueue ? Iconz().pause : Iconz().playFilled; + isPlayerPlaying && pageIsQueue ? Iconz.pause : Iconz.playFilled; return Padding( padding: bigPlayButtonPadding, diff --git a/lib/common/view/back_gesture.dart b/lib/common/view/back_gesture.dart index 9d448c1e6..b035c70f0 100644 --- a/lib/common/view/back_gesture.dart +++ b/lib/common/view/back_gesture.dart @@ -128,7 +128,7 @@ class _BackGestureState extends State BorderRadius.circular(_kButtonSize), ), ), - child: Icon(Iconz().goBack), + child: Icon(Iconz.goBack), ), ), ), diff --git a/lib/common/view/country_auto_complete.dart b/lib/common/view/country_auto_complete.dart index 1bbdb95a4..675efd5d4 100644 --- a/lib/common/view/country_auto_complete.dart +++ b/lib/common/view/country_auto_complete.dart @@ -239,7 +239,7 @@ class _CountryTile extends StatelessWidget { favs?.contains(t.code) == false ? addFav(t) : removeFav(t); }, icon: Icon( - favs?.contains(t.code) == true ? Iconz().starFilled : Iconz().star, + favs?.contains(t.code) == true ? Iconz.starFilled : Iconz.star, ), ), ); diff --git a/lib/common/view/explore_online_popup.dart b/lib/common/view/explore_online_popup.dart index 0d55c1ca9..ffbacb17c 100644 --- a/lib/common/view/explore_online_popup.dart +++ b/lib/common/view/explore_online_popup.dart @@ -32,7 +32,7 @@ class ExploreOnlinePopup extends StatelessWidget with WatchItMixin { ), ), ], - icon: Icon(Iconz().explore), + icon: Icon(Iconz.explore), ); } } diff --git a/lib/common/view/header_bar.dart b/lib/common/view/header_bar.dart index 068cc3bb1..66a20a18c 100644 --- a/lib/common/view/header_bar.dart +++ b/lib/common/view/header_bar.dart @@ -204,10 +204,10 @@ class SidebarButton extends StatelessWidget { masterScaffoldKey.currentState?.openDrawer(); } }, - icon: Iconz().sidebar == Iconz().materialSidebar - ? Transform.flip(flipX: true, child: Icon(Iconz().materialSidebar)) + icon: Iconz.sidebar == Iconz.materialSidebar + ? Transform.flip(flipX: true, child: Icon(Iconz.materialSidebar)) : Icon( - Iconz().sidebar, + Iconz.sidebar, size: iconSize, ), ), diff --git a/lib/common/view/icons.dart b/lib/common/view/icons.dart index 81c1fefe6..4b8001592 100644 --- a/lib/common/view/icons.dart +++ b/lib/common/view/icons.dart @@ -1,18 +1,17 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_tabler_icons/flutter_tabler_icons.dart'; import 'package:yaru/yaru.dart'; -import '../../extensions/build_context_x.dart'; import 'theme.dart'; class Iconz { - static final Iconz _instance = Iconz._internal(); - factory Iconz() => _instance; - - Iconz._internal(); + static IconData get warning => yaruStyled + ? YaruIcons.warning_filled + : appleStyled + ? CupertinoIcons.exclamationmark_triangle_fill + : Icons.warning_rounded; - IconData get menu { + static IconData get menu { return yaruStyled ? YaruIcons.menu : appleStyled @@ -20,9 +19,9 @@ class Iconz { : Icons.menu_rounded; } - IconData get materialSidebar => Icons.view_sidebar_rounded; + static IconData get materialSidebar => Icons.view_sidebar_rounded; - IconData get sidebar { + static IconData get sidebar { return yaruStyled ? YaruIcons.sidebar : appleStyled @@ -30,7 +29,7 @@ class Iconz { : materialSidebar; } - IconData get updateAvailable { + static IconData get updateAvailable { return yaruStyled ? YaruIcons.update_available : appleStyled @@ -38,7 +37,7 @@ class Iconz { : Icons.arrow_circle_up_rounded; } - IconData get remove { + static IconData get remove { return yaruStyled ? YaruIcons.minus : appleStyled @@ -46,84 +45,84 @@ class Iconz { : Icons.remove_rounded; } - IconData get check => yaruStyled + static IconData get check => yaruStyled ? YaruIcons.checkmark : appleStyled ? CupertinoIcons.check_mark : Icons.check_rounded; - IconData get musicNote => yaruStyled + static IconData get musicNote => yaruStyled ? YaruIcons.music_note : appleStyled ? CupertinoIcons.double_music_note : Icons.music_note_rounded; - IconData get external => yaruStyled + static IconData get external => yaruStyled ? YaruIcons.external_link : appleStyled ? CupertinoIcons.link : Icons.link_rounded; - IconData get starFilled => yaruStyled + static IconData get starFilled => yaruStyled ? YaruIcons.star_filled : appleStyled ? CupertinoIcons.star_fill : Icons.star_rounded; - IconData get star => yaruStyled + static IconData get star => yaruStyled ? YaruIcons.star : appleStyled ? CupertinoIcons.star : Icons.star_outline_rounded; - IconData get offline => yaruStyled + static IconData get offline => yaruStyled ? YaruIcons.network_offline : appleStyled ? CupertinoIcons.wifi_slash : Icons.offline_bolt_rounded; - IconData get cloud => yaruStyled + static IconData get cloud => yaruStyled ? YaruIcons.cloud : appleStyled ? CupertinoIcons.cloud : Icons.cloud_outlined; - IconData get pause => yaruStyled + static IconData get pause => yaruStyled ? YaruIcons.media_pause : appleStyled ? CupertinoIcons.pause : Icons.pause_rounded; - IconData get playFilled => yaruStyled + static IconData get playFilled => yaruStyled ? YaruIcons.media_play : appleStyled ? CupertinoIcons.play_fill : Icons.play_arrow_rounded; - IconData get download => yaruStyled + static IconData get download => yaruStyled ? YaruIcons.download : appleStyled ? CupertinoIcons.down_arrow : Icons.download_outlined; - IconData get downloadFilled => yaruStyled + static IconData get downloadFilled => yaruStyled ? YaruIcons.download_filled : appleStyled ? CupertinoIcons.down_arrow : Icons.download_rounded; - IconData get podcast => yaruStyled + static IconData get podcast => yaruStyled ? YaruIcons.podcast : appleStyled ? CupertinoIcons.mic : Icons.podcasts_outlined; - IconData get podcastFilled => yaruStyled + static IconData get podcastFilled => yaruStyled ? YaruIcons.podcast_filled : appleStyled ? CupertinoIcons.mic_fill : Icons.podcasts_rounded; - IconData get radio => yaruStyled + static IconData get radio => yaruStyled ? YaruIcons.radio : appleStyled ? CupertinoIcons.antenna_radiowaves_left_right : Icons.radio_outlined; - IconData get radioFilled => yaruStyled + static IconData get radioFilled => yaruStyled ? YaruIcons.radio_filled : appleStyled ? CupertinoIcons.antenna_radiowaves_left_right : Icons.radio_rounded; - IconData get localAudio { + static IconData get localAudio { if (appleStyled) { if (isMobile) { return CupertinoIcons.device_phone_portrait; @@ -137,7 +136,7 @@ class Iconz { : Icons.computer_rounded; } - IconData get localAudioFilled { + static IconData get localAudioFilled { if (appleStyled) { if (isMobile) { return CupertinoIcons.device_phone_portrait; @@ -151,7 +150,7 @@ class Iconz { : Icons.computer_rounded; } - IconData get copy { + static IconData get copy { return yaruStyled ? YaruIcons.copy : appleStyled @@ -159,7 +158,7 @@ class Iconz { : Icons.copy_rounded; } - IconData get explore { + static IconData get explore { return yaruStyled ? YaruIcons.compass : appleStyled @@ -167,7 +166,7 @@ class Iconz { : Icons.explore_rounded; } - IconData get drag { + static IconData get drag { if (appleStyled) { return CupertinoIcons.move; } @@ -177,193 +176,193 @@ class Iconz { return Icons.drag_handle_rounded; } - IconData get settings => yaruStyled + static IconData get settings => yaruStyled ? YaruIcons.settings : appleStyled ? CupertinoIcons.settings : Icons.settings_rounded; - IconData get addToLibrary => yaruStyled + static IconData get addToLibrary => yaruStyled ? YaruIcons.bell : appleStyled ? CupertinoIcons.bell : Icons.notifications_outlined; - IconData get removeFromLibrary => yaruStyled + static IconData get removeFromLibrary => yaruStyled ? YaruIcons.bell_filled : appleStyled ? CupertinoIcons.bell_fill : Icons.notifications_rounded; - IconData get refresh => yaruStyled + static IconData get refresh => yaruStyled ? YaruIcons.refresh : appleStyled ? CupertinoIcons.refresh : Icons.refresh_rounded; - IconData get replay => yaruStyled + static IconData get replay => yaruStyled ? YaruIcons.history : appleStyled ? CupertinoIcons.clock : Icons.history_rounded; - IconData get speakerLowFilled => yaruStyled + static IconData get speakerLowFilled => yaruStyled ? YaruIcons.speaker_low_filled : appleStyled ? CupertinoIcons.volume_off : Icons.volume_down_rounded; - IconData get speakerMediumFilled => yaruStyled + static IconData get speakerMediumFilled => yaruStyled ? YaruIcons.speaker_medium_filled : appleStyled ? CupertinoIcons.volume_down : Icons.volume_down_rounded; - IconData get speakerHighFilled => yaruStyled + static IconData get speakerHighFilled => yaruStyled ? YaruIcons.speaker_high_filled : appleStyled ? CupertinoIcons.volume_up : Icons.volume_up_rounded; - IconData get speakerMutedFilled => yaruStyled + static IconData get speakerMutedFilled => yaruStyled ? YaruIcons.speaker_muted_filled : appleStyled ? CupertinoIcons.volume_off : Icons.volume_off_rounded; - IconData get fullWindowExit => yaruStyled + static IconData get fullWindowExit => yaruStyled ? YaruIcons.arrow_down : appleStyled ? CupertinoIcons.arrow_down : Icons.arrow_downward_rounded; - IconData get fullWindow => yaruStyled + static IconData get fullWindow => yaruStyled ? YaruIcons.arrow_up : appleStyled ? CupertinoIcons.arrow_up : Icons.arrow_upward_rounded; - IconData get fullScreenExit => yaruStyled + static IconData get fullScreenExit => yaruStyled ? YaruIcons.fullscreen_exit : appleStyled ? CupertinoIcons.fullscreen_exit : Icons.fullscreen_exit_rounded; - IconData get fullScreen => yaruStyled + static IconData get fullScreen => yaruStyled ? YaruIcons.fullscreen : appleStyled ? CupertinoIcons.fullscreen : Icons.fullscreen_rounded; - IconData get repeatSingle => yaruStyled + static IconData get repeatSingle => yaruStyled ? YaruIcons.repeat_single : appleStyled ? CupertinoIcons.repeat_1 : Icons.repeat_one_rounded; - IconData get shuffle => yaruStyled + static IconData get shuffle => yaruStyled ? YaruIcons.shuffle : appleStyled ? CupertinoIcons.shuffle : Icons.shuffle_rounded; - IconData get levelMiddle => yaruStyled + static IconData get levelMiddle => yaruStyled ? YaruIcons.meter_middle : appleStyled ? CupertinoIcons.speedometer : Icons.speed_rounded; - IconData get levelHigh => yaruStyled + static IconData get levelHigh => yaruStyled ? YaruIcons.meter_three_quarter : appleStyled ? CupertinoIcons.speedometer : Icons.speed_rounded; - IconData get levelLow => yaruStyled + static IconData get levelLow => yaruStyled ? YaruIcons.meter_quarter : appleStyled ? CupertinoIcons.speedometer : Icons.speed_rounded; - IconData get skipBackward => yaruStyled + static IconData get skipBackward => yaruStyled ? YaruIcons.skip_backward : appleStyled ? CupertinoIcons.backward_end : Icons.skip_previous_rounded; - IconData get skipForward => yaruStyled + static IconData get skipForward => yaruStyled ? YaruIcons.skip_forward : appleStyled ? CupertinoIcons.forward_end : Icons.skip_next_rounded; - IconData get goBack => yaruStyled + static IconData get goBack => yaruStyled ? YaruIcons.go_previous : appleStyled ? CupertinoIcons.back : Icons.arrow_back_rounded; - IconData get goNext => yaruStyled + static IconData get goNext => yaruStyled ? YaruIcons.go_next : appleStyled ? CupertinoIcons.forward : Icons.arrow_forward_rounded; - IconData get forward30 => yaruStyled + static IconData get forward30 => yaruStyled ? YaruIcons.redo : appleStyled ? CupertinoIcons.goforward_30 : Icons.forward_30_rounded; - IconData get backward10 => yaruStyled + static IconData get backward10 => yaruStyled ? YaruIcons.undo : appleStyled ? CupertinoIcons.gobackward_10 : Icons.replay_10_rounded; - IconData get goUp => yaruStyled + static IconData get goUp => yaruStyled ? YaruIcons.go_up : appleStyled ? CupertinoIcons.up_arrow : Icons.arrow_upward_rounded; - IconData get share => yaruStyled + static IconData get share => yaruStyled ? YaruIcons.share : appleStyled ? CupertinoIcons.share : Icons.share; - IconData get startPlayList => yaruStyled + static IconData get startPlayList => yaruStyled ? YaruIcons.playlist_play : appleStyled ? CupertinoIcons.play_circle : Icons.playlist_play_rounded; - IconData get playlist => yaruStyled + static IconData get playlist => yaruStyled ? YaruIcons.playlist : appleStyled ? CupertinoIcons.music_note_list : Icons.list_rounded; - IconData get pen => yaruStyled + static IconData get pen => yaruStyled ? YaruIcons.pen : appleStyled ? CupertinoIcons.pen : Icons.edit_rounded; - IconData get pin => yaruStyled + static IconData get pin => yaruStyled ? YaruIcons.pin : appleStyled ? CupertinoIcons.pin : Icons.push_pin_outlined; - IconData get pinFilled => yaruStyled + static IconData get pinFilled => yaruStyled ? YaruIcons.pin : appleStyled ? CupertinoIcons.pin_fill : Icons.push_pin_rounded; - IconData get heart => yaruStyled + static IconData get heart => yaruStyled ? YaruIcons.heart : appleStyled ? CupertinoIcons.heart : Icons.favorite_outline_rounded; - IconData get heartFilled => yaruStyled + static IconData get heartFilled => yaruStyled ? YaruIcons.heart_filled : appleStyled ? CupertinoIcons.heart_fill : Icons.favorite_rounded; - IconData get globe => yaruStyled + static IconData get globe => yaruStyled ? YaruIcons.globe : appleStyled ? CupertinoIcons.globe : Icons.link_rounded; - IconData get imageMissing => yaruStyled + static IconData get imageMissing => yaruStyled ? YaruIcons.image_missing : appleStyled ? CupertinoIcons.question_diamond : Icons.image_not_supported_outlined; - IconData get imageMissingFilled => yaruStyled + static IconData get imageMissingFilled => yaruStyled ? YaruIcons.image_missing_filled : appleStyled ? CupertinoIcons.question_diamond_fill : Icons.image_not_supported_rounded; - IconData get plus => yaruStyled + static IconData get plus => yaruStyled ? YaruIcons.plus : appleStyled ? CupertinoIcons.plus : Icons.add_rounded; - IconData get search => yaruStyled + static IconData get search => yaruStyled ? YaruIcons.search : appleStyled ? CupertinoIcons.search @@ -373,150 +372,61 @@ class Iconz { : appleStyled ? CupertinoIcons.clear : Icons.clear_rounded; - IconData get viewMore => yaruStyled + static IconData get viewMore => yaruStyled ? YaruIcons.view_more : appleStyled ? CupertinoIcons.ellipsis_vertical : Icons.more_vert_rounded; - IconData? get close => yaruStyled + static IconData get close => yaruStyled ? YaruIcons.window_close : appleStyled ? CupertinoIcons.clear : Icons.clear_rounded; - IconData get list => yaruStyled + static IconData get list => yaruStyled ? YaruIcons.unordered_list : appleStyled ? CupertinoIcons.list_bullet : Icons.list_rounded; - IconData get grid => yaruStyled + static IconData get grid => yaruStyled ? YaruIcons.app_grid : appleStyled ? CupertinoIcons.square_grid_3x2_fill : Icons.grid_on_rounded; - IconData get move => yaruStyled + static IconData get move => yaruStyled ? YaruIcons.ordered_list : appleStyled ? CupertinoIcons.move : Icons.move_down_rounded; - IconData get materialAscending => Icons.sort_rounded; - IconData get ascending => yaruStyled + static IconData get materialAscending => Icons.sort_rounded; + static IconData get ascending => yaruStyled ? YaruIcons.sort_ascending : appleStyled ? CupertinoIcons.sort_up : materialAscending; - IconData get descending => yaruStyled + static IconData get descending => yaruStyled ? YaruIcons.sort_descending : appleStyled ? CupertinoIcons.sort_down : Icons.sort_rounded; - IconData get info => yaruStyled + static IconData get info => yaruStyled ? YaruIcons.information : appleStyled ? CupertinoIcons.info : Icons.info_rounded; - IconData get clearAll => yaruStyled + static IconData get clearAll => yaruStyled ? YaruIcons.edit_clear_all : appleStyled ? CupertinoIcons.paintbrush : Icons.cleaning_services_rounded; - IconData get insertIntoQueue => yaruStyled + static IconData get insertIntoQueue => yaruStyled ? YaruIcons.music_queue : appleStyled ? CupertinoIcons.plus_app : Icons.queue_rounded; - IconData get sleep => yaruStyled + static IconData get sleep => yaruStyled ? YaruIcons.clear_night : appleStyled ? CupertinoIcons.moon : Icons.mode_night_rounded; - - Widget getAnimatedStar(bool isStarred, [Color? color]) { - if (yaruStyled) { - return YaruAnimatedVectorIcon( - isStarred ? YaruAnimatedIcons.star_filled : YaruAnimatedIcons.star, - initialProgress: 1.0, - color: color, - size: iconSize, - ); - } else { - return isStarred - ? Icon( - Iconz().starFilled, - size: iconSize, - color: isStarred ? color : null, - ) - : Icon( - Iconz().star, - size: iconSize, - color: isStarred ? color : null, - ); - } - } - - Widget getAnimatedHeartIcon({required bool liked, Color? color}) { - if (yaruStyled) { - return YaruAnimatedVectorIcon( - liked ? YaruAnimatedIcons.heart_filled : YaruAnimatedIcons.heart, - initialProgress: 1.0, - color: color, - size: iconSize, - ); - } else { - return Icon( - liked ? Icons.favorite : Icons.favorite_outline, - color: color, - ); - } - } -} - -double get sideBarImageSize => 38; - -double get iconSize => yaruStyled - ? kYaruIconSize - : isMobile - ? 24.0 - : 20.0; - -IconData getIconForTag(String tag) { - final tagsToIcons = { - 'metal': TablerIcons.guitar_pick, - 'pop': TablerIcons.diamond, - }; - - return tagsToIcons[tag] ?? - (yaruStyled - ? YaruIcons.music_note - : appleStyled - ? CupertinoIcons.double_music_note - : Icons.music_note); -} - -class DisconnectedServerIcon extends StatelessWidget { - const DisconnectedServerIcon({super.key}); - - @override - Widget build(BuildContext context) { - final theme = context.t; - - return Stack( - alignment: Alignment.center, - children: [ - Icon( - Iconz().cloud, - color: theme.disabledColor, - ), - Positioned( - bottom: -2, - right: -2, - child: Icon( - Iconz().close, - color: theme.colorScheme.error, - size: 16, - ), - ), - ], - ); - } } diff --git a/lib/common/view/language_autocomplete.dart b/lib/common/view/language_autocomplete.dart index 279fb1a01..5d3a9b18f 100644 --- a/lib/common/view/language_autocomplete.dart +++ b/lib/common/view/language_autocomplete.dart @@ -231,7 +231,7 @@ class _LanguageTile extends StatelessWidget { favs?.contains(t.isoCode) == false ? addFav(t) : removeFav(t); }, icon: Icon( - favs?.contains(t.isoCode) == true ? Iconz().starFilled : Iconz().star, + favs?.contains(t.isoCode) == true ? Iconz.starFilled : Iconz.star, ), ), ); diff --git a/lib/common/view/like_all_icon.dart b/lib/common/view/like_all_icon.dart index 14195b3aa..d9ff631b9 100644 --- a/lib/common/view/like_all_icon.dart +++ b/lib/common/view/like_all_icon.dart @@ -1,9 +1,10 @@ -import '../../library/library_model.dart'; -import '../data/audio.dart'; -import 'icons.dart'; import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; +import '../../library/library_model.dart'; +import '../data/audio.dart'; +import 'animated_like_icon.dart'; + class LikeAllIcon extends StatelessWidget with WatchItMixin { const LikeAllIcon({super.key, required this.audios}); @@ -19,7 +20,7 @@ class LikeAllIcon extends StatelessWidget with WatchItMixin { onPressed: () => liked ? libraryModel.removeLikedAudios(audios) : libraryModel.addLikedAudios(audios), - icon: Iconz().getAnimatedHeartIcon(liked: liked), + icon: AnimatedHeart(liked: liked), ); } } diff --git a/lib/common/view/like_icon.dart b/lib/common/view/like_icon.dart index 25e54d3d6..53bf2b323 100644 --- a/lib/common/view/like_icon.dart +++ b/lib/common/view/like_icon.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; -import '../data/audio.dart'; -import 'icons.dart'; import '../../constants.dart'; import '../../l10n/l10n.dart'; import '../../library/library_model.dart'; import '../../playlists/view/add_to_playlist_snack_bar.dart'; +import '../data/audio.dart'; +import 'animated_like_icon.dart'; class LikeIcon extends StatelessWidget with WatchItMixin { const LikeIcon({ @@ -49,7 +49,7 @@ class LikeIcon extends StatelessWidget with WatchItMixin { tooltip: liked ? context.l10n.removeFromFavorites : context.l10n.addToFavorites, - icon: Iconz().getAnimatedHeartIcon( + icon: AnimatedHeart( liked: liked, color: color, ), @@ -95,7 +95,10 @@ class RadioLikeIcon extends StatelessWidget with WatchItMixin { tooltip: isStarredStation ? context.l10n.removeFromCollection : context.l10n.addToCollection, - icon: Iconz().getAnimatedStar(isStarredStation, color), + icon: AnimatedStar( + isStarred: isStarredStation, + color: color, + ), onPressed: onLike, color: color, ); diff --git a/lib/common/view/mpv_metadata_dialog.dart b/lib/common/view/mpv_metadata_dialog.dart index fca567272..8ef42b678 100644 --- a/lib/common/view/mpv_metadata_dialog.dart +++ b/lib/common/view/mpv_metadata_dialog.dart @@ -31,7 +31,7 @@ class MpvMetadataDialog extends StatelessWidget { child: SizedBox( width: 250, child: SafeNetworkImage( - errorIcon: Icon(Iconz().imageMissing), + errorIcon: Icon(Iconz.imageMissing), fit: BoxFit.fitHeight, url: image, ), diff --git a/lib/common/view/progress.dart b/lib/common/view/progress.dart index ea8955801..37cc02418 100644 --- a/lib/common/view/progress.dart +++ b/lib/common/view/progress.dart @@ -1,7 +1,7 @@ -import '../../extensions/build_context_x.dart'; -import 'icons.dart'; import 'package:flutter/material.dart'; import 'package:yaru/yaru.dart'; + +import '../../extensions/build_context_x.dart'; import 'theme.dart'; class SideBarProgress extends StatelessWidget { diff --git a/lib/common/view/safe_network_image.dart b/lib/common/view/safe_network_image.dart index b47b5ed02..ed7d80f68 100644 --- a/lib/common/view/safe_network_image.dart +++ b/lib/common/view/safe_network_image.dart @@ -36,7 +36,7 @@ class SafeNetworkImage extends StatelessWidget { final fallBack = Center( child: fallBackIcon ?? Icon( - Iconz().musicNote, + Iconz.musicNote, size: height != null ? height! * 0.7 : null, ), ); @@ -46,7 +46,7 @@ class SafeNetworkImage extends StatelessWidget { final errorWidget = Center( child: errorIcon ?? Icon( - Iconz().imageMissing, + Iconz.imageMissing, size: height != null ? height! * 0.7 : null, color: context.t.hintColor, ), diff --git a/lib/common/view/search_button.dart b/lib/common/view/search_button.dart index c33ab581b..ca49cb3bf 100644 --- a/lib/common/view/search_button.dart +++ b/lib/common/view/search_button.dart @@ -25,13 +25,13 @@ class SearchButton extends StatelessWidget { onPressed: onPressed, selectedIcon: icon ?? Icon( - Iconz().search, + Iconz.search, color: context.t.colorScheme.primary, size: iconSize, ), icon: icon ?? Icon( - Iconz().search, + Iconz.search, size: iconSize, ), ); diff --git a/lib/common/view/share_button.dart b/lib/common/view/share_button.dart index d8bce0148..945e3d777 100644 --- a/lib/common/view/share_button.dart +++ b/lib/common/view/share_button.dart @@ -45,7 +45,7 @@ class ShareButton extends StatelessWidget { ); }, icon: Icon( - Iconz().share, + Iconz.share, color: color, size: iconSize, ), diff --git a/lib/common/view/side_bar_fall_back_image.dart b/lib/common/view/side_bar_fall_back_image.dart index f0c2fc05e..b40dd0f68 100644 --- a/lib/common/view/side_bar_fall_back_image.dart +++ b/lib/common/view/side_bar_fall_back_image.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:yaru/yaru.dart'; import '../../extensions/build_context_x.dart'; -import 'icons.dart'; +import 'theme.dart'; class SideBarFallBackImage extends StatelessWidget { const SideBarFallBackImage({ diff --git a/lib/common/view/stream_provider_share_button.dart b/lib/common/view/stream_provider_share_button.dart index 8b78d4624..d0b31db14 100644 --- a/lib/common/view/stream_provider_share_button.dart +++ b/lib/common/view/stream_provider_share_button.dart @@ -57,7 +57,7 @@ class StreamProviderShareButton extends StatelessWidget { icon: Padding( padding: const EdgeInsets.only(bottom: 2), child: Icon( - onSearch != null ? Iconz().globe : iconData, + onSearch != null ? Iconz.globe : iconData, color: color, ), ), diff --git a/lib/common/view/theme.dart b/lib/common/view/theme.dart index 51bdcd173..0ce1f1c7f 100644 --- a/lib/common/view/theme.dart +++ b/lib/common/view/theme.dart @@ -10,7 +10,7 @@ import 'icons.dart'; ThemeData? yaruDarkWithTweaks(YaruThemeData yaru) { return yaru.darkTheme?.copyWith( actionIconTheme: ActionIconThemeData( - backButtonIconBuilder: (context) => Icon(Iconz().goBack), + backButtonIconBuilder: (context) => Icon(Iconz.goBack), ), scaffoldBackgroundColor: yaru.darkTheme?.scaffoldBackgroundColor.scale( lightness: -0.35, @@ -31,7 +31,7 @@ ThemeData? yaruDarkWithTweaks(YaruThemeData yaru) { ThemeData? yaruLightWithTweaks(YaruThemeData yaru) { return yaru.theme?.copyWith( actionIconTheme: ActionIconThemeData( - backButtonIconBuilder: (context) => Icon(Iconz().goBack), + backButtonIconBuilder: (context) => Icon(Iconz.goBack), ), cardColor: yaru.theme?.dividerColor.scale( lightness: -0.01, @@ -215,6 +215,14 @@ Color? chipSelectionColor(ThemeData theme, bool loading) { return yaruStyled ? (loading ? theme.colorScheme.outline : null) : null; } +double get iconSize => yaruStyled + ? kYaruIconSize + : isMobile + ? 24.0 + : 20.0; + +double get sideBarImageSize => 38; + double get likeButtonWidth => yaruStyled ? 62 : 70; double get progressStrokeWidth => 3.0; diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index d37692b09..251369b4d 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -346,7 +346,9 @@ "doNotAskAgain": "Nicht mehr fragen", "skipToLivStream": "Zur Live-Übertragung springen", "searchSimilarStation": "Ähnlichen Sender suchen", + "clicks": "Clicks", "regionNone": "Keine", + "onlineArtError": "Die Albumkunst-Online-Suche ist momentan nicht verfügbar", "regionAfghanistan": "Afghanistan", "regionAlandislands": "Ålandinseln", "regionAlbania": "Albanien", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 987fa8dcd..24279e772 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -344,6 +344,8 @@ "doNotAskAgain": "Do not ask again", "skipToLivStream": "Skip to live stream", "searchSimilarStation": "Search similar station", + "onlineArtError": "Online art lookup is currently not available", + "clicks": "Clicks", "regionNone": "None", "regionAfghanistan": "Afghanistan", "regionAlandislands": "Alandislands", diff --git a/lib/library/library_model.dart b/lib/library/library_model.dart index 967c8cd0e..3fa9f7c9e 100644 --- a/lib/library/library_model.dart +++ b/lib/library/library_model.dart @@ -66,18 +66,18 @@ class LibraryModel extends SafeChangeNotifier { Map> get starredStations => _service.starredStations; int get starredStationsLength => _service.starredStations.length; - void addStarredStation(String url, List