Make compact Dock persistent and support week swipes

This commit is contained in:
Codex
2026-10-14 09:49:53 +08:00
parent fe23c65fd9
commit caf7abe0c0
11 changed files with 474 additions and 363 deletions
+31 -71
View File
@@ -59,31 +59,9 @@ class _Shell extends StatefulWidget {
class _ShellState extends State<_Shell> with WidgetsBindingObserver {
int _tab = 0;
bool _dockHidden = false;
double _scrollTravel = 0;
void _selectTab(int index) {
if (index == _tab) return;
setState(() {
_tab = index;
_dockHidden = false;
_scrollTravel = 0;
});
}
bool _scroll(ScrollNotification notification) {
if (_tab == 2 || notification.metrics.axis != Axis.vertical) return false;
if (notification is ScrollUpdateNotification &&
notification.dragDetails != null) {
final delta = notification.scrollDelta ?? 0;
if (delta.sign != _scrollTravel.sign) _scrollTravel = 0;
_scrollTravel += delta;
final hide = notification.metrics.pixels > 0 && _scrollTravel > 24;
final reveal = notification.metrics.pixels <= 0 || _scrollTravel < -16;
if ((hide && !_dockHidden) || (reveal && _dockHidden)) {
setState(() => _dockHidden = hide);
}
}
return false;
setState(() => _tab = index);
}
@override
@@ -274,35 +252,32 @@ class _ShellState extends State<_Shell> with WidgetsBindingObserver {
),
),
Expanded(
child: NotificationListener<ScrollNotification>(
onNotification: _scroll,
child: TabDeck(
index: _tab,
children: [
TimetablePage(
controller: widget.controller,
onSync: _school,
),
ExamsPage(
controller: widget.controller,
onSync: () {
_school(exams: true);
},
),
ProfilePage(
controller: widget.controller,
onLogin: _school,
onUpdateTerm: () => _school(chooseTerm: true),
authStatus: widget.school?.statusLabel ?? '未登录',
logoutLabel: widget.school?.logoutFailed == true
? '重试退出学校登录'
: '退出学校登录',
onLogout: widget.school?.canLogout == true
? _logout
: null,
),
],
),
child: TabDeck(
index: _tab,
children: [
TimetablePage(
controller: widget.controller,
onSync: _school,
),
ExamsPage(
controller: widget.controller,
onSync: () {
_school(exams: true);
},
),
ProfilePage(
controller: widget.controller,
onLogin: _school,
onUpdateTerm: () => _school(chooseTerm: true),
authStatus: widget.school?.statusLabel ?? '未登录',
logoutLabel: widget.school?.logoutFailed == true
? '重试退出学校登录'
: '退出学校登录',
onLogout: widget.school?.canLogout == true
? _logout
: null,
),
],
),
),
],
@@ -313,25 +288,10 @@ class _ShellState extends State<_Shell> with WidgetsBindingObserver {
right: 0,
bottom: 16 + MediaQuery.paddingOf(context).bottom,
child: Center(
child: IgnorePointer(
ignoring: _dockHidden,
child: ExcludeSemantics(
excluding: _dockHidden,
child: AnimatedSlide(
key: const Key('floating-dock'),
offset: _dockHidden
? const Offset(0, 1.8)
: Offset.zero,
duration: MediaQuery.disableAnimationsOf(context)
? Duration.zero
: const Duration(milliseconds: 360),
curve: Curves.easeInOutCubic,
child: GlassDock(
selectedIndex: _tab,
onSelected: _selectTab,
),
),
),
child: GlassDock(
key: const Key('floating-dock'),
selectedIndex: _tab,
onSelected: _selectTab,
),
),
),