mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-22 15:28:45 +02:00
The Material theme now draws its main surfaces with rounded Material Symbols: navigation, player, mini player, queue, settings, sheets, dialogs and shared controls. AppIcon maps legacy Icons to their symbol and keeps outlined glyphs unfilled. Mornye keeps its original icons. Icon buttons, text and filled buttons, dialog actions, sliders, the setup FAB and indeterminate spinners use the Material 3 Expressive components. Each wrapper falls back to the standard Flutter widget for Mornye, reduced motion and custom sizing, so existing layouts and hit areas stay intact.
138 lines
5.2 KiB
Dart
138 lines
5.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
|
import 'package:spotiflac_android/models/automix_options.dart';
|
|
import 'package:spotiflac_android/models/settings.dart';
|
|
import 'package:spotiflac_android/models/theme_settings.dart';
|
|
import 'package:spotiflac_android/providers/settings_provider.dart';
|
|
import 'package:spotiflac_android/widgets/automix_settings.dart';
|
|
import 'package:spotiflac_android/theme/app_theme.dart';
|
|
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
|
import 'package:spotiflac_android/widgets/app_bottom_sheet.dart';
|
|
import 'package:spotiflac_android/widgets/app_slider.dart';
|
|
|
|
void main() {
|
|
testWidgets(
|
|
'manual duration saves at end of drag and USB disables DSP controls',
|
|
(tester) async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
final container = ProviderContainer(
|
|
overrides: [
|
|
initialSettingsProvider.overrideWithValue(
|
|
const AppSettings(
|
|
autoMix: true,
|
|
autoMixDuration: 5,
|
|
autoMixEffect: AutoMixEffect.custom,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
addTearDown(container.dispose);
|
|
await tester.pumpWidget(
|
|
UncontrolledProviderScope(
|
|
container: container,
|
|
child: const MaterialApp(
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(
|
|
body: SingleChildScrollView(child: AutoMixSettings()),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
final slider = tester.widget<AppSlider>(find.byType(AppSlider).first);
|
|
slider.onChanged!(45);
|
|
await tester.pump();
|
|
expect(container.read(settingsProvider).autoMixDuration, 5);
|
|
expect(find.text('Mix duration: 45 s'), findsOneWidget);
|
|
slider.onChangeEnd!(45);
|
|
await tester.pump();
|
|
expect(container.read(settingsProvider).autoMixDuration, 45);
|
|
container.read(settingsProvider.notifier).setUsbBitPerfect(true);
|
|
await tester.pump();
|
|
for (final slider in tester.widgetList<AppSlider>(
|
|
find.byType(AppSlider),
|
|
)) {
|
|
expect(slider.onChanged, isNull);
|
|
}
|
|
await tester.tap(find.text('Transition effect'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.byType(BottomSheet), findsNothing);
|
|
expect(tester.takeException(), isNull);
|
|
},
|
|
);
|
|
|
|
for (final mornye in [false, true]) {
|
|
testWidgets(
|
|
'effect picker follows app theme and saves selection ($mornye)',
|
|
(tester) async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
tester.view.physicalSize = const Size(350, 600);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final container = ProviderContainer(
|
|
overrides: [
|
|
initialSettingsProvider.overrideWithValue(
|
|
const AppSettings(autoMix: true),
|
|
),
|
|
],
|
|
);
|
|
addTearDown(container.dispose);
|
|
await tester.pumpWidget(
|
|
UncontrolledProviderScope(
|
|
container: container,
|
|
child: MaterialApp(
|
|
theme: mornye
|
|
? MornyeTheme.build(
|
|
Brightness.dark,
|
|
accent: MornyeAccent.blue,
|
|
)
|
|
: AppTheme.light(seedColor: Colors.blue),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: const MornyeSettingsTheme(
|
|
child: Scaffold(
|
|
body: SingleChildScrollView(child: AutoMixSettings()),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('Transition effect'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.byType(AppBottomSheet), findsOneWidget);
|
|
expect(find.byType(AppSheetOption), findsNWidgets(6));
|
|
final context = tester.element(find.byType(AppBottomSheet));
|
|
expect(context.isMornye, mornye);
|
|
final selected = tester
|
|
.widgetList<AppSheetOption>(find.byType(AppSheetOption))
|
|
.singleWhere((option) => option.trailing != null);
|
|
expect((selected.title as Text).data, 'Auto');
|
|
expect(
|
|
(selected.trailing as Icon).color,
|
|
Theme.of(context).colorScheme.primary,
|
|
);
|
|
final custom = find.descendant(
|
|
of: find.byType(AppBottomSheet),
|
|
matching: find.text('Custom'),
|
|
);
|
|
await tester.ensureVisible(custom);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(custom);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
container.read(settingsProvider).autoMixEffect,
|
|
AutoMixEffect.custom,
|
|
);
|
|
expect(find.byType(BottomSheet), findsNothing);
|
|
expect(find.text('Custom'), findsOneWidget);
|
|
expect(find.byType(AppSlider), findsNWidgets(2));
|
|
expect(tester.takeException(), isNull);
|
|
},
|
|
);
|
|
}
|
|
}
|