Prepare 0.7.9 with decisive Dock tap transitions
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
const appVersion = '0.7.8';
|
||||
const appBuildNumber = 34;
|
||||
const appVersion = '0.7.9';
|
||||
const appBuildNumber = 35;
|
||||
const appFilingNumber = '蜀ICP备2025169276号-5A';
|
||||
|
||||
@@ -35,7 +35,7 @@ class _GlassDockState extends State<GlassDock> with TickerProviderStateMixin {
|
||||
);
|
||||
late final AnimationController _tap = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 620),
|
||||
duration: const Duration(milliseconds: 420),
|
||||
);
|
||||
late final AnimationController _sway = AnimationController.unbounded(
|
||||
vsync: this,
|
||||
@@ -212,7 +212,7 @@ class _GlassDockState extends State<GlassDock> with TickerProviderStateMixin {
|
||||
_motion.animateWith(
|
||||
SpringSimulation(
|
||||
springyTap
|
||||
? const SpringDescription(mass: 1, stiffness: 350, damping: 20)
|
||||
? const SpringDescription(mass: 1, stiffness: 620, damping: 36)
|
||||
: const SpringDescription(mass: 1, stiffness: 360, damping: 26),
|
||||
_position,
|
||||
index.toDouble(),
|
||||
|
||||
@@ -12,7 +12,7 @@ class TabDeck extends StatefulWidget {
|
||||
class _TabDeckState extends State<TabDeck> with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _motion = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 330),
|
||||
duration: const Duration(milliseconds: 240),
|
||||
value: 1,
|
||||
);
|
||||
int? _outgoing;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
name: hepan_everyday
|
||||
description: TPSchedule 学生课表
|
||||
publish_to: none
|
||||
version: 0.7.8+34
|
||||
version: 0.7.9+35
|
||||
environment:
|
||||
sdk: ^3.13.5
|
||||
dependencies:
|
||||
|
||||
@@ -11,6 +11,30 @@ import 'navigation_test.dart' show uiController;
|
||||
|
||||
void main() {
|
||||
setUpAll(tzdata.initializeTimeZones);
|
||||
testWidgets(
|
||||
'tap reaches its page promptly and finishes the glass pulse within 480ms',
|
||||
(tester) async {
|
||||
await tester.pumpWidget(_dock());
|
||||
await tester.pumpAndSettle();
|
||||
final lens = find.byType(GlassRefraction).last;
|
||||
final rest = tester.getSize(lens);
|
||||
final target = tester.getCenter(find.byIcon(Icons.assignment_rounded)).dx;
|
||||
await tester.tap(find.byIcon(Icons.assignment_rounded));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 160));
|
||||
expect((tester.getCenter(lens).dx - target).abs(), lessThan(7));
|
||||
for (var i = 0; i < 20; i++) {
|
||||
await tester.pump(const Duration(milliseconds: 16));
|
||||
}
|
||||
expect(
|
||||
find.byKey(const ValueKey('dock-symbol-refraction')),
|
||||
findsNothing,
|
||||
);
|
||||
expect(tester.getSize(lens).width, closeTo(rest.width, 0.5));
|
||||
expect(tester.getCenter(lens).dx, closeTo(target, 0.6));
|
||||
await tester.pumpAndSettle();
|
||||
},
|
||||
);
|
||||
testWidgets(
|
||||
'moving lens refracts symbols above the icon row and releases cleanly',
|
||||
(tester) async {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hepan_everyday/widgets/glass_dock.dart';
|
||||
import 'package:hepan_everyday/widgets/tab_deck.dart';
|
||||
import 'package:hepan_everyday/app/hepan_app.dart';
|
||||
import 'package:hepan_everyday/features/timetable/timetable_page.dart';
|
||||
import 'package:timezone/data/latest.dart' as tzdata;
|
||||
@@ -9,6 +10,31 @@ import 'navigation_test.dart' show uiController;
|
||||
|
||||
void main() {
|
||||
setUpAll(tzdata.initializeTimeZones);
|
||||
testWidgets(
|
||||
'tab content finishes within one frame of 240ms and retains page state',
|
||||
(tester) async {
|
||||
Widget deck(int index) => MaterialApp(
|
||||
home: Scaffold(
|
||||
body: TabDeck(
|
||||
index: index,
|
||||
children: const [TextField(), Text('新页面')],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(deck(0));
|
||||
await tester.enterText(find.byType(TextField), '保留内容');
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
await tester.pumpWidget(deck(1));
|
||||
await tester.pump(); // Start the transition clock before advancing it.
|
||||
await tester.pump(const Duration(milliseconds: 240));
|
||||
await tester.pump(const Duration(milliseconds: 16));
|
||||
expect(find.byType(TextField), findsNothing);
|
||||
expect(find.text('新页面'), findsOneWidget);
|
||||
await tester.pumpWidget(deck(0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('保留内容'), findsOneWidget);
|
||||
},
|
||||
);
|
||||
testWidgets('only the selected tab is blue, including during glass travel', (
|
||||
tester,
|
||||
) async {
|
||||
|
||||
Reference in New Issue
Block a user