diff --git a/lib/components/event_list_tile.dart b/lib/components/event_list_tile.dart index 0f748c7..69f8cf4 100644 --- a/lib/components/event_list_tile.dart +++ b/lib/components/event_list_tile.dart @@ -20,13 +20,14 @@ class EventListTile extends StatelessWidget { FavoritesProvider favProvider = Provider.of(context, listen: true); bool isFavorite = favProvider.isInFavorites(item.name); + String imageUrl = item.imageUrl ?? ''; return ListTile( - leading: item.imageUrl!.startsWith("http") ? + leading: imageUrl.startsWith("http") ? SizedBox( width: 100.0, // Diameter of CircleAvatar height: 100.0, child: CachedNetworkImage( - imageUrl: item.imageUrl ?? '', + imageUrl: imageUrl, placeholder: (context, url) => FittedBox( child: CircularProgressIndicator(), diff --git a/lib/controls/nav_bar.dart b/lib/controls/nav_bar.dart index acbeeaf..0415a1a 100644 --- a/lib/controls/nav_bar.dart +++ b/lib/controls/nav_bar.dart @@ -29,10 +29,10 @@ class NavBar extends StatefulWidget { static final List _widgetOptions = [ const HomePage(), // 0 const EventsPage(), // 1 - const TracksPage(), // 2 - const SpeakersPage(), // 3 - const RoomsPage(), // 4 - const PreferencesPage(), // 5 + TracksPage(), // 2 + SpeakersPage(), // 3 + RoomsPage(), // 4 + PreferencesPage(), // 5 const TravelPage(), // 6 const AboutPage(), // 7 ]; diff --git a/lib/data/appProviders/preferences_provider.dart b/lib/data/appProviders/preferences_provider.dart index 89906c5..ef188a0 100644 --- a/lib/data/appProviders/preferences_provider.dart +++ b/lib/data/appProviders/preferences_provider.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart' show SharedPreferences; @@ -68,6 +69,28 @@ class PreferencesProvider { await prefs.setBool(_calendarColorByRoomKey, value); } + // --------------------------------------------------------- + static const String _useTestDataKey = 'useTestData'; + static final ValueNotifier useTestDataNotifier = ValueNotifier(false); + + static Future loadUseTestData() async { + bool value = false; + if (kDebugMode) { + final prefs = await SharedPreferences.getInstance(); + value = prefs.getBool(_useTestDataKey) ?? false; // Default + } + useTestDataNotifier.value = value; + } + + static Future setUseTestData(bool value) async { + if (kDebugMode) { + useTestDataNotifier.value = value; + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(_useTestDataKey, value); + } else { + useTestDataNotifier.value = false; + } + } // --------------------------------------------------------- static const String _isDayViewKey = 'isDayView'; diff --git a/lib/data/dataProviders/events_provider.dart b/lib/data/dataProviders/events_provider.dart index 68860d0..2f4615d 100644 --- a/lib/data/dataProviders/events_provider.dart +++ b/lib/data/dataProviders/events_provider.dart @@ -1,8 +1,10 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/gsheets_provider.dart'; import 'package:iccm_eu_app/data/model/event_data.dart'; +import 'package:iccm_eu_app/data/testData/test_data.dart'; import 'package:iccm_eu_app/utils/debug.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -27,16 +29,21 @@ class EventsProvider with ChangeNotifier { } void updateCache() { - // Process raw data from GsheetsProvider and update _tracks - var data = _gsheetsProvider.getEventData(); - if (data != null && data.isNotEmpty) { + if (kDebugMode && PreferencesProvider.useTestDataNotifier.value) { _cacheClear(); - for (final itemData in data) { - _cacheAdd(EventData.fromItemData(itemData)); + for (EventData item in TestData.getEvents()) { + _cacheAdd(item); + } + } else { // Process raw data from GsheetsProvider and update _tracks + var data = _gsheetsProvider.getEventData(); + if (data != null && data.isNotEmpty) { + _cacheClear(); + for (final itemData in data) { + _cacheAdd(EventData.fromItemData(itemData)); + } } - _commit(); } - notifyListeners(); + _commit(); } Future _loadCache() async { diff --git a/lib/data/dataProviders/gsheets_provider.dart b/lib/data/dataProviders/gsheets_provider.dart index e191a2f..e34eea5 100644 --- a/lib/data/dataProviders/gsheets_provider.dart +++ b/lib/data/dataProviders/gsheets_provider.dart @@ -1,9 +1,9 @@ import 'dart:convert'; import 'dart:core'; +import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:crypto/crypto.dart'; -import 'package:flutter/material.dart'; import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/events_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/home_provider.dart'; @@ -172,33 +172,34 @@ class GsheetsProvider with ChangeNotifier { return; } - List workSheetTitles = []; - workSheetTitles.add(EventsProvider.worksheetTitle); - workSheetTitles.add(RoomsProvider.worksheetTitle); - workSheetTitles.add(SpeakersProvider.worksheetTitle); - workSheetTitles.add(TracksProvider.worksheetTitle); - workSheetTitles.add(HomeProvider.worksheetTitle); - workSheetTitles.add(TravelProvider.worksheetTitle); - workSheetTitles.add(TravelDetailsProvider.worksheetTitle); + if (!kDebugMode || !PreferencesProvider.useTestDataNotifier.value) { + List workSheetTitles = []; + workSheetTitles.add(EventsProvider.worksheetTitle); + workSheetTitles.add(RoomsProvider.worksheetTitle); + workSheetTitles.add(SpeakersProvider.worksheetTitle); + workSheetTitles.add(TracksProvider.worksheetTitle); + workSheetTitles.add(HomeProvider.worksheetTitle); + workSheetTitles.add(TravelProvider.worksheetTitle); + workSheetTitles.add(TravelDetailsProvider.worksheetTitle); - await _readWorksheets( - worksheetTitles: workSheetTitles, - errorProvider: errorProvider); + await _readWorksheets( + worksheetTitles: workSheetTitles, + errorProvider: errorProvider); - // Terminate if data is empty - if (_countDataObjects(_rawData) == 0) { - _isFetchingData = false; - Debug.msg("Fetch: Not data found."); - return; - } - - String cachedChecksum = await PreferencesProvider.cachedChecksum; - String dataChecksum = _generateChecksum(_rawData); + // Terminate if data is empty + if (_countDataObjects(_rawData) == 0) { + _isFetchingData = false; + Debug.msg("Fetch: Not data found."); + return; + } - if (cachedChecksum != dataChecksum || force) { - await PreferencesProvider.setCachedChecksum(dataChecksum); - await PreferencesProvider.setLastUpdated(now); + String cachedChecksum = await PreferencesProvider.cachedChecksum; + String dataChecksum = _generateChecksum(_rawData); + if (cachedChecksum != dataChecksum || force) { + await PreferencesProvider.setCachedChecksum(dataChecksum); + await PreferencesProvider.setLastUpdated(now); + } } notifyListeners(); Debug.msg("Fetch completed successfully."); diff --git a/lib/data/dataProviders/rooms_provider.dart b/lib/data/dataProviders/rooms_provider.dart index 32d8098..493bb1c 100644 --- a/lib/data/dataProviders/rooms_provider.dart +++ b/lib/data/dataProviders/rooms_provider.dart @@ -1,9 +1,11 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/gsheets_provider.dart'; import 'package:iccm_eu_app/data/definitions/item_colors_dictionary.dart'; import 'package:iccm_eu_app/data/model/room_data.dart'; +import 'package:iccm_eu_app/data/testData/test_data.dart'; import 'package:iccm_eu_app/utils/debug.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -29,16 +31,22 @@ class RoomsProvider with ChangeNotifier { } void updateCache() { - // Process raw data from GsheetsProvider and update _tracks - var data = _gsheetsProvider.getRoomData(); - if (data != null && data.isNotEmpty) { + if (kDebugMode && PreferencesProvider.useTestDataNotifier.value) { _cacheClear(); - for (final itemData in data) { - _cacheAdd(RoomData.fromItemData(itemData)); + for (RoomData item in TestData.rooms) { + _cacheAdd(item); + } + } else { + // Process raw data from GsheetsProvider and update _tracks + var data = _gsheetsProvider.getRoomData(); + if (data != null && data.isNotEmpty) { + _cacheClear(); + for (final itemData in data) { + _cacheAdd(RoomData.fromItemData(itemData)); + } } - _commit(); } - notifyListeners(); + _commit(); } Future _loadCache() async { diff --git a/lib/data/dataProviders/speakers_provider.dart b/lib/data/dataProviders/speakers_provider.dart index 56f463e..3e8f436 100644 --- a/lib/data/dataProviders/speakers_provider.dart +++ b/lib/data/dataProviders/speakers_provider.dart @@ -1,8 +1,10 @@ import 'dart:convert'; -import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/gsheets_provider.dart'; import 'package:iccm_eu_app/data/model/speaker_data.dart'; +import 'package:iccm_eu_app/data/testData/test_data.dart'; import 'package:iccm_eu_app/utils/debug.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -27,16 +29,22 @@ class SpeakersProvider with ChangeNotifier { } void updateCache() { - // Process raw data from GsheetsProvider and update _tracks - var data = _gsheetsProvider.getSpeakerData(); - if (data != null && data.isNotEmpty) { + if (kDebugMode && PreferencesProvider.useTestDataNotifier.value) { _cacheClear(); - for (final itemData in data) { - _cacheAdd(SpeakerData.fromItemData(itemData)); + for (SpeakerData item in TestData.speakers) { + _cacheAdd(item); + } + } else { + // Process raw data from GsheetsProvider and update _tracks + var data = _gsheetsProvider.getSpeakerData(); + if (data != null && data.isNotEmpty) { + _cacheClear(); + for (final itemData in data) { + _cacheAdd(SpeakerData.fromItemData(itemData)); + } } - _commit(); } - notifyListeners(); + _commit(); } Future _loadCache() async { diff --git a/lib/data/dataProviders/tracks_provider.dart b/lib/data/dataProviders/tracks_provider.dart index 57bdd6d..da1b5e2 100644 --- a/lib/data/dataProviders/tracks_provider.dart +++ b/lib/data/dataProviders/tracks_provider.dart @@ -1,9 +1,11 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/gsheets_provider.dart'; import 'package:iccm_eu_app/data/definitions/item_colors_dictionary.dart'; import 'package:iccm_eu_app/data/model/track_data.dart'; +import 'package:iccm_eu_app/data/testData/test_data.dart'; import 'package:iccm_eu_app/utils/debug.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -31,15 +33,24 @@ class TracksProvider with ChangeNotifier { } void updateCache() { - // Process raw data from GsheetsProvider and update _tracks - var data = _gsheetsProvider.getTrackData(); - if (data != null && data.isNotEmpty) { + if (kDebugMode && PreferencesProvider.useTestDataNotifier.value) { + Debug.msg("Updating TrackData cache from TestData ($kDebugMode, ${PreferencesProvider.useTestDataNotifier.value})."); _cacheClear(); - for (final itemData in data) { - _cacheAdd(TrackData.fromItemData(itemData)); + for (TrackData item in TestData.tracks) { + _cacheAdd(item); + } + } else { + Debug.msg("Updating TrackData cache from GSheets ($kDebugMode, ${PreferencesProvider.useTestDataNotifier.value})."); + // Process raw data from GsheetsProvider and update _tracks + var data = _gsheetsProvider.getTrackData(); + if (data != null && data.isNotEmpty) { + _cacheClear(); + for (final itemData in data) { + _cacheAdd(TrackData.fromItemData(itemData)); + } } - _commit(); } + _commit(); } Future _loadCache() async { diff --git a/lib/data/dataProviders/travel_details_provider.dart b/lib/data/dataProviders/travel_details_provider.dart index 844c815..1d5190c 100644 --- a/lib/data/dataProviders/travel_details_provider.dart +++ b/lib/data/dataProviders/travel_details_provider.dart @@ -67,7 +67,6 @@ class TravelDetailsProvider with ChangeNotifier { _cache.sort((a, b) => a.name.compareTo(b.name)); _saveCache(); _populateItemsFromCache(); - Debug.msg("Found ${_items.length} travel elements"); notifyListeners(); } diff --git a/lib/data/model/room_data.dart b/lib/data/model/room_data.dart index 091ccfe..a954c0a 100644 --- a/lib/data/model/room_data.dart +++ b/lib/data/model/room_data.dart @@ -11,6 +11,13 @@ class RoomData extends ModelItem { final String details; late ColorsData? colors; + RoomData({ + required this.imageUrl, + required this.name, + required this.details, + this.colors, + }); + RoomData._({ required this.imageUrl, required this.name, diff --git a/lib/data/model/speaker_data.dart b/lib/data/model/speaker_data.dart index 46e3eb2..b963cb6 100644 --- a/lib/data/model/speaker_data.dart +++ b/lib/data/model/speaker_data.dart @@ -9,6 +9,12 @@ class SpeakerData extends ModelItem { @override final String details; + SpeakerData({ + required this.imageUrl, + required this.name, + required this.details, + }); + SpeakerData._({ required this.imageUrl, required this.name, diff --git a/lib/data/model/track_data.dart b/lib/data/model/track_data.dart index aa66d97..935c578 100644 --- a/lib/data/model/track_data.dart +++ b/lib/data/model/track_data.dart @@ -11,6 +11,13 @@ class TrackData extends ModelItem { final String details; late ColorsData? colors; + TrackData({ + required this.imageUrl, + required this.name, + required this.details, + this.colors, + }); + TrackData._({ required this.imageUrl, required this.name, diff --git a/lib/data/testData/test_data.dart b/lib/data/testData/test_data.dart new file mode 100644 index 0000000..a15f86c --- /dev/null +++ b/lib/data/testData/test_data.dart @@ -0,0 +1,138 @@ + +import 'package:iccm_eu_app/data/model/event_data.dart'; +import 'package:iccm_eu_app/data/model/room_data.dart'; +import 'package:iccm_eu_app/data/model/speaker_data.dart'; +import 'package:iccm_eu_app/data/model/track_data.dart'; + + +class TestData { + static final List rooms = [ + RoomData( + name: 'Room 1', + details: 'First Room', + imageUrl: '', + ), + RoomData( + name: 'Room 2', + details: 'Second Room', + imageUrl: '', + ), + RoomData( + name: 'Room 3', + details: 'Third Room', + imageUrl: '', + ), + RoomData( + name: 'Room 4', + details: 'Fourth Room', + imageUrl: '', + ), + ]; + + static final List tracks = [ + TrackData( + name: 'Track 1', + details: 'First Track', + imageUrl: '', + ), + TrackData( + name: 'Track 2', + details: 'Second Track', + imageUrl: '', + ), + TrackData( + name: 'Track 3', + details: 'Third Track', + imageUrl: '', + ), + TrackData( + name: 'Track 4', + details: 'Fourth Track', + imageUrl: '', + ), + ]; + + static final List speakers = [ + SpeakerData( + name: 'Speaker 1', + details: 'First Speaker', + imageUrl: '', + ), + SpeakerData( + name: 'Speaker 2', + details: 'Second Speaker', + imageUrl: '', + ), + SpeakerData( + name: 'Speaker 3', + details: 'Third Speaker', + imageUrl: '', + ), + SpeakerData( + name: 'Speaker 4', + details: 'Fourth Speaker', + imageUrl: '', + ), + ]; + + static List getEvents() { + List items = []; + // From previous day to next day + // From 8:00 to 22:00 + // Schedule a series of events + // Around now(), add a series of short events + DateTime now = DateTime.now(); + DateTime scheduleStart = now.subtract(Duration( + hours: now.hour, + minutes: now.minute, + seconds: now.second, + milliseconds: now.millisecond, + )); + List scheduleDays = [ + scheduleStart.subtract(Duration(days: 1)), + scheduleStart, + scheduleStart.add(Duration(days: 1)), + ]; + int eventCount = 0; + TrackData track = tracks[0]; + SpeakerData? speaker = speakers[0]; + RoomData room = rooms[0]; + for (DateTime day in scheduleDays) { + DateTime startTime = day.add(Duration(hours: 8)); + while (startTime.hour < 22) { + Duration duration; + int parallel; + if (startTime.isAfter(now.subtract(Duration(hours: 1, minutes: 1))) && + startTime.isBefore(now.add(Duration(hours: 1, minutes: 1)))) { + duration = Duration(hours: 0, minutes: 30); + parallel = 3; + } else { + duration = Duration(hours: 1, minutes: 0); + parallel = 0; + } + DateTime endTime = startTime.add(duration); + for (int i = 0; i <= parallel; i++) { + items.add(EventData( + start: startTime, + end: endTime, + name: 'Event $eventCount', + details: 'Details', + track: track.name, + speaker: speaker?.name, + room: room.name, + )); + startTime = endTime; + track = tracks[eventCount % tracks.length]; + room = rooms[eventCount % rooms.length]; + if (eventCount % 2 == 0) { + speaker = speakers[eventCount % speakers.length]; + } else { + speaker = null; + } + eventCount ++; + } + } + } + return items; + } +} \ No newline at end of file diff --git a/lib/pages/event_details_page.dart b/lib/pages/event_details_page.dart index 098d278..8fa3e4f 100644 --- a/lib/pages/event_details_page.dart +++ b/lib/pages/event_details_page.dart @@ -63,6 +63,7 @@ class EventDetailsPage extends StatelessWidget { FavoritesProvider favProvider = Provider.of(context, listen: true); bool isFavorite = favProvider.isInFavorites(item.name); + String imageUrl = item.imageUrl ?? ''; return Scaffold( appBar: AppBar( @@ -76,9 +77,9 @@ class EventDetailsPage extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (item.imageUrl!.startsWith("http")) + if (imageUrl.startsWith("http")) CachedNetworkImage( - imageUrl: item.imageUrl ?? '', + imageUrl: imageUrl, imageBuilder: (context, imageProvider) => CircleAvatar( backgroundImage: imageProvider, diff --git a/lib/pages/events_page.dart b/lib/pages/events_page.dart index 55be77f..6beb925 100644 --- a/lib/pages/events_page.dart +++ b/lib/pages/events_page.dart @@ -107,11 +107,12 @@ class DayViewCalendarState extends State { @override void initState() { super.initState(); - _loadColorByRoom(); + _loadPreferences(); } - Future _loadColorByRoom() async { + Future _loadPreferences() async { PreferencesProvider.loadCalendarColorByRoom(); + PreferencesProvider.loadUseTestData(); } @override diff --git a/lib/pages/preferences_page.dart b/lib/pages/preferences_page.dart index 06174b7..a45cf3d 100644 --- a/lib/pages/preferences_page.dart +++ b/lib/pages/preferences_page.dart @@ -1,10 +1,21 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:iccm_eu_app/components/toggle_button.dart'; import 'package:iccm_eu_app/components/toggle_is_dark_mode.dart'; import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; +import 'package:iccm_eu_app/data/dataProviders/error_provider.dart'; +import 'package:iccm_eu_app/data/dataProviders/gsheets_provider.dart'; +import 'package:provider/provider.dart'; class PreferencesPage extends StatelessWidget { - const PreferencesPage({super.key}); + PreferencesPage({super.key}) { + _loadPreferences(); + } + + Future _loadPreferences() async { + PreferencesProvider.loadCalendarColorByRoom(); + PreferencesProvider.loadUseTestData(); + } @override Widget build(BuildContext context) { @@ -28,17 +39,26 @@ class PreferencesPage extends StatelessWidget { children: [ Text( 'Preferences', - style: Theme.of(context).textTheme.titleLarge, + style: Theme + .of(context) + .textTheme + .titleLarge, textAlign: TextAlign.center, ), SizedBox(height: 16), Text('Theme', - style: Theme.of(context).textTheme.titleLarge, + style: Theme + .of(context) + .textTheme + .titleLarge, ), ToggleIsDarkModeListTile(context: context), const Divider(), Text('Calendar Colors', - style: Theme.of(context).textTheme.titleLarge, + style: Theme + .of(context) + .textTheme + .titleLarge, ), ValueListenableBuilder( valueListenable: PreferencesProvider.calendarColorByRoomNotifier, @@ -53,6 +73,39 @@ class PreferencesPage extends StatelessWidget { ); }, ), + if (kDebugMode) + const Divider() + else + const SizedBox.shrink(), + if (kDebugMode) + Text('Test Data', + style: Theme + .of(context) + .textTheme + .titleLarge, + ) + else + const SizedBox.shrink(), + if (kDebugMode) + ValueListenableBuilder( + valueListenable: PreferencesProvider.useTestDataNotifier, + builder: (context, builderValue, child) { + return ToggleButtonListTile( + value: builderValue, + onChanged: (bool newValue) { + PreferencesProvider.setUseTestData(newValue); + Provider.of(context, listen: false).fetchData( + errorProvider: Provider.of(context, listen: false), + force: true, + ); + }, + title: 'Use Test Data', + toggleTitle: 'Test Data', + ); + }, + ) + else + const SizedBox.shrink(), // const Divider(), // const Text('Profile', // style: TextStyle( diff --git a/lib/pages/rooms_page.dart b/lib/pages/rooms_page.dart index 6bd3878..4f5e660 100644 --- a/lib/pages/rooms_page.dart +++ b/lib/pages/rooms_page.dart @@ -1,10 +1,17 @@ import 'package:flutter/material.dart'; import 'package:iccm_eu_app/components/room_list_tile.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/rooms_provider.dart'; import 'package:provider/provider.dart'; class RoomsPage extends StatelessWidget { - const RoomsPage({super.key}); + RoomsPage({super.key}) { + _loadPreferences(); + } + + Future _loadPreferences() async { + PreferencesProvider.loadUseTestData(); + } @override Widget build(BuildContext context) { diff --git a/lib/pages/speakers_page.dart b/lib/pages/speakers_page.dart index 958c40b..bd5a426 100644 --- a/lib/pages/speakers_page.dart +++ b/lib/pages/speakers_page.dart @@ -1,10 +1,17 @@ import 'package:flutter/material.dart'; import 'package:iccm_eu_app/components/speaker_list_tile.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/speakers_provider.dart'; import 'package:provider/provider.dart'; class SpeakersPage extends StatelessWidget { - const SpeakersPage({super.key}); + SpeakersPage({super.key}) { + _loadPreferences(); + } + + Future _loadPreferences() async { + PreferencesProvider.loadUseTestData(); + } @override Widget build(BuildContext context) { diff --git a/lib/pages/tracks_page.dart b/lib/pages/tracks_page.dart index c3860cb..deac908 100644 --- a/lib/pages/tracks_page.dart +++ b/lib/pages/tracks_page.dart @@ -1,10 +1,17 @@ import 'package:flutter/material.dart'; import 'package:iccm_eu_app/components/track_list_tile.dart'; +import 'package:iccm_eu_app/data/appProviders/preferences_provider.dart'; import 'package:iccm_eu_app/data/dataProviders/tracks_provider.dart'; import 'package:provider/provider.dart'; class TracksPage extends StatelessWidget { - const TracksPage({super.key}); + TracksPage({super.key}) { + _loadPreferences(); + } + + Future _loadPreferences() async { + PreferencesProvider.loadUseTestData(); + } @override Widget build(BuildContext context) {