Skip to content

Commit

Permalink
feat: improve radio search and update yaru (#1101)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier authored Dec 19, 2024
1 parent 9f956ba commit 837a22b
Show file tree
Hide file tree
Showing 18 changed files with 231 additions and 230 deletions.
15 changes: 12 additions & 3 deletions lib/app/view/desktop_musicpod_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:phoenix_theme/phoenix_theme.dart';
import 'package:watch_it/watch_it.dart';
import 'package:yaru/yaru.dart';

import '../../app_config.dart';
import '../../constants.dart';
import '../../external_path/external_path_service.dart';
import '../../l10n/l10n.dart';
Expand Down Expand Up @@ -56,15 +58,22 @@ class _DesktopMusicPodAppState extends State<DesktopMusicPodApp> {
@override
Widget build(BuildContext context) {
final themeIndex = watchPropertyValue((SettingsModel m) => m.themeIndex);
final phoenix = phoenixTheme(color: widget.accent ?? Colors.greenAccent);
final color = widget.accent ?? const Color(0xFFed3c63);
final phoenix = phoenixTheme(color: color);

return MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.values[themeIndex],
highContrastTheme: widget.highContrastTheme,
highContrastDarkTheme: widget.highContrastDarkTheme,
theme: widget.lightTheme ?? phoenix.lightTheme,
darkTheme: widget.darkTheme ?? phoenix.darkTheme,
theme: widget.lightTheme ??
(yaruStyled
? createYaruLightTheme(primaryColor: color)
: phoenix.lightTheme),
darkTheme: widget.darkTheme ??
(yaruStyled
? createYaruDarkTheme(primaryColor: color)
: phoenix.darkTheme),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: supportedLocales,
onGenerateTitle: (context) => kAppTitle,
Expand Down
6 changes: 5 additions & 1 deletion lib/app/view/main_page_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ class MainPageIcon extends StatelessWidget with WatchItMixin {

return Padding(
padding: mainPageIconPadding,
child: Icon(selected ? audioType.selectedIconData : audioType.iconData),
child: Icon(
selected
? audioType.selectedIconDataMainPage
: audioType.iconDataMainPage,
),
);
}
}
2 changes: 2 additions & 0 deletions lib/app_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ bool allowDiscordRPC = (kDebugMode && !Platform.isAndroid) ||
Platform.isWindows ||
bool.tryParse(const String.fromEnvironment('ALLOW_DISCORD_RPC')) == true;

bool get useSystemTheme => !Platform.isLinux;

bool get yaruStyled => Platform.isLinux;

bool get appleStyled => Platform.isMacOS || Platform.isIOS;
Expand Down
14 changes: 13 additions & 1 deletion lib/common/data/audio_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,24 @@ enum AudioType {
};

IconData get iconData => switch (this) {
local => Iconz.localAudio,
local => Iconz.musicNote,
radio => Iconz.radio,
podcast => Iconz.podcast,
};

IconData get selectedIconData => switch (this) {
local => Iconz.musicNote,
radio => Iconz.radioFilled,
podcast => Iconz.podcastFilled,
};

IconData get iconDataMainPage => switch (this) {
local => Iconz.localAudio,
radio => Iconz.radio,
podcast => Iconz.podcast,
};

IconData get selectedIconDataMainPage => switch (this) {
local => Iconz.localAudioFilled,
radio => Iconz.radioFilled,
podcast => Iconz.podcastFilled,
Expand Down
57 changes: 57 additions & 0 deletions lib/common/view/audio_fall_back_icon.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:yaru/yaru.dart';

import '../data/audio.dart';
import 'icons.dart';
import 'theme.dart';
import '../../extensions/build_context_x.dart';
import '../../extensions/theme_data_x.dart';

class AudioFallBackIcon extends StatelessWidget {
const AudioFallBackIcon({
super.key,
required this.audio,
this.iconSize,
this.dimension,
this.color,
});

final double? iconSize;
final Audio? audio;
final double? dimension;
final Color? color;

@override
Widget build(BuildContext context) {
final theme = context.theme;
final light = theme.isLight;
final fallBackColor = theme.primaryColor;
final gradientColor = color ??
getAlphabetColor(
audio?.title ?? audio?.album ?? '',
fallBackColor,
);
return Container(
height: dimension ?? double.infinity,
width: dimension ?? double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [
gradientColor.scale(lightness: light ? 0 : -0.4, saturation: -0.5),
gradientColor.scale(
lightness: light ? -0.1 : -0.2,
saturation: -0.5,
),
],
),
),
child: Icon(
audio?.audioType?.iconData ?? Iconz.musicNote,
size: iconSize,
color: contrastColor(gradientColor).withOpacity(0.7),
),
);
}
}
1 change: 1 addition & 0 deletions lib/common/view/audio_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class _AudioTileState extends State<AudioTile> {
},
title: Padding(
padding: const EdgeInsets.only(right: kLargestSpace),
// TODO: make playlists audiotype agnostic and stop forwarding callbacks once and for all
child: widget.onTitleTap == null
? Text(
widget.audio.title ?? l10n.unknown,
Expand Down
27 changes: 10 additions & 17 deletions lib/common/view/audio_tile_image.dart
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
import 'package:flutter/material.dart';

import 'ui_constants.dart';
import '../../local_audio/view/local_cover.dart';
import '../data/audio.dart';
import '../data/audio_type.dart';
import 'icons.dart';
import 'audio_fall_back_icon.dart';
import 'safe_network_image.dart';
import 'ui_constants.dart';

class AudioTileImage extends StatelessWidget {
const AudioTileImage({
super.key,
this.audio,
required this.size,
this.fallback,
});
final Audio? audio;
final double size;
final Widget? fallback;

@override
Widget build(BuildContext context) {
final icon = Icon(
switch (audio?.audioType) {
AudioType.radio => Iconz.radio,
AudioType.podcast => Iconz.podcast,
_ => Iconz.musicNote,
},
size: size / (1.65),
);
final fallbackIcon =
AudioFallBackIcon(audio: audio, iconSize: size / (1.65));
Widget image;
if (audio?.hasPathAndId == true) {
image = LocalCover(
albumId: audio!.albumId!,
path: audio!.path!,
fit: BoxFit.cover,
dimension: size,
fallback: icon,
fallback: fallbackIcon,
);
} else if (audio?.imageUrl != null || audio?.albumArtUrl != null) {
} else {
image = SafeNetworkImage(
url: audio?.imageUrl ?? audio?.albumArtUrl,
height: size,
fit: BoxFit.cover,
fallBackIcon: icon,
errorIcon: icon,
fallBackIcon: fallbackIcon,
errorIcon: fallbackIcon,
);
} else {
image = icon;
}

return SizedBox.square(
Expand Down
1 change: 0 additions & 1 deletion lib/common/view/progress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class LinearProgress extends StatelessWidget {
return yaruStyled
? YaruLinearProgressIndicator(
value: value,
minHeight: trackHeight,
strokeWidth: trackHeight,
color: color,
)
Expand Down
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Future<void> main(List<String> args) async {
..setMinimumSize(const Size(500, 700))
..setSize(const Size(950, 820));
}
if (!yaruStyled) {
if (useSystemTheme) {
SystemTheme.fallbackColor = const Color(0xFFed3c63);
await SystemTheme.accentColor.load();
}
Expand Down
27 changes: 5 additions & 22 deletions lib/player/view/player_fall_back_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import 'package:flutter/material.dart';
import 'package:yaru/yaru.dart';

import '../../common/data/audio.dart';
import '../../common/data/audio_type.dart';
import '../../common/view/icons.dart';
import '../../common/view/theme.dart';
import '../../extensions/build_context_x.dart';
import '../../extensions/theme_data_x.dart';

Expand All @@ -26,30 +24,19 @@ class PlayerFallBackImage extends StatelessWidget {
Widget build(BuildContext context) {
final iconSize = width * 0.7;
final theme = context.theme;
IconData iconData;
if (audio?.audioType == AudioType.radio) {
iconData = Iconz.radio;
} else if (audio?.audioType == AudioType.podcast) {
iconData = Iconz.podcast;
} else {
iconData = Iconz.musicNote;
}
final color = theme.primaryColor;
return Center(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [
getAlphabetColor(
audio?.title ?? audio?.album ?? 'a',
).scale(
color.scale(
lightness: theme.isLight ? 0 : -0.4,
saturation: -0.5,
),
getAlphabetColor(
audio?.title ?? audio?.album ?? 'a',
).scale(
color.scale(
lightness: theme.isLight ? -0.1 : -0.2,
saturation: -0.5,
),
Expand All @@ -61,13 +48,9 @@ class PlayerFallBackImage extends StatelessWidget {
child: noIcon
? null
: Icon(
iconData,
audio?.audioType?.iconData ?? Iconz.musicNote,
size: iconSize,
color: contrastColor(
getAlphabetColor(
audio?.title ?? audio?.album ?? 'a',
),
),
color: contrastColor(color),
),
),
);
Expand Down
45 changes: 36 additions & 9 deletions lib/radio/radio_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ class RadioService {
return hosts;
}

RadioBrowserListResponse<Station>? _response;
String? _uuid;
String? _country;
String? _name;
String? _state;
String? _tag;
String? _language;
int? _limit;
Future<List<Station>?> search({
String? uuid,
String? country,
Expand All @@ -72,36 +80,55 @@ class RadioService {
}
}

RadioBrowserListResponse<Station>? response;
if (_response?.items != null &&
_uuid == uuid &&
_country == country &&
_name == name &&
_state == state &&
_tag == tag &&
_language == language &&
_limit == limit) {
return _response?.items;
}

final parameters = InputParameters(
hidebroken: true,
order: 'stationcount',
limit: limit,
limit: limit > 300 ? 300 : limit,
);
try {
if (uuid != null) {
response = await _radioBrowserApi!.getStationsByUUID(uuids: [uuid]);
_response = await _radioBrowserApi!.getStationsByUUID(uuids: [uuid]);
}
if (name?.isEmpty == false) {
response = await _radioBrowserApi!
_response = await _radioBrowserApi!
.getStationsByName(name: name!, parameters: parameters);
} else if (country?.isEmpty == false) {
response = await _radioBrowserApi!
_response = await _radioBrowserApi!
.getStationsByCountry(country: country!, parameters: parameters);
} else if (tag?.isEmpty == false) {
response = await _radioBrowserApi!
_response = await _radioBrowserApi!
.getStationsByTag(tag: tag!, parameters: parameters);
} else if (state?.isEmpty == false) {
response = await _radioBrowserApi!
_response = await _radioBrowserApi!
.getStationsByState(state: state!, parameters: parameters);
} else if (language?.isEmpty == false) {
response = await _radioBrowserApi!
_response = await _radioBrowserApi!
.getStationsByLanguage(language: language!, parameters: parameters);
}
} on Exception catch (e) {
printMessageInDebugMode(e);
}
return response?.items ?? [];

_uuid = uuid;
_country = country;
_name = name;
_state = state;
_tag = tag;
_language = language;
_limit = limit;

return _response?.items ?? [];
}

List<Tag>? _tags;
Expand Down
Loading

0 comments on commit 837a22b

Please sign in to comment.