refactor(providers): move UI-declared providers to lib/providers

The listening summary and system volume providers lived in UI files.
They move verbatim to lib/providers with the same names; the old files
re-export them so tests and other importers are unchanged.
This commit is contained in:
zarzet committed 2026-10-19 00:56:52 +07:00
1 parent c10c0ab5f5
commit 8af7efb6ce
4 files changed
+53 -41

No files matched your search

@@ -0,0 +1,14 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/services/listening_statistics.dart';
final listeningSummaryProvider = FutureProvider.autoDispose
.family<ListeningSummary, ({int days, int year})>((ref, period) async {
await listeningRecorder.flush();
final now = DateTime.now();
final tomorrow = DateTime(now.year, now.month, now.day + 1);
final start = period.days == 0
? DateTime(period.year)
: DateTime(now.year, now.month, now.day - period.days + 1);
final end = period.days == 0 ? DateTime(period.year + 1) : tomorrow;
return ListeningStatisticsStore.instance.load(start, end);
});
+35
View File
@@ -0,0 +1,35 @@
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/services/music_playback_deck.dart';
import 'package:spotiflac_android/services/system_volume_service.dart';
import 'package:volume_controller/volume_controller.dart';
final usbVolumeProvider = StreamProvider.autoDispose<UsbVolumeState?>((ref) {
final events = StreamController<UsbVolumeState?>();
void changed() => events.add(usbHardwareVolume.value);
usbHardwareVolume.addListener(changed);
changed();
ref.onDispose(() {
usbHardwareVolume.removeListener(changed);
unawaited(events.close());
});
return events.stream;
});
/// A single shared subscription for the visible player, including hardware
/// volume-button changes. This controls system volume, not ReplayGain gain.
final systemVolumeProvider = StreamProvider.autoDispose<double>(
(ref) => SystemVolumeService.instance.changes,
);
final systemVolumeWriterProvider = Provider<Future<void> Function(double)>((
ref,
) {
return (value) {
if (usbHardwareVolume.value != null) return setUsbHardwareVolume(value);
final volume = VolumeController.instance;
volume.showSystemUI = false;
return volume.setVolume(value.clamp(0, 1));
};
});
+2 -11
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/listening_statistics_provider.dart';
import 'package:spotiflac_android/providers/settings_provider.dart';
import 'package:spotiflac_android/screens/listening_rewind_screen.dart';
import 'package:spotiflac_android/services/listening_statistics.dart';
@@ -22,17 +23,7 @@ import 'package:spotiflac_android/widgets/app_sliver_header.dart';
import 'package:spotiflac_android/widgets/player_artwork.dart';
import 'package:spotiflac_android/widgets/settings_group.dart';
final listeningSummaryProvider = FutureProvider.autoDispose
.family<ListeningSummary, ({int days, int year})>((ref, period) async {
await listeningRecorder.flush();
final now = DateTime.now();
final tomorrow = DateTime(now.year, now.month, now.day + 1);
final start = period.days == 0
? DateTime(period.year)
: DateTime(now.year, now.month, now.day - period.days + 1);
final end = period.days == 0 ? DateTime(period.year + 1) : tomorrow;
return ListeningStatisticsStore.instance.load(start, end);
});
export 'package:spotiflac_android/providers/listening_statistics_provider.dart';
class ListeningStatisticsScreen extends ConsumerStatefulWidget {
const ListeningStatisticsScreen({super.key});
+2 -30
View File
@@ -4,43 +4,15 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/system_volume_provider.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
import 'package:spotiflac_android/widgets/app_icon.dart';
import 'package:spotiflac_android/widgets/app_slider.dart';
import 'package:spotiflac_android/widgets/mornye_player_slider.dart';
import 'package:spotiflac_android/utils/logger.dart';
import 'package:volume_controller/volume_controller.dart';
import 'package:spotiflac_android/services/music_playback_deck.dart';
import 'package:spotiflac_android/services/system_volume_service.dart';
final usbVolumeProvider = StreamProvider.autoDispose<UsbVolumeState?>((ref) {
final events = StreamController<UsbVolumeState?>();
void changed() => events.add(usbHardwareVolume.value);
usbHardwareVolume.addListener(changed);
changed();
ref.onDispose(() {
usbHardwareVolume.removeListener(changed);
unawaited(events.close());
});
return events.stream;
});
/// A single shared subscription for the visible player, including hardware
/// volume-button changes. This controls system volume, not ReplayGain gain.
final systemVolumeProvider = StreamProvider.autoDispose<double>(
(ref) => SystemVolumeService.instance.changes,
);
final systemVolumeWriterProvider = Provider<Future<void> Function(double)>((
ref,
) {
return (value) {
if (usbHardwareVolume.value != null) return setUsbHardwareVolume(value);
final volume = VolumeController.instance;
volume.showSystemUI = false;
return volume.setVolume(value.clamp(0, 1));
};
});
export 'package:spotiflac_android/providers/system_volume_provider.dart';
/// System (or USB hardware) volume slider for the player and USB settings.
/// Mornye draws its glass slider between speaker glyphs; Material draws the