66//
77// SPDX-License-Identifier: EUPL-1.2
88
9+ import 'dart:async' ;
910import 'dart:math' ;
1011
1112import 'package:bloc_provider/bloc_provider.dart' ;
13+ import 'package:date/date.dart' ;
1214import 'package:flutter/cupertino.dart' ;
1315import 'package:flutter/foundation.dart' ;
1416import 'package:flutter/gestures.dart' ;
@@ -49,10 +51,9 @@ class TimetablePage extends StatelessWidget {
4951 static const tag = "timetable-page" ;
5052 static const days = 5 ;
5153
52- final today = TimetableDateHelper .dateBeginThisWeek ();
5354 static const timetableScale = 1.00 ;
5455
55- TimetablePage ({super .key});
56+ const TimetablePage ({super .key});
5657
5758 String getAdUnitId (BuildContext context) {
5859 if (kDebugMode) {
@@ -143,8 +144,8 @@ class _SettingsIcon extends StatelessWidget {
143144 }
144145}
145146
146- class TimeTableUnit extends StatelessWidget {
147- TimeTableUnit ({
147+ class TimeTableUnit extends StatefulWidget {
148+ const TimeTableUnit ({
148149 super .key,
149150 required this .groupInfos,
150151 required this .lessons,
@@ -155,12 +156,60 @@ class TimeTableUnit extends StatelessWidget {
155156 final List <Lesson > lessons;
156157 final TimetableConfig timetableConfig;
157158
158- final today = TimetableDateHelper .dateBeginThisWeek ();
159+ @override
160+ State <TimeTableUnit > createState () => _TimeTableUnitState ();
161+ }
162+
163+ class _TimeTableUnitState extends State <TimeTableUnit > {
164+ late final Date _today = Date .today ();
165+ late final Date _startOfCurrentWeek = TimetableDateHelper .dateBeginThisWeek (
166+ today: _today,
167+ );
168+ late final Date _endOfCurrentWeek = TimetableDateHelper .dateAddDays (
169+ _startOfCurrentWeek,
170+ 6 ,
171+ );
172+ final PageController _pageController = PageController ();
173+ late StreamSubscription <List <CalendricalEvent >>? _initialWeekSub;
174+
175+ void _maybeJumpToUpcomingWeek (Iterable <CalendricalEvent > events) {
176+ final shouldOpenUpcomingWeek = TimetableDateHelper .shouldOpenUpcomingWeek (
177+ today: _today,
178+ enabledWeekDays: widget.timetableConfig.getEnabledWeekDays (),
179+ isFeatureEnabled:
180+ widget.timetableConfig.openUpcomingWeekOnNonSchoolDays (),
181+ eventDatesInCurrentWeek: events.map ((e) => e.date),
182+ );
183+
184+ if (! shouldOpenUpcomingWeek || ! mounted) return ;
185+ _pageController.jumpToPage (1 );
186+ }
159187
160188 @override
161- Widget build (BuildContext context) {
162- final bloc = BlocProvider .of <TimetableBloc >(context);
189+ void initState () {
190+ super .initState ();
191+
192+ WidgetsBinding .instance.addPostFrameCallback ((_) {
193+ if (! mounted) return ;
163194
195+ final bloc = context.read <TimetableBloc >();
196+ _initialWeekSub = bloc
197+ .events (_startOfCurrentWeek, endDate: _endOfCurrentWeek)
198+ .where ((events) => events.isNotEmpty || true )
199+ .take (1 )
200+ .listen (_maybeJumpToUpcomingWeek);
201+ });
202+ }
203+
204+ @override
205+ void dispose () {
206+ _initialWeekSub? .cancel ();
207+ _pageController.dispose ();
208+ super .dispose ();
209+ }
210+
211+ @override
212+ Widget build (BuildContext context) {
164213 return PageView .builder (
165214 // Users expect to be able to drag the timetable horizontally to the
166215 // next/previous week via mouse as this is old behavior.
@@ -170,25 +219,31 @@ class TimeTableUnit extends StatelessWidget {
170219 // workaround to explicitly re-enable this behavior. See:
171220 // https://docs.flutter.dev/release/breaking-changes/default-scroll-behavior-drag
172221 //
173- // In the future we might add explicit buttons to go forward or backwards
174- // a week in the timetable - in this case desktop might remove this
175- // behavior.
222+ // In the future we might add explicit buttons to go forward or
223+ // backwards a week in the timetable - in this case desktop might
224+ // remove this behavior.
176225 scrollBehavior: ScrollConfiguration .of (context).copyWith (
177226 dragDevices: {PointerDeviceKind .touch, PointerDeviceKind .mouse},
178227 ),
228+ controller: _pageController,
179229 itemBuilder: (context, index) {
180- final startOfWeek = TimetableDateHelper .dateAddWeeks (today, index);
230+ final startOfWeek = TimetableDateHelper .dateAddWeeks (
231+ _startOfCurrentWeek,
232+ index,
233+ );
181234 final endDate = TimetableDateHelper .dateAddDays (startOfWeek, 6 );
182235 final daysList = TimetableDateHelper .generateDaysList (
183236 startOfWeek,
184237 endDate,
185- timetableConfig.getEnabledWeekDays (),
238+ widget. timetableConfig.getEnabledWeekDays (),
186239 );
187240
188241 final filteredLessonsList = getFilteredLessonList (
189- lessons,
190- timetableConfig.getWeekType (daysList.first),
242+ widget. lessons,
243+ widget. timetableConfig.getWeekType (daysList.first),
191244 );
245+
246+ final bloc = BlocProvider .of <TimetableBloc >(context);
192247 return StreamBuilder <List <CalendricalEvent >>(
193248 stream: bloc.events (startOfWeek, endDate: endDate),
194249 builder: (context, snapshot) {
@@ -197,13 +252,13 @@ class TimeTableUnit extends StatelessWidget {
197252 filteredLessonsList,
198253 daysList,
199254 events,
200- groupInfos,
255+ widget. groupInfos,
201256 );
202257 return TimetableWeekView (
203258 dates: daysList,
204259 elements: [...builder.buildElements ()],
205- config: timetableConfig,
206- periods: timetableConfig.getPeriods (),
260+ config: widget. timetableConfig,
261+ periods: widget. timetableConfig.getPeriods (),
207262 );
208263 },
209264 );
0 commit comments