Files
SpotiFLAC-Mobile/test/native_glass_metrics_test.dart
zarzet 55a390d679 fix(ui): correct glass shader coordinates on scaled tablets
Use native window metrics for glass shaders while preserving scaled layout metrics for their content. Cover fullscreen tablet orientations and resizing to a compact window.

Fixes #597
2026-09-25 21:11:30 +07:00

107 lines
3.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:liquid_glass_easy/liquid_glass_easy.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
import 'package:spotiflac_android/utils/adaptive_layout.dart';
import 'package:spotiflac_android/widgets/app_switch.dart';
import 'package:spotiflac_android/widgets/mornye_chrome.dart';
void main() {
testWidgets('glass uses window pixels while tablet content keeps its scale', (
tester,
) async {
tester.view.devicePixelRatio = 2;
tester.view.padding = const FakeViewPadding(bottom: 40);
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
addTearDown(tester.view.resetPadding);
MediaQueryData? contentMetrics;
Future<void> pumpAt(Size size) async {
tester.view.physicalSize = size * 2;
await tester.pumpWidget(
ProviderScope(
child: MaterialApp(
theme: MornyeTheme.build(Brightness.dark),
builder: (context, child) => AdaptiveUiScaler(child: child!),
home: Scaffold(
body: Column(
children: [
MornyeGlass(
blurEnabled: true,
child: Builder(
builder: (context) {
contentMetrics = MediaQuery.of(context);
return const SizedBox(width: 200, height: 50);
},
),
),
MornyeSegmentedControl(
labels: const ['One', 'Two'],
selectedIndex: 0,
onChanged: (_) {},
),
AppSwitch(value: true, onChanged: (_) {}),
MornyeTabBar(
destinations: const [
NavigationDestination(
icon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.music_note),
label: 'Library',
),
],
selectedIndex: 0,
onSelected: (_) {},
blurEnabled: true,
),
],
),
),
),
),
);
await tester.pumpAndSettle();
}
// Full-screen tablet in both orientations, compact tablet, then a pop-up
// window and back. Resizing must update the shader without disabling glass.
for (final size in [
const Size(1400, 876),
const Size(876, 1400),
const Size(700, 1000),
const Size(430, 850),
const Size(1400, 876),
]) {
await pumpAt(size);
final scale = adaptiveUiScaleForSize(size);
expect(contentMetrics!.size, size / scale);
expect(contentMetrics!.devicePixelRatio, 2 * scale);
expect(contentMetrics!.padding.bottom, closeTo(20 / scale, 0.01));
for (final type in [
LiquidGlassLens,
LiquidGlassTabBar,
LiquidGlassSwitch,
]) {
final glass = find.byType(type);
expect(glass, findsWidgets);
for (final element in glass.evaluate()) {
final metrics = MediaQuery.of(element);
expect(metrics.size, size, reason: '$type at $size');
expect(metrics.devicePixelRatio, 2, reason: '$type at $size');
expect(metrics.textScaler, contentMetrics!.textScaler);
expect(metrics.highContrast, contentMetrics!.highContrast);
expect(metrics.disableAnimations, contentMetrics!.disableAnimations);
}
}
final content = tester.getRect(find.byType(MornyeGlass).first);
expect(content.width, closeTo(200 * scale, 0.01));
expect(content.height, closeTo(50 * scale, 0.01));
expect(tester.takeException(), isNull);
}
});
}