mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
chore: housekeeping cleanup and code deduplication
- Remove stray tracked files (root AndroidManifest.xml, build.gradle.bak, temp_project template) - Move README-only images out of app asset bundle to reduce APK/IPA size (~1.68MB) - Fix logo filename typo (transparant -> transparent) - Deduplicate _readPositiveInt into shared int_utils.dart - Deduplicate _themeModeFromString (reuse from theme_settings.dart) - Remove deprecated LocalLibraryState.items getter - Remove unused sqflite_common_ffi dependency - Update apps.json version to 4.5.1 - Fix Flutter version in CONTRIBUTING.md (3.38.1 -> 3.41.5) - Improve .gitignore patterns (NUL, *.bak, root AndroidManifest.xml)
This commit is contained in:
1 parent
1bd54c530b
commit
904b45e8f6
24 files changed
+56
-161
No files matched your search
@@ -46,7 +46,7 @@ class ThemeSettings {
|
||||
|
||||
factory ThemeSettings.fromJson(Map<String, dynamic> json) {
|
||||
return ThemeSettings(
|
||||
themeMode: _themeModeFromString(json[kThemeModeKey] as String?),
|
||||
themeMode: themeModeFromString(json[kThemeModeKey] as String?),
|
||||
useDynamicColor: json[kUseDynamicColorKey] as bool? ?? true,
|
||||
seedColorValue: json[kSeedColorKey] as int? ?? kDefaultSeedColor,
|
||||
useAmoled: json[kUseAmoledKey] as bool? ?? false,
|
||||
@@ -68,7 +68,7 @@ class ThemeSettings {
|
||||
themeMode.hashCode ^ useDynamicColor.hashCode ^ seedColorValue.hashCode ^ useAmoled.hashCode;
|
||||
}
|
||||
|
||||
ThemeMode _themeModeFromString(String? value) {
|
||||
ThemeMode themeModeFromString(String? value) {
|
||||
if (value == null) return ThemeMode.system;
|
||||
return ThemeMode.values.firstWhere(
|
||||
(e) => e.name == value,
|
||||
|
||||
@@ -21,6 +21,7 @@ import 'package:spotiflac_android/utils/logger.dart' hide log;
|
||||
import 'package:spotiflac_android/utils/file_access.dart';
|
||||
import 'package:spotiflac_android/utils/string_utils.dart';
|
||||
import 'package:spotiflac_android/utils/artist_utils.dart';
|
||||
import 'package:spotiflac_android/utils/int_utils.dart';
|
||||
|
||||
export 'package:spotiflac_android/services/history_database.dart'
|
||||
show HistoryLookupRequest, HistoryBatchLookupRequest;
|
||||
@@ -34,19 +35,8 @@ final _trimUnderscoresAndSpacesRegex = RegExp(r'^[_ ]+|[_ ]+$');
|
||||
final _multiWhitespaceRegex = RegExp(r'\s+');
|
||||
final _multiUnderscoreRegex = RegExp(r'_+');
|
||||
|
||||
int? _readPositiveIntValue(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is num) {
|
||||
final asInt = value.toInt();
|
||||
return asInt > 0 ? asInt : null;
|
||||
}
|
||||
final parsed = int.tryParse(value.toString());
|
||||
if (parsed == null || parsed <= 0) return null;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
int? _readPositiveBitrateKbps(dynamic value) {
|
||||
final parsed = _readPositiveIntValue(value);
|
||||
final parsed = readPositiveInt(value);
|
||||
if (parsed == null) return null;
|
||||
return parsed >= 10000 ? (parsed / 1000).round() : parsed;
|
||||
}
|
||||
@@ -666,17 +656,6 @@ class DownloadHistoryNotifier extends Notifier<DownloadHistoryState> {
|
||||
}
|
||||
}
|
||||
|
||||
int? _readPositiveInt(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is num) {
|
||||
final asInt = value.toInt();
|
||||
return asInt > 0 ? asInt : null;
|
||||
}
|
||||
final parsed = int.tryParse(value.toString());
|
||||
if (parsed == null || parsed <= 0) return null;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
bool _supportsAudioMetadataProbe(String filePath) {
|
||||
final trimmed = filePath.trim().toLowerCase();
|
||||
if (trimmed.isEmpty) return false;
|
||||
@@ -757,8 +736,8 @@ class DownloadHistoryNotifier extends Notifier<DownloadHistoryState> {
|
||||
return null;
|
||||
}
|
||||
|
||||
final bitDepth = _readPositiveInt(result['bit_depth']);
|
||||
final sampleRate = _readPositiveInt(result['sample_rate']);
|
||||
final bitDepth = readPositiveInt(result['bit_depth']);
|
||||
final sampleRate = readPositiveInt(result['sample_rate']);
|
||||
final bitrateKbps = _readPositiveBitrateKbps(result['bitrate']);
|
||||
final quality = _resolveDisplayQuality(
|
||||
filePath: filePath,
|
||||
@@ -768,11 +747,11 @@ class DownloadHistoryNotifier extends Notifier<DownloadHistoryState> {
|
||||
storedQuality: fallbackQuality,
|
||||
);
|
||||
final composer = normalizeOptionalString(result['composer']?.toString());
|
||||
final duration = _readPositiveInt(result['duration']);
|
||||
final trackNumber = _readPositiveInt(result['track_number']);
|
||||
final totalTracks = _readPositiveInt(result['total_tracks']);
|
||||
final discNumber = _readPositiveInt(result['disc_number']);
|
||||
final totalDiscs = _readPositiveInt(result['total_discs']);
|
||||
final duration = readPositiveInt(result['duration']);
|
||||
final trackNumber = readPositiveInt(result['track_number']);
|
||||
final totalTracks = readPositiveInt(result['total_tracks']);
|
||||
final discNumber = readPositiveInt(result['disc_number']);
|
||||
final totalDiscs = readPositiveInt(result['total_discs']);
|
||||
|
||||
if (quality == null &&
|
||||
bitDepth == null &&
|
||||
|
||||
@@ -54,11 +54,6 @@ class LocalLibraryState {
|
||||
_isrcSet = isrcSet ?? const <String>{},
|
||||
_filePathById = filePathById ?? const <String, String>{};
|
||||
|
||||
@Deprecated(
|
||||
'LocalLibraryState no longer owns full track rows. Use DB-backed page providers.',
|
||||
)
|
||||
List<LocalLibraryItem> get items => const <LocalLibraryItem>[];
|
||||
|
||||
bool hasIsrc(String isrc) => _isrcSet.contains(isrc);
|
||||
|
||||
bool hasTrack(String trackName, String artistName) {
|
||||
|
||||
@@ -25,7 +25,7 @@ class ThemeNotifier extends Notifier<ThemeSettings> {
|
||||
final useAmoled = prefs.getBool(kUseAmoledKey);
|
||||
|
||||
state = ThemeSettings(
|
||||
themeMode: _themeModeFromString(modeString),
|
||||
themeMode: themeModeFromString(modeString),
|
||||
useDynamicColor: useDynamic ?? true,
|
||||
seedColorValue: seedColor ?? kDefaultSeedColor,
|
||||
useAmoled: useAmoled ?? false,
|
||||
@@ -71,12 +71,4 @@ class ThemeNotifier extends Notifier<ThemeSettings> {
|
||||
state = state.copyWith(useAmoled: value);
|
||||
await _saveToStorage();
|
||||
}
|
||||
|
||||
ThemeMode _themeModeFromString(String? value) {
|
||||
if (value == null) return ThemeMode.system;
|
||||
return ThemeMode.values.firstWhere(
|
||||
(e) => e.name == value,
|
||||
orElse: () => ThemeMode.system,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1549,7 +1549,7 @@ class _HomeTabState extends ConsumerState<HomeTab>
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/logo-transparant.png',
|
||||
'assets/images/logo-transparent.png',
|
||||
color: colorScheme.onPrimary,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (_, _, _) => ClipRRect(
|
||||
|
||||
@@ -302,7 +302,7 @@ class _AppHeaderCard extends StatelessWidget {
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/logo-transparant.png',
|
||||
'assets/images/logo-transparent.png',
|
||||
color: colorScheme.onPrimary,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (_, _, _) => ClipRRect(
|
||||
|
||||
@@ -681,7 +681,7 @@ class _SetupScreenState extends ConsumerState<SetupScreen> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/logo-transparant.png',
|
||||
'assets/images/logo-transparent.png',
|
||||
width: logoSize,
|
||||
height: logoSize,
|
||||
color: colorScheme.primary,
|
||||
|
||||
@@ -22,6 +22,7 @@ import 'package:spotiflac_android/utils/lyrics_metadata_helper.dart';
|
||||
import 'package:spotiflac_android/utils/mime_utils.dart';
|
||||
import 'package:spotiflac_android/utils/image_cache_utils.dart';
|
||||
import 'package:spotiflac_android/utils/string_utils.dart';
|
||||
import 'package:spotiflac_android/utils/int_utils.dart';
|
||||
import 'package:spotiflac_android/widgets/audio_analysis_widget.dart';
|
||||
import 'package:spotiflac_android/widgets/cached_cover_image.dart';
|
||||
|
||||
@@ -365,9 +366,9 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
final resolvedBitDepth = _readPositiveInt(metadata['bit_depth']);
|
||||
final resolvedSampleRate = _readPositiveInt(metadata['sample_rate']);
|
||||
final resolvedDuration = _readPositiveInt(metadata['duration']);
|
||||
final resolvedBitDepth = readPositiveInt(metadata['bit_depth']);
|
||||
final resolvedSampleRate = readPositiveInt(metadata['sample_rate']);
|
||||
final resolvedDuration = readPositiveInt(metadata['duration']);
|
||||
final resolvedAlbum = metadata['album']?.toString();
|
||||
final resolvedQuality = buildDisplayAudioQuality(
|
||||
bitDepth: resolvedBitDepth ?? bitDepth,
|
||||
@@ -386,10 +387,10 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
|
||||
// Resolve label/copyright from file when the model doesn't carry them
|
||||
// (e.g. local library items, or download history items without these fields).
|
||||
final resolvedTrackNumber = _readPositiveInt(metadata['track_number']);
|
||||
final resolvedTotalTracks = _readPositiveInt(metadata['total_tracks']);
|
||||
final resolvedDiscNumber = _readPositiveInt(metadata['disc_number']);
|
||||
final resolvedTotalDiscs = _readPositiveInt(metadata['total_discs']);
|
||||
final resolvedTrackNumber = readPositiveInt(metadata['track_number']);
|
||||
final resolvedTotalTracks = readPositiveInt(metadata['total_tracks']);
|
||||
final resolvedDiscNumber = readPositiveInt(metadata['disc_number']);
|
||||
final resolvedTotalDiscs = readPositiveInt(metadata['total_discs']);
|
||||
final resolvedComposer = metadata['composer']?.toString();
|
||||
final resolvedLabel = metadata['label']?.toString();
|
||||
final resolvedCopyright = metadata['copyright']?.toString();
|
||||
@@ -614,7 +615,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
}
|
||||
|
||||
int? get totalTracks =>
|
||||
_readPositiveInt(_editedMetadata?['total_tracks']) ??
|
||||
readPositiveInt(_editedMetadata?['total_tracks']) ??
|
||||
(_isLocalItem
|
||||
? _localLibraryItem!.totalTracks
|
||||
: _downloadItem!.totalTracks);
|
||||
@@ -631,7 +632,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
}
|
||||
|
||||
int? get totalDiscs =>
|
||||
_readPositiveInt(_editedMetadata?['total_discs']) ??
|
||||
readPositiveInt(_editedMetadata?['total_discs']) ??
|
||||
(_isLocalItem
|
||||
? _localLibraryItem!.totalDiscs
|
||||
: _downloadItem!.totalDiscs);
|
||||
@@ -670,13 +671,13 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
_editedMetadata?['composer']?.toString() ??
|
||||
(_isLocalItem ? _localLibraryItem!.composer : null);
|
||||
int? get duration =>
|
||||
_readPositiveInt(_editedMetadata?['duration']) ??
|
||||
readPositiveInt(_editedMetadata?['duration']) ??
|
||||
(_isLocalItem ? _localLibraryItem!.duration : _downloadItem!.duration);
|
||||
int? get bitDepth =>
|
||||
_readPositiveInt(_editedMetadata?['bit_depth']) ??
|
||||
readPositiveInt(_editedMetadata?['bit_depth']) ??
|
||||
(_isLocalItem ? _localLibraryItem!.bitDepth : _downloadItem!.bitDepth);
|
||||
int? get sampleRate =>
|
||||
_readPositiveInt(_editedMetadata?['sample_rate']) ??
|
||||
readPositiveInt(_editedMetadata?['sample_rate']) ??
|
||||
(_isLocalItem
|
||||
? _localLibraryItem!.sampleRate
|
||||
: _downloadItem!.sampleRate);
|
||||
@@ -706,17 +707,6 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
|
||||
String? get _quality => _isLocalItem ? null : _downloadItem!.quality;
|
||||
|
||||
int? _readPositiveInt(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is num) {
|
||||
final asInt = value.toInt();
|
||||
return asInt > 0 ? asInt : null;
|
||||
}
|
||||
final parsed = int.tryParse(value.toString());
|
||||
if (parsed == null || parsed <= 0) return null;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
String _displayServiceTrackId(String value) {
|
||||
final raw = value.trim();
|
||||
if (raw.isEmpty) return raw;
|
||||
@@ -4394,7 +4384,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
|
||||
};
|
||||
|
||||
final initialDurationSeconds =
|
||||
_readPositiveInt(fileMetadata?['duration']) ?? duration ?? 0;
|
||||
readPositiveInt(fileMetadata?['duration']) ?? duration ?? 0;
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/// Parses a dynamic value to a positive integer (> 0), or returns null.
|
||||
///
|
||||
/// Accepts [num] and parseable [String] values.
|
||||
int? readPositiveInt(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is num) {
|
||||
final asInt = value.toInt();
|
||||
return asInt > 0 ? asInt : null;
|
||||
}
|
||||
final parsed = int.tryParse(value.toString());
|
||||
if (parsed == null || parsed <= 0) return null;
|
||||
return parsed;
|
||||
}
|
||||
Reference in new issue
Block a user