mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-27 05:12:29 +02:00
feat(library): add combined quality label #511
This commit is contained in:
@@ -8,6 +8,7 @@ class AppSettings {
|
||||
static const String homeFeedProviderOff = '__off__';
|
||||
static const String libraryQualityLabelBitrate = 'bitrate';
|
||||
static const String libraryQualityLabelBitDepth = 'bit_depth';
|
||||
static const String libraryQualityLabelBitDepthBitrate = 'bit_depth_bitrate';
|
||||
|
||||
final String defaultService;
|
||||
final String audioQuality;
|
||||
@@ -41,7 +42,8 @@ class AppSettings {
|
||||
/// 'last' (keep last used), 'all', 'albums', 'singles', or 'playlists'.
|
||||
final String defaultLibraryView;
|
||||
|
||||
/// Library badge text: measured bitrate or the legacy bit depth/sample rate.
|
||||
/// Library badge text: measured bitrate, bit depth/sample rate, or the
|
||||
/// combined bit depth/bitrate label.
|
||||
final String libraryQualityLabelMode;
|
||||
final bool askQualityBeforeDownload;
|
||||
final bool enableLogging;
|
||||
|
||||
@@ -380,9 +380,13 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
}
|
||||
|
||||
String _normalizeLibraryQualityLabelMode(String value) {
|
||||
return value == AppSettings.libraryQualityLabelBitDepth
|
||||
? AppSettings.libraryQualityLabelBitDepth
|
||||
: AppSettings.libraryQualityLabelBitrate;
|
||||
return switch (value) {
|
||||
AppSettings.libraryQualityLabelBitDepth =>
|
||||
AppSettings.libraryQualityLabelBitDepth,
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate =>
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate,
|
||||
_ => AppSettings.libraryQualityLabelBitrate,
|
||||
};
|
||||
}
|
||||
|
||||
String _normalizeExtensionVerificationBrowserMode(String value) {
|
||||
|
||||
@@ -404,6 +404,10 @@ class _LibrarySettingsPageState extends ConsumerState<LibrarySettingsPage> {
|
||||
return '${context.l10n.audioAnalysisBitDepth} & '
|
||||
'${context.l10n.audioAnalysisSampleRate}';
|
||||
}
|
||||
if (mode == AppSettings.libraryQualityLabelBitDepthBitrate) {
|
||||
return '${context.l10n.audioAnalysisBitDepth} & '
|
||||
'${context.l10n.trackConvertBitrate}';
|
||||
}
|
||||
return context.l10n.trackConvertBitrate;
|
||||
}
|
||||
|
||||
@@ -421,6 +425,12 @@ class _LibrarySettingsPageState extends ConsumerState<LibrarySettingsPage> {
|
||||
'${context.l10n.audioAnalysisBitDepth} & '
|
||||
'${context.l10n.audioAnalysisSampleRate}',
|
||||
),
|
||||
(
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate,
|
||||
Icons.multiline_chart_rounded,
|
||||
'${context.l10n.audioAnalysisBitDepth} & '
|
||||
'${context.l10n.trackConvertBitrate}',
|
||||
),
|
||||
];
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
|
||||
@@ -5,9 +5,13 @@ import 'package:spotiflac_android/utils/string_utils.dart';
|
||||
const highQualityBadgeBitrateThresholdKbps = 900;
|
||||
|
||||
String normalizeLibraryQualityLabelMode(String? mode) {
|
||||
return mode == AppSettings.libraryQualityLabelBitDepth
|
||||
? AppSettings.libraryQualityLabelBitDepth
|
||||
: AppSettings.libraryQualityLabelBitrate;
|
||||
return switch (mode) {
|
||||
AppSettings.libraryQualityLabelBitDepth =>
|
||||
AppSettings.libraryQualityLabelBitDepth,
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate =>
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate,
|
||||
_ => AppSettings.libraryQualityLabelBitrate,
|
||||
};
|
||||
}
|
||||
|
||||
/// Builds a Library label from metadata already held in memory. Lossy formats
|
||||
@@ -21,22 +25,61 @@ String? buildLibraryAudioQualityLabel({
|
||||
int? sampleRate,
|
||||
String? storedQuality,
|
||||
}) {
|
||||
final bitrateLabel = bitrateKbps != null && bitrateKbps > 0
|
||||
? buildDisplayAudioQuality(bitrateKbps: bitrateKbps, format: format)
|
||||
final stored = normalizeOptionalString(storedQuality);
|
||||
final storedBitrate = _bitrateFromStoredQuality(stored);
|
||||
final effectiveBitrate = bitrateKbps != null && bitrateKbps > 0
|
||||
? bitrateKbps
|
||||
: storedBitrate;
|
||||
final bitrateLabel = effectiveBitrate != null
|
||||
? buildDisplayAudioQuality(bitrateKbps: effectiveBitrate, format: format)
|
||||
: null;
|
||||
final bitDepthLabel =
|
||||
bitDepth != null && bitDepth > 0 && sampleRate != null && sampleRate > 0
|
||||
? buildDisplayAudioQuality(bitDepth: bitDepth, sampleRate: sampleRate)
|
||||
: null;
|
||||
final fallback = normalizeOptionalString(storedQuality);
|
||||
final normalizedMode = normalizeLibraryQualityLabelMode(mode);
|
||||
|
||||
final useBitDepth =
|
||||
normalizeLibraryQualityLabelMode(mode) ==
|
||||
AppSettings.libraryQualityLabelBitDepth &&
|
||||
!isLossyAudioFormat(format);
|
||||
return useBitDepth
|
||||
? bitDepthLabel ?? bitrateLabel ?? fallback
|
||||
: bitrateLabel ?? bitDepthLabel ?? fallback;
|
||||
if (isLossyAudioFormat(format)) {
|
||||
return bitrateLabel;
|
||||
}
|
||||
|
||||
return switch (normalizedMode) {
|
||||
AppSettings.libraryQualityLabelBitDepth =>
|
||||
bitDepthLabel ?? bitrateLabel ?? stored,
|
||||
AppSettings.libraryQualityLabelBitDepthBitrate =>
|
||||
_buildBitDepthBitrateLabel(
|
||||
bitDepth: bitDepth,
|
||||
bitrateKbps: effectiveBitrate,
|
||||
) ??
|
||||
bitrateLabel ??
|
||||
bitDepthLabel ??
|
||||
stored,
|
||||
// Do not display bit depth/sample rate while the user selected bitrate.
|
||||
// Legacy rows are backfilled separately; a stored measured bitrate remains
|
||||
// usable while that migration completes.
|
||||
_ => bitrateLabel,
|
||||
};
|
||||
}
|
||||
|
||||
int? _bitrateFromStoredQuality(String? quality) {
|
||||
final match = RegExp(
|
||||
r'\b(\d+(?:\.\d+)?)\s*(k(?:bps)?|mbps)\b',
|
||||
caseSensitive: false,
|
||||
).firstMatch(quality ?? '');
|
||||
final value = double.tryParse(match?.group(1) ?? '');
|
||||
if (value == null || value <= 0) return null;
|
||||
final unit = match?.group(2)?.toLowerCase();
|
||||
return unit == 'mbps' ? (value * 1000).round() : value.round();
|
||||
}
|
||||
|
||||
String? _buildBitDepthBitrateLabel({int? bitDepth, int? bitrateKbps}) {
|
||||
if (bitDepth == null ||
|
||||
bitDepth <= 0 ||
|
||||
bitrateKbps == null ||
|
||||
bitrateKbps <= 0) {
|
||||
return null;
|
||||
}
|
||||
return '$bitDepth-bit/${bitrateKbps}kbps';
|
||||
}
|
||||
|
||||
/// Preserves the highlighted color used by legacy 24-bit Library badges while
|
||||
|
||||
Reference in New Issue
Block a user