diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml index f74085f3..812458ba 100644 --- a/android/app/src/main/res/drawable-v21/launch_background.xml +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -1,12 +1,4 @@ - - - - diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml index 304732f8..5782842b 100644 --- a/android/app/src/main/res/drawable/launch_background.xml +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -1,12 +1,4 @@ - - - - diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml index 06952be7..c6e7031f 100644 --- a/android/app/src/main/res/values-night/styles.xml +++ b/android/app/src/main/res/values-night/styles.xml @@ -1,17 +1,8 @@ - - diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index cb1ef880..ff81bae8 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,17 +1,8 @@ - - diff --git a/go_backend/ape_tags.go b/go_backend/ape_tags.go index 9b6057d6..43eb2c29 100644 --- a/go_backend/ape_tags.go +++ b/go_backend/ape_tags.go @@ -56,7 +56,6 @@ func ReadAPETags(filePath string) (*APETag, error) { return nil, fmt.Errorf("file too small for APE tag") } - // Try to find APE tag footer at the end of file. // The footer is the last 32 bytes before any ID3v1 tag (128 bytes). tag, err := readAPETagAtOffset(f, fileSize, fileSize-apeTagHeaderSize) if err == nil { @@ -255,7 +254,6 @@ func findExistingAPETagSize(filePath string) (int64, error) { tagSize := int64(binary.LittleEndian.Uint32(footer[12:16])) - // Check if there's also a header (tagSize only covers items + footer) hasHeader := (flags & (1 << 31)) != 0 // bit 31 = tag contains header totalSize := tagSize if hasHeader { @@ -511,7 +509,6 @@ func apeKeysFromFields(fields map[string]string) map[string]struct{} { // deletion: the caller sends an empty value which is not serialized into // newItems, but the old value must still be dropped. func MergeAPEItems(existing, newItems []APETagItem, overrideKeys map[string]struct{}) []APETagItem { - // Build a set of keys being updated (upper-case for case-insensitive match) combined := make(map[string]struct{}, len(newItems)+len(overrideKeys)) for k := range overrideKeys { combined[strings.ToUpper(k)] = struct{}{} @@ -539,7 +536,6 @@ func ReadAPETagsFromReader(r io.ReaderAt, fileSize int64) (*APETag, error) { return nil, fmt.Errorf("file too small for APE tag") } - // Try footer at end of file footer := make([]byte, apeTagHeaderSize) if _, err := r.ReadAt(footer, fileSize-apeTagHeaderSize); err != nil { return nil, fmt.Errorf("failed to read APE footer: %w", err) diff --git a/go_backend/exports.go b/go_backend/exports.go index 285c0d0b..fcc22361 100644 --- a/go_backend/exports.go +++ b/go_backend/exports.go @@ -2529,7 +2529,6 @@ func ReEnrichFile(requestJSON string) (string, error) { lower := strings.ToLower(req.FilePath) isFlac := strings.HasSuffix(lower, ".flac") - // Download cover art to temp file var coverTempPath string var coverDataBytes []byte if req.CoverURL != "" && req.shouldUpdateField("cover") { @@ -2590,7 +2589,6 @@ func ReEnrichFile(requestJSON string) (string, error) { } } - // Fetch lyrics if req.EmbedLyrics && req.shouldUpdateField("lyrics") { client := NewLyricsClient() durationSec := float64(req.DurationMs) / 1000.0 diff --git a/go_backend/extension_test.go b/go_backend/extension_test.go index 50fad881..658cc2f7 100644 --- a/go_backend/extension_test.go +++ b/go_backend/extension_test.go @@ -116,7 +116,6 @@ func TestIsDomainAllowed(t *testing.T) { } func TestExtensionRuntime_NetworkSandbox(t *testing.T) { - // Create a mock extension with limited network permissions ext := &loadedExtension{ ID: "test-ext", Manifest: &ExtensionManifest{ @@ -253,7 +252,6 @@ func TestExtensionRuntime_UtilityFunctions(t *testing.T) { if err != nil { t.Fatalf("stringifyJSON failed: %v", err) } - // JSON output may vary in order, just check it's valid if result.String() == "" { t.Error("Expected non-empty JSON string") } @@ -424,7 +422,6 @@ func TestExtensionRuntime_BindExtensionRequestCancelContext(t *testing.T) { } func TestExtensionRuntime_SSRFProtection(t *testing.T) { - // Create extension with limited network permissions ext := &loadedExtension{ ID: "test-ext", Manifest: &ExtensionManifest{ diff --git a/lib/constants/app_info.dart b/lib/constants/app_info.dart index a32ae917..253ef974 100644 --- a/lib/constants/app_info.dart +++ b/lib/constants/app_info.dart @@ -1,13 +1,10 @@ import 'package:flutter/foundation.dart'; -/// App version and info constants -/// Update version here only - all other files will reference this class AppInfo { static const String version = '4.5.0'; static const String buildNumber = '127'; static const String fullVersion = '$version+$buildNumber'; - /// Shows "Internal" in debug builds, actual version in release. static String get displayVersion => kDebugMode ? 'Internal' : version; static const String appName = 'SpotiFLAC Mobile'; diff --git a/lib/l10n/l10n.dart b/lib/l10n/l10n.dart index 9b1ea89b..6c908b45 100644 --- a/lib/l10n/l10n.dart +++ b/lib/l10n/l10n.dart @@ -3,9 +3,6 @@ import 'package:spotiflac_android/l10n/app_localizations.dart'; export 'package:spotiflac_android/l10n/app_localizations.dart'; -/// Extension to easily access AppLocalizations from BuildContext extension AppLocalizationsX on BuildContext { - /// Get the AppLocalizations instance - /// Usage: context.l10n.navHome AppLocalizations get l10n => AppLocalizations.of(this); } diff --git a/lib/models/theme_settings.dart b/lib/models/theme_settings.dart index 6860c67e..5f331d1e 100644 --- a/lib/models/theme_settings.dart +++ b/lib/models/theme_settings.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -/// Storage keys for theme settings persistence const String kThemeModeKey = 'theme_mode'; const String kUseDynamicColorKey = 'use_dynamic_color'; const String kSeedColorKey = 'seed_color'; @@ -13,7 +12,7 @@ class ThemeSettings { final ThemeMode themeMode; final bool useDynamicColor; final int seedColorValue; - final bool useAmoled; // Pure black background for OLED screens + final bool useAmoled; const ThemeSettings({ this.themeMode = ThemeMode.system, diff --git a/lib/providers/download_queue_provider.dart b/lib/providers/download_queue_provider.dart index 2cbdc2bf..b63d8cc5 100644 --- a/lib/providers/download_queue_provider.dart +++ b/lib/providers/download_queue_provider.dart @@ -3598,11 +3598,6 @@ class DownloadQueueNotifier extends Notifier { return null; } - // --------------------------------------------------------------------------- - // Album ReplayGain: accumulate per-track data, compute & write album gain - // --------------------------------------------------------------------------- - - /// Build a stable key for grouping tracks by album. String _albumRgKey(Track track) { if (track.albumId != null && track.albumId!.isNotEmpty) { return 'id:${track.albumId}'; @@ -3773,7 +3768,6 @@ class DownloadQueueNotifier extends Notifier { _log.w('SAF write-back failed for album RG: $filePath'); } } finally { - // Clean up temp file regardless of SAF result. try { final tmp = File(tempPath!); if (await tmp.exists()) await tmp.delete(); @@ -4017,7 +4011,6 @@ class DownloadQueueNotifier extends Notifier { final isM4a = format == 'm4a'; final isMp3 = format == 'mp3'; - // ── Cover download ────────────────────────────────────────────── String? coverPath; var coverUrl = normalizeRemoteHttpUrl(track.coverUrl); if (coverUrl != null && coverUrl.isNotEmpty) { @@ -4055,7 +4048,6 @@ class DownloadQueueNotifier extends Notifier { } try { - // ── Metadata map ──────────────────────────────────────────────── final metadata = { 'TITLE': track.name, 'ARTIST': track.artistName, @@ -4099,7 +4091,6 @@ class DownloadQueueNotifier extends Notifier { metadata['COMPOSER'] = track.composer!; } - // ── Lyrics ────────────────────────────────────────────────────── final lyricsMode = settings.lyricsMode; final extensionState = ref.read(extensionProvider); final skipLyrics = _shouldSkipLyrics( @@ -4160,7 +4151,6 @@ class DownloadQueueNotifier extends Notifier { ReplayGainResult? scannedReplayGain; - // ── ReplayGain (MP3/Opus/M4A: scan before FFmpeg, add to metadata) ─ if (settings.embedReplayGain && !isFlac) { try { final rgResult = await FFmpegService.scanReplayGain(filePath); @@ -4178,7 +4168,6 @@ class DownloadQueueNotifier extends Notifier { } } - // ── FFmpeg embed (format-specific) ────────────────────────────── final validCover = coverPath != null && await File(coverPath).exists() ? coverPath : null; @@ -4232,7 +4221,6 @@ class DownloadQueueNotifier extends Notifier { } } - // ── FLAC post-processing ──────────────────────────────────────── if (isFlac) { if (settings.artistTagMode == artistTagModeSplitVorbis) { try { @@ -7991,10 +7979,6 @@ final downloadQueueLookupProvider = Provider((ref) { return ref.watch(downloadQueueProvider.select((s) => s.lookup)); }); -// --------------------------------------------------------------------------- -// Album ReplayGain helpers -// --------------------------------------------------------------------------- - class _AlbumRgTrackEntry { String filePath; final String trackId; diff --git a/lib/screens/home_tab.dart b/lib/screens/home_tab.dart index 1f7d6221..69626dec 100644 --- a/lib/screens/home_tab.dart +++ b/lib/screens/home_tab.dart @@ -1753,7 +1753,6 @@ class _HomeTabState extends ConsumerState ); } - /// Build YT Music "Quick picks" style swipeable pages section Widget _buildYTMusicQuickPicksSection( ExploreSection section, ColorScheme colorScheme, diff --git a/lib/screens/library_tracks_folder_screen.dart b/lib/screens/library_tracks_folder_screen.dart index 43131602..fc45b73c 100644 --- a/lib/screens/library_tracks_folder_screen.dart +++ b/lib/screens/library_tracks_folder_screen.dart @@ -125,7 +125,6 @@ class _LibraryTracksFolderScreenState return null; } - /// Returns true if [url] is a local file path rather than a network URL. bool _isCoverLocalPath(String url) { return !url.startsWith('http://') && !url.startsWith('https://'); } @@ -1301,7 +1300,6 @@ class _CollectionTrackTile extends ConsumerWidget { return null; } - /// Builds a cover image widget that handles both network URLs and local file paths. Widget _buildTrackCover(BuildContext context, String coverUrl, double size) { final isLocal = !coverUrl.startsWith('http://') && !coverUrl.startsWith('https://'); diff --git a/lib/screens/queue_tab.dart b/lib/screens/queue_tab.dart index 8aeed2d5..3335a4bf 100644 --- a/lib/screens/queue_tab.dart +++ b/lib/screens/queue_tab.dart @@ -2162,7 +2162,6 @@ class _QueueTabState extends ConsumerState { .createPlaylist(playlistName); } - /// Build a playlist cover thumbnail (custom cover > first track cover > icon fallback). /// Pass a finite [size] (e.g. 56) for list view, or `null` for grid view /// where the widget should expand to fill its parent. Widget _buildPlaylistCover( @@ -2987,7 +2986,6 @@ class _QueueTabState extends ConsumerState { ); } - /// Returns the visible collection entries, hiding Wishlist/Loved when empty. List<_CollectionEntry> _getVisibleCollectionEntries( LibraryCollectionsState collectionState, ) { @@ -4483,7 +4481,6 @@ class _QueueTabState extends ConsumerState { } } - /// Show batch convert bottom sheet for selected tracks Future _showBatchConvertSheet( BuildContext context, List allItems, @@ -5629,7 +5626,6 @@ class _QueueTabState extends ConsumerState { ); } - /// Build cover image widget for unified library item. /// When [size] is provided, renders at fixed dimensions (list mode). /// When [size] is null, fills the parent container (grid mode). Widget _buildUnifiedCoverImage( diff --git a/lib/screens/settings/app_settings_page.dart b/lib/screens/settings/app_settings_page.dart index e4991ab7..a37cbbee 100644 --- a/lib/screens/settings/app_settings_page.dart +++ b/lib/screens/settings/app_settings_page.dart @@ -60,7 +60,6 @@ class AppSettingsPage extends ConsumerWidget { ), ), - // ── Updates ──────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionApp), ), @@ -97,7 +96,6 @@ class AppSettingsPage extends ConsumerWidget { ), ), - // ── Data ─────────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionData), ), @@ -122,7 +120,6 @@ class AppSettingsPage extends ConsumerWidget { ), ), - // ── Debug ────────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionDebug), ), diff --git a/lib/screens/settings/appearance_settings_page.dart b/lib/screens/settings/appearance_settings_page.dart index 21f0082e..9e5cc131 100644 --- a/lib/screens/settings/appearance_settings_page.dart +++ b/lib/screens/settings/appearance_settings_page.dart @@ -741,7 +741,6 @@ class _LanguageSelector extends StatelessWidget { ('zh_TW', '繁體中文', Icons.language), ]; - /// Get only languages that meet the translation threshold. /// Uses filteredLocaleCodes from supported_locales.dart (generated file). List<(String, String, IconData)> get _languages { return _allLanguages.where((lang) { diff --git a/lib/screens/settings/donate_page.dart b/lib/screens/settings/donate_page.dart index d2828382..8a3880b1 100644 --- a/lib/screens/settings/donate_page.dart +++ b/lib/screens/settings/donate_page.dart @@ -166,7 +166,6 @@ class _RecentDonorsCard extends StatelessWidget { final isDark = Theme.of(context).brightness == Brightness.dark; const donorNames = []; - // Match SettingsGroup color logic final cardColor = isDark ? Color.alphaBlend( Colors.white.withValues(alpha: 0.08), diff --git a/lib/screens/settings/download_settings_page.dart b/lib/screens/settings/download_settings_page.dart index 8e55018e..9760f39c 100644 --- a/lib/screens/settings/download_settings_page.dart +++ b/lib/screens/settings/download_settings_page.dart @@ -74,7 +74,6 @@ class _DownloadSettingsPageState extends ConsumerState { ), ), - // ── Service ──────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionService), ), @@ -91,7 +90,6 @@ class _DownloadSettingsPageState extends ConsumerState { ), ), - // ── Audio Quality ────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionAudioQuality, @@ -117,7 +115,6 @@ class _DownloadSettingsPageState extends ConsumerState { ), ), - // ── Network & Performance ────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionPerformance, @@ -176,7 +173,6 @@ class _DownloadSettingsPageState extends ConsumerState { ), ), - // ── Fallback & Search ────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionSearchSource, @@ -211,7 +207,6 @@ class _DownloadSettingsPageState extends ConsumerState { ), ), - // ── Misc ─────────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionDownload), ), @@ -611,8 +606,6 @@ class _DownloadSettingsPageState extends ConsumerState { } } -// ── Private widgets (reused from original) ───────────────────────────────── - class _BetaBadge extends StatelessWidget { const _BetaBadge(); @@ -896,7 +889,6 @@ class _ConcurrentChip extends StatelessWidget { } } -// Imported from options_settings_page — search source selectors class _MetadataSourceSelector extends ConsumerWidget { const _MetadataSourceSelector(); diff --git a/lib/screens/settings/extensions_page.dart b/lib/screens/settings/extensions_page.dart index 3210b054..d90e3849 100644 --- a/lib/screens/settings/extensions_page.dart +++ b/lib/screens/settings/extensions_page.dart @@ -347,7 +347,6 @@ class _ExtensionsPageState extends ConsumerState { return _getFriendlyErrorMessage(firstError); } - /// Parse error message to be more user-friendly String _getFriendlyErrorMessage(String? error) { if (error == null) return context.l10n.snackbarFailedToInstall; diff --git a/lib/screens/settings/files_settings_page.dart b/lib/screens/settings/files_settings_page.dart index c2d6d974..96bf6cc2 100644 --- a/lib/screens/settings/files_settings_page.dart +++ b/lib/screens/settings/files_settings_page.dart @@ -135,7 +135,6 @@ class _FilesSettingsPageState extends ConsumerState { ), ), - // ── Download Location ────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.setupDownloadLocationTitle, @@ -159,7 +158,6 @@ class _FilesSettingsPageState extends ConsumerState { ), ), - // ── Filename Formats ─────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionFileSettings, @@ -199,7 +197,6 @@ class _FilesSettingsPageState extends ConsumerState { ), ), - // ── Folder Structure ─────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.downloadFolderOrganization, @@ -318,7 +315,6 @@ class _FilesSettingsPageState extends ConsumerState { ), ), - // ── Storage Access (Android 13+) ─────────────────────────── if (Platform.isAndroid && _androidSdkVersion >= 33) ...[ SliverToBoxAdapter( child: SettingsSectionHeader( @@ -379,8 +375,6 @@ class _FilesSettingsPageState extends ConsumerState { ); } - // ── Helpers ────────────────────────────────────────────────────────────── - String _getAlbumFolderStructureLabel(String structure) { switch (structure) { case 'album_only': diff --git a/lib/screens/settings/log_screen.dart b/lib/screens/settings/log_screen.dart index 8377ed8f..89a4f442 100644 --- a/lib/screens/settings/log_screen.dart +++ b/lib/screens/settings/log_screen.dart @@ -556,7 +556,6 @@ class _LogEntryTile extends StatelessWidget { } } -/// Summary card showing detected issues in logs class _LogSummaryCard extends StatelessWidget { final List logs; diff --git a/lib/screens/settings/lyrics_provider_priority_page.dart b/lib/screens/settings/lyrics_provider_priority_page.dart index 32c8fd83..37bcc34a 100644 --- a/lib/screens/settings/lyrics_provider_priority_page.dart +++ b/lib/screens/settings/lyrics_provider_priority_page.dart @@ -358,7 +358,6 @@ class _DisabledProviderItem extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ - // Empty space aligned with numbered badge const SizedBox(width: 28), const SizedBox(width: 16), Icon(info.icon, color: colorScheme.outline), diff --git a/lib/screens/settings/lyrics_settings_page.dart b/lib/screens/settings/lyrics_settings_page.dart index 862da242..6e23bd47 100644 --- a/lib/screens/settings/lyrics_settings_page.dart +++ b/lib/screens/settings/lyrics_settings_page.dart @@ -60,7 +60,6 @@ class LyricsSettingsPage extends ConsumerWidget { ), ), - // ── Lyrics Embedding ─────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionLyrics), ), @@ -112,7 +111,6 @@ class LyricsSettingsPage extends ConsumerWidget { ), ), - // ── Provider Options ─────────────────────────────────────── if (settings.embedMetadata && settings.embedLyrics) ...[ SliverToBoxAdapter( child: SettingsSectionHeader( diff --git a/lib/screens/settings/metadata_settings_page.dart b/lib/screens/settings/metadata_settings_page.dart index d3485517..234b5b61 100644 --- a/lib/screens/settings/metadata_settings_page.dart +++ b/lib/screens/settings/metadata_settings_page.dart @@ -61,7 +61,6 @@ class MetadataSettingsPage extends ConsumerWidget { ), ), - // ── Embedding ────────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader(title: context.l10n.sectionDownload), ), @@ -116,7 +115,6 @@ class MetadataSettingsPage extends ConsumerWidget { ), ), - // ── Providers ───────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionMetadataProviders, @@ -141,7 +139,6 @@ class MetadataSettingsPage extends ConsumerWidget { ), ), - // ── Deduplication ────────────────────────────────────────── SliverToBoxAdapter( child: SettingsSectionHeader( title: context.l10n.sectionDuplicates, diff --git a/lib/screens/settings/settings_tab.dart b/lib/screens/settings/settings_tab.dart index 97b51288..bccd5b60 100644 --- a/lib/screens/settings/settings_tab.dart +++ b/lib/screens/settings/settings_tab.dart @@ -61,7 +61,6 @@ class SettingsTab extends ConsumerWidget { ), ), - // ── Group 1: Appearance & Content ────────────────────────────── SliverToBoxAdapter( child: Builder( builder: (context) { @@ -96,7 +95,6 @@ class SettingsTab extends ConsumerWidget { ), ), - // ── Group 2: Download ────────────────────────────────────────── SliverToBoxAdapter( child: Builder( builder: (context) { @@ -139,7 +137,6 @@ class SettingsTab extends ConsumerWidget { ), ), - // ── Group 3: App ─────────────────────────────────────────────── SliverToBoxAdapter( child: Builder( builder: (context) { diff --git a/lib/screens/setup_screen.dart b/lib/screens/setup_screen.dart index 426654a0..f15b5896 100644 --- a/lib/screens/setup_screen.dart +++ b/lib/screens/setup_screen.dart @@ -717,7 +717,6 @@ class _SetupScreenState extends ConsumerState { ); } - // --- Language data (native names, always readable regardless of current locale) --- static const _allLanguages = [ ('system', 'System Default', Icons.phone_android), ('en', 'English', Icons.language), @@ -757,7 +756,6 @@ class _SetupScreenState extends ConsumerState { return LayoutBuilder( builder: (context, constraints) { final shortestSide = MediaQuery.sizeOf(context).shortestSide; - // Match _StepLayout sizing exactly final iconPadding = (shortestSide * 0.06).clamp(16.0, 24.0); final iconSize = (shortestSide * 0.12).clamp(32.0, 48.0); final titleGap = (shortestSide * 0.06).clamp(16.0, 32.0); @@ -766,7 +764,6 @@ class _SetupScreenState extends ConsumerState { return Column( children: [ - // Header: identical to _StepLayout (same padding, spacing, styles) Padding( padding: const EdgeInsets.fromLTRB(24, 24, 24, 0), child: Column( @@ -805,7 +802,6 @@ class _SetupScreenState extends ConsumerState { ], ), ), - // Language list (scrollable action area) Expanded( child: ListView.builder( padding: const EdgeInsets.fromLTRB(24, 0, 24, 80), diff --git a/lib/services/ffmpeg_service.dart b/lib/services/ffmpeg_service.dart index 5201fc2b..69491c3f 100644 --- a/lib/services/ffmpeg_service.dart +++ b/lib/services/ffmpeg_service.dart @@ -1060,7 +1060,6 @@ class FFmpegService { /// Uses the FFmpeg `ebur128` audio filter to measure integrated loudness (LUFS) /// and true peak. ReplayGain reference level is -18 LUFS (≈ 89 dB SPL). /// - /// Returns a [ReplayGainResult] on success, or null if the scan fails. static Future scanReplayGain(String filePath) async { // -nostats suppresses the interactive progress line. // ebur128=peak=true prints integrated loudness + true peak. @@ -1079,7 +1078,6 @@ class FFmpegService { // because -f null always "fails" on some FFmpeg builds. final output = result.output; - // Parse integrated loudness: "I: -14.0 LUFS" final integratedMatch = RegExp( r'I:\s+(-?\d+\.?\d*)\s+LUFS', ).allMatches(output); @@ -1205,7 +1203,6 @@ class FFmpegService { } } - // Cleanup temp file on failure try { final tempFile = File(tempOutput); if (await tempFile.exists()) await tempFile.delete(); @@ -1332,7 +1329,6 @@ class FFmpegService { output.contains('incorrect codec parameters')) { _log.w('MP3 copy failed (codec mismatch), re-encoding with libmp3lame'); - // Clean up failed temp file try { final tempFile = File(tempOutput); if (await tempFile.exists()) await tempFile.delete(); @@ -1353,7 +1349,6 @@ class FFmpegService { return await _finalizeMp3Embed(mp3Path, reencodeOutput); } - // Clean up re-encode temp file try { final tempFile = File(reencodeOutput); if (await tempFile.exists()) await tempFile.delete(); @@ -1363,7 +1358,6 @@ class FFmpegService { return null; } - // Clean up temp file for other failures try { final tempFile = File(tempOutput); if (await tempFile.exists()) await tempFile.delete(); @@ -1375,7 +1369,6 @@ class FFmpegService { return null; } - /// Build and execute FFmpeg arguments for MP3 metadata embedding. static Future _runMp3Embed({ required String mp3Path, required String tempOutput, @@ -1775,7 +1768,6 @@ class FFmpegService { /// Unified audio format conversion with full metadata + cover preservation. /// Supports: FLAC/M4A/MP3/Opus -> MP3/Opus/ALAC/FLAC. /// ALAC and FLAC targets are lossless (bitrate parameter is ignored). - /// Returns the new file path on success, null on failure. static Future convertAudioFormat({ required String inputPath, required String targetFormat, @@ -1881,7 +1873,6 @@ class FFmpegService { return outputPath; } - /// Convert any audio format to ALAC (Apple Lossless) in an M4A container. /// Metadata and cover art are embedded in a single FFmpeg pass. static Future _convertToAlac({ required String inputPath, @@ -1954,7 +1945,6 @@ class FFmpegService { return outputPath; } - /// Convert any audio format to FLAC with metadata and cover art preservation. static Future _convertToFlac({ required String inputPath, required Map metadata, @@ -2359,7 +2349,6 @@ class FFmpegService { /// [outputDir] is where individual track files will be saved /// [tracks] is the list of track split info from the Go CUE parser /// [albumMetadata] contains album-level metadata (artist, album, genre, date) - /// Returns list of output file paths on success, null on failure. static Future?> splitCueToTracks({ required String audioPath, required String outputDir, diff --git a/lib/services/update_checker.dart b/lib/services/update_checker.dart index 7ea63307..ff182ac0 100644 --- a/lib/services/update_checker.dart +++ b/lib/services/update_checker.dart @@ -45,8 +45,6 @@ class UpdateChecker { static const String _allReleasesApiUrl = 'https://api.github.com/repos/${AppInfo.githubRepo}/releases'; - /// Check for updates based on channel preference - /// [channel] can be 'stable' or 'preview' static Future checkForUpdate({String channel = 'stable'}) async { if (!Platform.isAndroid) { return null; diff --git a/lib/widgets/download_service_picker.dart b/lib/widgets/download_service_picker.dart index e4549ea6..c6dad072 100644 --- a/lib/widgets/download_service_picker.dart +++ b/lib/widgets/download_service_picker.dart @@ -10,7 +10,7 @@ class DownloadServicePicker extends ConsumerStatefulWidget { final String? artistName; final String? coverUrl; final void Function(String quality, String service) onSelect; - final String? recommendedService; // Service to show as "(Recommended)" + final String? recommendedService; const DownloadServicePicker({ super.key, diff --git a/site/docs.html b/site/docs.html index 6a148a93..b8d1cb7c 100644 --- a/site/docs.html +++ b/site/docs.html @@ -17,7 +17,6 @@