Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- **Calmer motion and chrome** — the staggered entrance skips to the final frame under reduced motion, decorative art is excluded from the accessibility tree, and route-scoped system-bar styling keeps icon contrast correct after light screens are popped.

### Settings & Navigation
- **Online artist and album information toggle** — Settings → Integrations → Metadata can hide Apple Music biographies, similar artists, top songs, album notes, and new artist-portrait downloads on artist and album pages. The preference is independent of post-scan album identification, and existing saved portraits, local descriptions, and library artwork stay untouched.
- **Bottom Bar Width** — a new 70–100% slider in Settings → Interface → Bottom Bar scales the navigation bar inward from its usual margins and centers it, while keeping each item at least 44 dp; reset returns to full width.
- **Mini player as its own card** — the mini player now always sits above the frosted navigation bar instead of merging into it, aligns to the standard bar width, and keeps its gradient, border, and shadow in separated and collapsed layouts.

Expand Down
32 changes: 20 additions & 12 deletions lib/features/albums/screens/album_detail_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,15 @@ class _AlbumDetailScreenState extends ConsumerState<AlbumDetailScreen>
}

void _showMore() {
final appleMusic = ref
.read(
appleMusicAlbumProvider((widget.albumName, widget.albumArtist)),
)
.value;
final pageInfoEnabled =
ref.read(appleMusicPageInfoEnabledProvider).value ?? true;
final appleMusic = pageInfoEnabled
? ref
.read(
appleMusicAlbumProvider((widget.albumName, widget.albumArtist)),
)
.value
: null;
DetailMoreSheet.show(
context,
items: [
Expand All @@ -397,17 +401,18 @@ class _AlbumDetailScreenState extends ConsumerState<AlbumDetailScreen>
initialAlbum: widget.albumName,
),
),
if (appleMusic != null)
if (pageInfoEnabled && appleMusic != null)
DetailMoreSheetItem(
icon: LucideIcons.externalLink,
label: l10n.englishForFilipino.openInAppleMusic,
onTap: () => _openAppleMusic(_albumAppleMusicUri(appleMusic)),
),
DetailMoreSheetItem(
icon: LucideIcons.refreshCw,
label: l10n.englishForFilipino.refreshAppleMusic,
onTap: _refreshAppleMusic,
),
if (pageInfoEnabled)
DetailMoreSheetItem(
icon: LucideIcons.refreshCw,
label: l10n.englishForFilipino.refreshAppleMusic,
onTap: _refreshAppleMusic,
),
DetailMoreSheetItem(
icon: LucideIcons.moonStar,
label: l10n.englishForFilipino.sleepTimer,
Expand Down Expand Up @@ -502,11 +507,14 @@ class _AlbumDetailScreenState extends ConsumerState<AlbumDetailScreen>
builder: (context, animatedBg, _) {
final resolvedBg = animatedBg ?? AppColors.background;
final prefs = ref.watch(appPreferencesProvider);
final appleMusic = ref
final pageInfoEnabled =
ref.watch(appleMusicPageInfoEnabledProvider).value ?? true;
final remoteAlbum = ref
.watch(
appleMusicAlbumProvider((widget.albumName, widget.albumArtist)),
)
.value;
final appleMusic = pageInfoEnabled ? remoteAlbum : null;
final albumNotes = appleMusic?.notes?.trim();
return Stack(
children: [
Expand Down
47 changes: 31 additions & 16 deletions lib/features/artists/screens/artist_detail_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,30 @@ class _ArtistDetailScreenState extends ConsumerState<ArtistDetailScreen>
await _applyAppleMusicArtistArt();
}

Future<bool> _pageInfoEnabled() async {
final cached = ref.read(appleMusicPageInfoEnabledProvider).value;
if (cached != null) return cached;
return ref.read(appleMusicSettingsProvider).pageInfoEnabled();
}

/// Last-resort artist image: the Apple Music page image, downloaded once and
/// saved to the artist repository so it stays offline afterwards.
Future<void> _applyAppleMusicArtistArt() async {
if (_artistArt != null && _artistArt!.isNotEmpty) return;
if (!await _pageInfoEnabled() || !mounted) return;

final data = await ref.read(
appleMusicArtistProvider(widget.artistName).future,
);
final imageUrl = data?.info?.imageUrl;
if (!mounted || imageUrl == null || imageUrl.isEmpty) return;
if (!await _pageInfoEnabled() || !mounted) return;
if (imageUrl == null || imageUrl.isEmpty) return;

final bytes = await AppleMusicMetadataService.instance.fetchArtworkBytes(
imageUrl,
);
if (!mounted || bytes == null) return;
final bytes = await ref
.read(appleMusicMetadataServiceProvider)
.fetchArtworkBytes(imageUrl);
// The toggle may have been switched off while the portrait was in flight.
if (!await _pageInfoEnabled() || !mounted || bytes == null) return;

try {
final support = await getApplicationSupportDirectory();
Expand All @@ -178,7 +187,7 @@ class _ArtistDetailScreenState extends ConsumerState<ArtistDetailScreen>
final name = widget.artistName.hashCode.toRadixString(16);
final file = File('${dir.path}/$name.jpg');
await file.writeAsBytes(bytes);
if (!mounted) return;
if (!await _pageInfoEnabled() || !mounted) return;
setState(() {
_artistArt = file.path;
_artistArtSourcePath = null;
Expand Down Expand Up @@ -426,9 +435,11 @@ class _ArtistDetailScreenState extends ConsumerState<ArtistDetailScreen>
}

void _showMore() {
final appleMusic = ref
.read(appleMusicArtistProvider(widget.artistName))
.value;
final pageInfoEnabled =
ref.read(appleMusicPageInfoEnabledProvider).value ?? true;
final appleMusic = pageInfoEnabled
? ref.read(appleMusicArtistProvider(widget.artistName)).value
: null;
DetailMoreSheet.show(
context,
items: [
Expand All @@ -444,17 +455,18 @@ class _ArtistDetailScreenState extends ConsumerState<ArtistDetailScreen>
label: l10n.englishForFilipino.addToPlaylist,
onTap: () => AddToPlaylistSheet.showSongs(context, widget.songs),
),
if (appleMusic != null)
if (pageInfoEnabled && appleMusic != null)
DetailMoreSheetItem(
icon: LucideIcons.externalLink,
label: l10n.englishForFilipino.openInAppleMusic,
onTap: () => _openAppleMusic(_artistAppleMusicUri(appleMusic)),
),
DetailMoreSheetItem(
icon: LucideIcons.refreshCw,
label: l10n.englishForFilipino.refreshAppleMusic,
onTap: _refreshAppleMusic,
),
if (pageInfoEnabled)
DetailMoreSheetItem(
icon: LucideIcons.refreshCw,
label: l10n.englishForFilipino.refreshAppleMusic,
onTap: _refreshAppleMusic,
),
DetailMoreSheetItem(
icon: LucideIcons.moonStar,
label: l10n.englishForFilipino.sleepTimer,
Expand Down Expand Up @@ -588,9 +600,12 @@ class _ArtistDetailScreenState extends ConsumerState<ArtistDetailScreen>
builder: (context, animatedBg, _) {
final resolvedBg = animatedBg ?? AppColors.background;
final prefs = ref.watch(appPreferencesProvider);
final appleMusic = ref
final pageInfoEnabled =
ref.watch(appleMusicPageInfoEnabledProvider).value ?? true;
final remoteArtist = ref
.watch(appleMusicArtistProvider(widget.artistName))
.value;
final appleMusic = pageInfoEnabled ? remoteArtist : null;
final appleBio = appleMusic?.info?.biography?.trim();
final similarArtists =
appleMusic?.info?.similarArtists ??
Expand Down
14 changes: 11 additions & 3 deletions lib/features/settings/data/settings_search_catalog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,17 @@ List<SettingsSearchPage> buildSettingsSearchCatalog() {
('lastFm', l10n.lastFm),
('listenbrainz', l10n.listenbrainz),
], keywords: 'scrobble scrobbling last.fm listenbrainz login'),
_section('metadata', l10n.metadata, [
('autoIdentifyUntaggedAlbums', l10n.autoIdentifyUntaggedAlbums),
], keywords: 'apple music album identification tags'),
_section(
'metadata',
l10n.metadata,
[
('onlineArtistAlbumInformation', l10n.onlineArtistAlbumInformation),
('autoIdentifyUntaggedAlbums', l10n.autoIdentifyUntaggedAlbums),
],
keywords:
'apple music artist information biography similar artists '
'top songs album notes portrait identification tags',
),
],
),
for (var tab = 0; tab < 4; tab++)
Expand Down
51 changes: 37 additions & 14 deletions lib/features/settings/widgets/apple_music_settings_tile.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flick/features/settings/widgets/settings_widgets.dart';
import 'package:flick/providers/apple_music_provider.dart';
import 'package:flick/services/apple_music/apple_music_settings.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:flick/l10n/settings_l10n.dart';

class AppleMusicSettingsTile extends StatefulWidget {
class AppleMusicSettingsTile extends ConsumerStatefulWidget {
const AppleMusicSettingsTile({super.key});

@override
State<AppleMusicSettingsTile> createState() => _AppleMusicSettingsTileState();
ConsumerState<AppleMusicSettingsTile> createState() =>
_AppleMusicSettingsTileState();
}

class _AppleMusicSettingsTileState extends State<AppleMusicSettingsTile> {
class _AppleMusicSettingsTileState
extends ConsumerState<AppleMusicSettingsTile> {
final _settings = AppleMusicSettings();
bool _enabled = false;
bool _autoEnrichEnabled = false;

@override
void initState() {
Expand All @@ -24,23 +28,42 @@ class _AppleMusicSettingsTileState extends State<AppleMusicSettingsTile> {
Future<void> _load() async {
final enabled = await _settings.autoEnrichEnabled();
if (!mounted) return;
setState(() => _enabled = enabled);
setState(() => _autoEnrichEnabled = enabled);
}

Future<void> _toggle(bool value) async {
setState(() => _enabled = value);
Future<void> _toggleAutoEnrich(bool value) async {
setState(() => _autoEnrichEnabled = value);
await _settings.setAutoEnrichEnabled(value);
}

Future<void> _togglePageInfo(bool value) {
return ref
.read(appleMusicPageInfoEnabledProvider.notifier)
.setEnabled(value);
}

@override
Widget build(BuildContext context) {
return ToggleSetting(
icon: LucideIcons.sparkles,
title: l10n.englishForFilipino.autoIdentifyUntaggedAlbums,
subtitle:
l10n.afterScanningMatchFilesWithMissing,
value: _enabled,
onChanged: _toggle,
final pageInfoEnabled =
ref.watch(appleMusicPageInfoEnabledProvider).value ?? true;
return Column(
children: [
ToggleSetting(
icon: LucideIcons.globe,
title: l10n.englishForFilipino.onlineArtistAlbumInformation,
subtitle: l10n.showAppleMusicBiographiesRecommendationsAnd,
value: pageInfoEnabled,
onChanged: _togglePageInfo,
),
const SettingsDivider(),
ToggleSetting(
icon: LucideIcons.sparkles,
title: l10n.englishForFilipino.autoIdentifyUntaggedAlbums,
subtitle: l10n.afterScanningMatchFilesWithMissing,
value: _autoEnrichEnabled,
onChanged: _toggleAutoEnrich,
),
],
);
}
}
8 changes: 8 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -7079,6 +7079,10 @@
"@onboardingWelcomeTitle": {
"description": "lib/features/onboarding/screens/onboarding_screen.dart:30"
},
"onlineArtistAlbumInformation": "Online artist & album information",
"@onlineArtistAlbumInformation": {
"description": "lib/features/settings/widgets/apple_music_settings_tile.dart"
},
"onlineResults": "Online Results",
"@onlineResults": {
"description": "lib/features/songs/widgets/album_art_picker_bottom_sheet.dart:365"
Expand Down Expand Up @@ -9062,6 +9066,10 @@
"@showAlbumArtworkOnTheMini": {
"description": "lib/features/settings/screens/widget_settings_screen.dart:201"
},
"showAppleMusicBiographiesRecommendationsAnd": "Show Apple Music biographies, similar artists, top songs, album notes, and artist portraits.",
"@showAppleMusicBiographiesRecommendationsAnd": {
"description": "lib/features/settings/widgets/apple_music_settings_tile.dart"
},
"showArtist": "Show artist",
"@showArtist": {
"description": "lib/features/player/widgets/player_layout_sheet.dart:256"
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_tl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,7 @@
"onboardingReadyTitle": "Handa\nka na",
"onboardingWelcomeBody": "Maganda at mabilis na music player\npara sa lokal mong aklatan.\nWalang ads. Walang tracking. Musika lang.",
"onboardingWelcomeTitle": "Kumusta! Greetings from Flick!",
"onlineArtistAlbumInformation": "Impormasyon sa artist at album online",
"onlineResults": "Mga resulta online",
"onlyLibraryEntriesAreRemovedYour": "Mga tala lamang sa aklatan ang aalisin — mananatili sa imbakan ang iyong mga audio file.",
"onlyReReadFilesThatAre": "Basahin lamang muli ang mga bago o nabagong file.",
Expand Down Expand Up @@ -1801,6 +1802,7 @@
"showAlbum2": "Ipakita ang album",
"showAlbumArtwork": "Ipakita ang larawan ng album.",
"showAlbumArtworkOnTheMini": "Ipakita ang larawan ng album sa mini player",
"showAppleMusicBiographiesRecommendationsAnd": "Ipakita ang talambuhay, katulad na artist, nangungunang kanta, tala ng album, at larawan ng artist mula sa Apple Music.",
"showArtist": "Ipakita ang kumanta",
"showArtist2": "Ipakita ang kumanta",
"showArtistBelowSongTitle": "Ipakita ang kumanta sa ilalim ng pamagat ng kanta",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,7 @@
"onboardingReadyTitle": "一切\n就绪",
"onboardingWelcomeBody": "一款为本地音乐库打造的\n漂亮、快速播放器。\n无广告,无追踪,只有音乐。",
"onboardingWelcomeTitle": "欢迎使用\nFlick 播放器",
"onlineArtistAlbumInformation": "在线歌手与专辑信息",
"onlineResults": "在线结果",
"onlyLibraryEntriesAreRemovedYour": "仅移除音乐库条目——音频文件仍保留在磁盘上。",
"onlyReReadFilesThatAre": "只重新读取新增或有改动的文件。",
Expand Down Expand Up @@ -1951,6 +1952,7 @@
"showAlbum2": "显示专辑",
"showAlbumArtwork": "显示专辑封面。",
"showAlbumArtworkOnTheMini": "在迷你播放器上显示专辑封面",
"showAppleMusicBiographiesRecommendationsAnd": "显示 Apple Music 的简介、相似歌手、热门歌曲、专辑介绍和歌手照片。",
"showArtist": "显示艺术家",
"showArtist2": "显示艺术家",
"showArtistBelowSongTitle": "在歌曲标题下显示艺术家",
Expand Down
12 changes: 12 additions & 0 deletions lib/l10n/generated/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9166,6 +9166,12 @@ abstract class AppLocalizations {
/// **'Welcome to\nFlick Player'**
String get onboardingWelcomeTitle;

/// lib/features/settings/widgets/apple_music_settings_tile.dart
///
/// In en, this message translates to:
/// **'Online artist & album information'**
String get onlineArtistAlbumInformation;

/// lib/features/songs/widgets/album_art_picker_bottom_sheet.dart:365
///
/// In en, this message translates to:
Expand Down Expand Up @@ -11758,6 +11764,12 @@ abstract class AppLocalizations {
/// **'Show album artwork on the mini player'**
String get showAlbumArtworkOnTheMini;

/// lib/features/settings/widgets/apple_music_settings_tile.dart
///
/// In en, this message translates to:
/// **'Show Apple Music biographies, similar artists, top songs, album notes, and artist portraits.'**
String get showAppleMusicBiographiesRecommendationsAnd;

/// lib/features/player/widgets/player_layout_sheet.dart:256
///
/// In en, this message translates to:
Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/generated/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5362,6 +5362,10 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get onboardingWelcomeTitle => 'Welcome to\nFlick Player';

@override
String get onlineArtistAlbumInformation =>
'Online artist & album information';

@override
String get onlineResults => 'Online Results';

Expand Down Expand Up @@ -6880,6 +6884,10 @@ class AppLocalizationsEn extends AppLocalizations {
String get showAlbumArtworkOnTheMini =>
'Show album artwork on the mini player';

@override
String get showAppleMusicBiographiesRecommendationsAnd =>
'Show Apple Music biographies, similar artists, top songs, album notes, and artist portraits.';

@override
String get showArtist => 'Show artist';

Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/generated/app_localizations_tl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5419,6 +5419,10 @@ class AppLocalizationsTl extends AppLocalizations {
@override
String get onboardingWelcomeTitle => 'Kumusta! Greetings from Flick!';

@override
String get onlineArtistAlbumInformation =>
'Impormasyon sa artist at album online';

@override
String get onlineResults => 'Mga resulta online';

Expand Down Expand Up @@ -6958,6 +6962,10 @@ class AppLocalizationsTl extends AppLocalizations {
String get showAlbumArtworkOnTheMini =>
'Ipakita ang larawan ng album sa mini player';

@override
String get showAppleMusicBiographiesRecommendationsAnd =>
'Ipakita ang talambuhay, katulad na artist, nangungunang kanta, tala ng album, at larawan ng artist mula sa Apple Music.';

@override
String get showArtist => 'Ipakita ang kumanta';

Expand Down
Loading
Loading