From 031baca8295f5b03e04c0bf713897f267294bc0d Mon Sep 17 00:00:00 2001 From: Username * Date: Wed, 15 Nov 2023 21:18:28 +0100 Subject: [PATCH 01/17] feat: make some toggles into their own classes --- .../widgets/grid_day_views_toggle.dart | 23 +++++ .../widgets/navigation_bar_toggle.dart | 31 +++++++ .../widgets/rotation_week_toggle.dart | 50 ++++++++++ lib/screens/timetable_screen.dart | 93 +++++-------------- 4 files changed, 126 insertions(+), 71 deletions(-) create mode 100644 lib/components/widgets/grid_day_views_toggle.dart create mode 100644 lib/components/widgets/navigation_bar_toggle.dart create mode 100644 lib/components/widgets/rotation_week_toggle.dart diff --git a/lib/components/widgets/grid_day_views_toggle.dart b/lib/components/widgets/grid_day_views_toggle.dart new file mode 100644 index 0000000..dbd7f10 --- /dev/null +++ b/lib/components/widgets/grid_day_views_toggle.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +/// Toggle between day and grid/week views. +class GridDayViewsToggle extends HookWidget { + final ValueNotifier isGridView; + const GridDayViewsToggle({ + Key? key, + required this.isGridView, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return IconButton( + onPressed: () { + isGridView.value = !isGridView.value; + }, + selectedIcon: const Icon(Icons.view_agenda_outlined), + icon: const Icon(Icons.grid_view_outlined), + isSelected: isGridView.value, + ); + } +} diff --git a/lib/components/widgets/navigation_bar_toggle.dart b/lib/components/widgets/navigation_bar_toggle.dart new file mode 100644 index 0000000..f90b9d9 --- /dev/null +++ b/lib/components/widgets/navigation_bar_toggle.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:timetable/models/settings.dart'; + +/// Toggles the navbar. +class NavbarToggle extends HookConsumerWidget { + const NavbarToggle({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final settings = ref.read(settingsProvider.notifier); + final navbarToggle = ref.watch(settingsProvider).navbarVisible; + + return IconButton( + onPressed: () { + settings.updateNavbarVisible(!navbarToggle); + }, + selectedIcon: const Icon( + Icons.fullscreen, + size: 25, + ), + icon: const Icon( + Icons.close_fullscreen_outlined, + size: 20, + ), + isSelected: navbarToggle, + ); + } +} diff --git a/lib/components/widgets/rotation_week_toggle.dart b/lib/components/widgets/rotation_week_toggle.dart new file mode 100644 index 0000000..d9308a1 --- /dev/null +++ b/lib/components/widgets/rotation_week_toggle.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:timetable/constants/rotation_weeks.dart'; + +/// Toggles between all rotation weeks. +class RotationWeekToggle extends HookWidget { + final ValueNotifier rotationWeek; + const RotationWeekToggle({ + Key? key, + required this.rotationWeek, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final clickCount = useState(0); + List labels = [ + RotationWeeks.all, + RotationWeeks.a, + RotationWeeks.b, + ]; + + void changeLabel() { + clickCount.value++; + if (clickCount.value >= 3) { + clickCount.value = 0; + } + } + + return InkWell( + onTap: () { + changeLabel(); + rotationWeek.value = labels[clickCount.value]; + }, + borderRadius: BorderRadius.circular(50), + child: Ink( + width: 40, + height: 40, + child: Center( + child: Text( + getRotationWeekButtonLabel(labels[clickCount.value]), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + ), + ), + ); + } +} diff --git a/lib/screens/timetable_screen.dart b/lib/screens/timetable_screen.dart index 0381d69..a5df14f 100644 --- a/lib/screens/timetable_screen.dart +++ b/lib/screens/timetable_screen.dart @@ -3,93 +3,44 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:timetable/components/timetable_views/day_view.dart'; import 'package:timetable/components/timetable_views/grid_view.dart'; +import 'package:timetable/components/widgets/grid_day_views_toggle.dart'; +import 'package:timetable/components/widgets/navigation_bar_toggle.dart'; +import 'package:timetable/components/widgets/rotation_week_toggle.dart'; import 'package:timetable/constants/rotation_weeks.dart'; import 'package:timetable/models/settings.dart'; /// The main screen, displays the default timetable view. -/// groups [TimetableGridView] & [TimetableDayView]. +/// basically groups [TimetableGridView] & [TimetableDayView]. class TimetableScreen extends HookConsumerWidget { const TimetableScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final rotationWeeks = ref.watch(settingsProvider).rotationWeeks; - final navbarToggle = ref.watch(settingsProvider).navbarVisible; - final settings = ref.read(settingsProvider.notifier); - final isGridView = useState(true); final rotationWeek = useState(RotationWeeks.all); - List labels = [ - RotationWeeks.all, - RotationWeeks.a, - RotationWeeks.b, - ]; - - final clickCount = useState(0); - - void changeLabel() { - clickCount.value++; - if (clickCount.value >= 3) { - clickCount.value = 0; - } - } - return Scaffold( appBar: AppBar( - title: Row( - children: [ - IconButton( - onPressed: () { - settings.updateNavbarVisible(!navbarToggle); - }, - selectedIcon: const Icon( - Icons.fullscreen, - size: 25, - ), - icon: const Icon( - Icons.close_fullscreen_outlined, - size: 20, - ), - isSelected: navbarToggle, - ), - const SizedBox( - width: 5, - ), - const Text('Timetable'), - ], + title: const Row( + children: [ + NavbarToggle(), + SizedBox( + width: 5, + ), + Text('Timetable'), + ], + ), + actions: [ + if (rotationWeeks) + RotationWeekToggle( + rotationWeek: rotationWeek, + ), + GridDayViewsToggle( + isGridView: isGridView, ), - actions: [ - if (rotationWeeks) - InkWell( - onTap: () { - changeLabel(); - rotationWeek.value = labels[clickCount.value]; - }, - borderRadius: BorderRadius.circular(50), - child: Ink( - width: 40, - height: 40, - child: Center( - child: Text( - getRotationWeekButtonLabel(labels[clickCount.value]), - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - ), - ), - ), - IconButton( - onPressed: () { - isGridView.value = !isGridView.value; - }, - selectedIcon: const Icon(Icons.view_agenda_outlined), - icon: const Icon(Icons.grid_view_outlined), - isSelected: isGridView.value, - ) - ]), + ], + ), body: isGridView.value ? TimetableGridView( rotationWeek: rotationWeek, From 4bf2c5ad2292db9bdd60f0be1ea6eefe5ebd4c8f Mon Sep 17 00:00:00 2001 From: Username * Date: Tue, 19 Dec 2023 15:17:12 +0100 Subject: [PATCH 02/17] fix bug with overlapping subjects not deleting properly --- lib/models/subjects.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/models/subjects.dart b/lib/models/subjects.dart index 8141494..09abfb5 100644 --- a/lib/models/subjects.dart +++ b/lib/models/subjects.dart @@ -84,11 +84,7 @@ class SubjectNotifier extends StateNotifier> { void removeSubject(Subject subject, List> overlappingSubjects) { state = state.where((s) => s != subject).toList(); - overlappingSubjects = overlappingSubjects - .where( - (list) => !list.contains(subject), - ) - .toList(); + overlappingSubjects.removeWhere((e) => e.contains(subject)); saveData(); } From cd6df1765a9b472f705fbc356a5f7f0158c4c028 Mon Sep 17 00:00:00 2001 From: Username * Date: Tue, 19 Dec 2023 15:17:46 +0100 Subject: [PATCH 03/17] add building in dev --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 044aa9a..a51bb42 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - dev jobs: build: name: Android Build From e09d16b843ffebe1e5e6fbc2882559c937f664eb Mon Sep 17 00:00:00 2001 From: Username * Date: Tue, 19 Dec 2023 15:20:52 +0100 Subject: [PATCH 04/17] feat: fix if grid time difference is 0, 24 hours will show --- lib/constants/grid_properties.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/constants/grid_properties.dart b/lib/constants/grid_properties.dart index fb3b1bf..7d0d87e 100644 --- a/lib/constants/grid_properties.dart +++ b/lib/constants/grid_properties.dart @@ -25,8 +25,8 @@ int rows(WidgetRef ref) { if (customTimePeriod && (customEndTime.hour - customStartTime.hour != 0)) { return (customEndTime.hour - customStartTime.hour).abs(); } else if (customTimePeriod && - (customEndTime.minute - customStartTime.minute == 0)) { - return 23; + (customEndTime.hour - customStartTime.hour == 0)) { + return 24; } else { return 10; } From aa0db6290d570c52ad8acb244280a4e02391a8fa Mon Sep 17 00:00:00 2001 From: Username * Date: Tue, 19 Dec 2023 15:46:26 +0100 Subject: [PATCH 05/17] documentation improvements --- README.md | 18 +++--------------- lib/constants/grid_properties.dart | 1 + 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index cf49e4e..e099fcb 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,4 @@ -# timetable +# Timetable +![Workflow Status](https://github.com/user5522/timetable/actions/workflows/build.yml/badge.svg) -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) - -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +A Flutter based Android timetable application for managing time. \ No newline at end of file diff --git a/lib/constants/grid_properties.dart b/lib/constants/grid_properties.dart index 7d0d87e..741835b 100644 --- a/lib/constants/grid_properties.dart +++ b/lib/constants/grid_properties.dart @@ -17,6 +17,7 @@ int columns(WidgetRef ref) { /// Number of rows in the grid view based on the custom start time and custom end time (if customTimePeriod is true), /// otherwise uses the default time period. (8:00 -> 18:00) +/// if hour difference is 0, there will be 24 rows int rows(WidgetRef ref) { final customTimePeriod = ref.watch(settingsProvider).customTimePeriod; final customStartTime = ref.watch(settingsProvider).customStartTime; From 71f2be760eca940651effc29180dd42698254196 Mon Sep 17 00:00:00 2001 From: Username * Date: Wed, 20 Dec 2023 15:10:21 +0100 Subject: [PATCH 06/17] random improvements --- .../settings/screens/timetable_period_screen.dart | 3 ++- .../subject_configs/rotation_week_config.dart | 9 +++------ lib/components/timetable_views/day_view.dart | 3 ++- lib/components/timetable_views/grid_view.dart | 4 ++-- .../bottom_sheets/rotation_week_modal_bottom_sheet.dart | 7 +++++-- .../widgets/grid_view_overlapping_subjects_builder.dart | 8 +++----- lib/components/widgets/rotation_week_toggle.dart | 2 +- lib/constants/rotation_weeks.dart | 6 ++++-- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/components/settings/screens/timetable_period_screen.dart b/lib/components/settings/screens/timetable_period_screen.dart index 5579fb0..f55d0cd 100644 --- a/lib/components/settings/screens/timetable_period_screen.dart +++ b/lib/components/settings/screens/timetable_period_screen.dart @@ -3,7 +3,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:timetable/constants/custom_times.dart'; import 'package:timetable/models/settings.dart'; -/// +/// Screen to manage the period of the timetable. +/// Changes the start time and end time of the timetable. class TimetablePeriodScreen extends ConsumerWidget { const TimetablePeriodScreen({super.key}); diff --git a/lib/components/subject_management/subject_configs/rotation_week_config.dart b/lib/components/subject_management/subject_configs/rotation_week_config.dart index 352b34c..97e0705 100644 --- a/lib/components/subject_management/subject_configs/rotation_week_config.dart +++ b/lib/components/subject_management/subject_configs/rotation_week_config.dart @@ -29,12 +29,9 @@ class RotationWeekConfig extends StatelessWidget { isDismissible: true, context: context, builder: (context) { - return SizedBox( - height: 200, - child: RotationWeekModalBottomSheet( - rotationWeek: rotationWeek, - rotationWeeks: rotationWeeks, - ), + return RotationWeekModalBottomSheet( + rotationWeek: rotationWeek, + rotationWeeks: rotationWeeks, ); }, ); diff --git a/lib/components/timetable_views/day_view.dart b/lib/components/timetable_views/day_view.dart index e616fd3..af13ee1 100644 --- a/lib/components/timetable_views/day_view.dart +++ b/lib/components/timetable_views/day_view.dart @@ -51,7 +51,8 @@ class TimetableDayView extends HookConsumerWidget { ), Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: getFilteredSubjects(rotationWeek, subject) + children: getFilteredByRotationWeeksSubjects( + rotationWeek, subject) .where((s) => s.day.index == index) .map( (subject) => DayViewSubjectBuilder( diff --git a/lib/components/timetable_views/grid_view.dart b/lib/components/timetable_views/grid_view.dart index a1ea142..3ab3c54 100644 --- a/lib/components/timetable_views/grid_view.dart +++ b/lib/components/timetable_views/grid_view.dart @@ -60,7 +60,7 @@ class TimetableGridView extends HookConsumerWidget { rows: rows(ref), columns: columns(ref), grid: generate( - getFilteredSubjects(rotationWeek, subject) + getFilteredByRotationWeeksSubjects(rotationWeek, subject) .where( (e) => e.endTime.hour <= @@ -172,7 +172,7 @@ class TimetableGridView extends HookConsumerWidget { child: OverlappingSubjBuilder( subjects: subjects, earlierStartTimeHour: earlierStartTimeHour, - lateerEndTimeHour: laterEndTimeHour, + laterEndTimeHour: laterEndTimeHour, ), ); } diff --git a/lib/components/widgets/bottom_sheets/rotation_week_modal_bottom_sheet.dart b/lib/components/widgets/bottom_sheets/rotation_week_modal_bottom_sheet.dart index 19cd73d..984f603 100644 --- a/lib/components/widgets/bottom_sheets/rotation_week_modal_bottom_sheet.dart +++ b/lib/components/widgets/bottom_sheets/rotation_week_modal_bottom_sheet.dart @@ -6,8 +6,11 @@ class RotationWeekModalBottomSheet extends StatelessWidget { final List rotationWeeks; final ValueNotifier rotationWeek; - const RotationWeekModalBottomSheet( - {super.key, required this.rotationWeeks, required this.rotationWeek}); + const RotationWeekModalBottomSheet({ + super.key, + required this.rotationWeeks, + required this.rotationWeek, + }); @override Widget build(BuildContext context) { diff --git a/lib/components/widgets/grid_view_overlapping_subjects_builder.dart b/lib/components/widgets/grid_view_overlapping_subjects_builder.dart index afc8a87..eb1bfe9 100644 --- a/lib/components/widgets/grid_view_overlapping_subjects_builder.dart +++ b/lib/components/widgets/grid_view_overlapping_subjects_builder.dart @@ -12,13 +12,13 @@ import 'package:timetable/components/subject_management/subject_screen.dart'; class OverlappingSubjBuilder extends ConsumerWidget { final List subjects; final int earlierStartTimeHour; - final int lateerEndTimeHour; + final int laterEndTimeHour; const OverlappingSubjBuilder({ Key? key, required this.subjects, required this.earlierStartTimeHour, - required this.lateerEndTimeHour, + required this.laterEndTimeHour, }) : super(key: key); @override @@ -50,9 +50,7 @@ class OverlappingSubjBuilder extends ConsumerWidget { ? 0 : 1, bottomWidth: - lateerEndTimeHour == getCustomEndTime(customEndTime, ref).hour - ? 0 - : 1, + laterEndTimeHour == getCustomEndTime(customEndTime, ref).hour ? 0 : 1, strokeAlign: BorderSide.strokeAlignCenter, color: Colors.grey, ); diff --git a/lib/components/widgets/rotation_week_toggle.dart b/lib/components/widgets/rotation_week_toggle.dart index d9308a1..6ad6052 100644 --- a/lib/components/widgets/rotation_week_toggle.dart +++ b/lib/components/widgets/rotation_week_toggle.dart @@ -21,7 +21,7 @@ class RotationWeekToggle extends HookWidget { void changeLabel() { clickCount.value++; - if (clickCount.value >= 3) { + if (clickCount.value >= labels.length) { clickCount.value = 0; } } diff --git a/lib/constants/rotation_weeks.dart b/lib/constants/rotation_weeks.dart index 9c0889c..55e098e 100644 --- a/lib/constants/rotation_weeks.dart +++ b/lib/constants/rotation_weeks.dart @@ -38,8 +38,10 @@ String getRotationWeekButtonLabel(RotationWeeks rotationWeek) { } /// Filters the list of subjects based on the selected rotation week. -List getFilteredSubjects( - ValueNotifier rotationWeek, List allSubjects) { +List getFilteredByRotationWeeksSubjects( + ValueNotifier rotationWeek, + List allSubjects, +) { switch (rotationWeek.value) { case RotationWeeks.all: return allSubjects From c8131ecc0c44ac43c7b5cecf57321a53a6f46f96 Mon Sep 17 00:00:00 2001 From: Username * Date: Wed, 20 Dec 2023 20:24:51 +0100 Subject: [PATCH 07/17] accessibility improvements and bug fixes --- lib/components/widgets/days_row.dart | 1 - lib/components/widgets/navigation_bar.dart | 39 ++++++++----------- .../widgets/rotation_week_toggle.dart | 1 - lib/components/widgets/time_column.dart | 1 - lib/main.dart | 2 +- lib/screens/settings_screen.dart | 7 +++- lib/screens/timetable_screen.dart | 11 +----- 7 files changed, 26 insertions(+), 36 deletions(-) diff --git a/lib/components/widgets/days_row.dart b/lib/components/widgets/days_row.dart index b3267c4..f6d0d82 100644 --- a/lib/components/widgets/days_row.dart +++ b/lib/components/widgets/days_row.dart @@ -29,7 +29,6 @@ class DaysRow extends ConsumerWidget { hideSunday ? days.length - 1 : days.length, (i) => Container( alignment: Alignment.bottomCenter, - height: 20, width: tileWidth, child: Text( singleLetterDays diff --git a/lib/components/widgets/navigation_bar.dart b/lib/components/widgets/navigation_bar.dart index 55171ce..c4e8736 100644 --- a/lib/components/widgets/navigation_bar.dart +++ b/lib/components/widgets/navigation_bar.dart @@ -1,31 +1,34 @@ import 'package:animations/animations.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:timetable/models/settings.dart'; import 'package:timetable/screens/settings_screen.dart'; import 'package:timetable/screens/timetable_screen.dart'; /// The navigation bar. -class Navigation extends ConsumerStatefulWidget { - const Navigation({super.key}); +class Navigation extends HookConsumerWidget { + const Navigation({ + super.key, + }); @override - ConsumerState createState() => _NavigationState(); -} - -class _NavigationState extends ConsumerState { - int currentPageIndex = 0; - - @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { final navbarToggle = ref.watch(settingsProvider).navbarVisible; + final currentPageIndex = useState(0); + + void onTabTapped(int index) { + if (currentPageIndex.value != index) { + currentPageIndex.value = index; + } + } return Scaffold( bottomNavigationBar: Visibility( visible: navbarToggle, child: NavigationBar( - onDestinationSelected: _onTabTapped, - selectedIndex: currentPageIndex, + onDestinationSelected: onTabTapped, + selectedIndex: currentPageIndex.value, destinations: const [ NavigationDestination( selectedIcon: Icon(Icons.table_chart), @@ -49,25 +52,17 @@ class _NavigationState extends ConsumerState { transitionType: SharedAxisTransitionType.horizontal, child: child); }, - child: _buildPage(currentPageIndex), + child: _buildPage(currentPageIndex.value), ), ); } - void _onTabTapped(int index) { - if (currentPageIndex != index) { - setState(() { - currentPageIndex = index; - }); - } - } - Widget _buildPage(int pageIndex) { switch (pageIndex) { case 0: return const TimetableScreen(); case 1: - return const SettingsScreen(); + return SettingsScreen(); default: return const TimetableScreen(); } diff --git a/lib/components/widgets/rotation_week_toggle.dart b/lib/components/widgets/rotation_week_toggle.dart index 6ad6052..0ed0991 100644 --- a/lib/components/widgets/rotation_week_toggle.dart +++ b/lib/components/widgets/rotation_week_toggle.dart @@ -40,7 +40,6 @@ class RotationWeekToggle extends HookWidget { getRotationWeekButtonLabel(labels[clickCount.value]), style: const TextStyle( fontWeight: FontWeight.bold, - fontSize: 16, ), ), ), diff --git a/lib/components/widgets/time_column.dart b/lib/components/widgets/time_column.dart index 53af2e7..c2a0eff 100644 --- a/lib/components/widgets/time_column.dart +++ b/lib/components/widgets/time_column.dart @@ -21,7 +21,6 @@ class TimeColumn extends ConsumerWidget { rows(ref), (i) => SizedBox( height: compactMode ? 125 : 100, - width: timeColumnWidth, child: Text( is24HoursFormat ? times24h[i + diff --git a/lib/main.dart b/lib/main.dart index 1d44fdb..d989ee5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,7 +59,7 @@ class Timetable extends ConsumerWidget { ), useMaterial3: true, ), - home: const Navigation(), + home: Navigation(), ); }, ); diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 49b013d..221c48b 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -5,13 +5,16 @@ import 'package:timetable/components/settings/customize_timetable.dart'; import 'package:timetable/components/settings/theme_options.dart'; import 'package:timetable/components/settings/timetable_data.dart'; import 'package:timetable/components/settings/timetable_features.dart'; +import 'package:timetable/components/widgets/navigation_bar_toggle.dart'; import 'package:timetable/models/settings.dart'; import 'package:timetable/provider/themes.dart'; /// Settings Screen, groups all settings ([CustomizeTimetableOptions], [TimetableDataOptions], /// [TimetableFeaturesOptions] and [ThemeOptions]) together. class SettingsScreen extends ConsumerWidget { - const SettingsScreen({super.key}); + const SettingsScreen({ + super.key, + }); Future getAndroidVersion() async { DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); @@ -24,10 +27,12 @@ class SettingsScreen extends ConsumerWidget { final themeMode = ref.read(themeModeProvider.notifier); final monetTheming = ref.watch(settingsProvider).monetTheming; final settings = ref.read(settingsProvider.notifier); + final navbarToggle = ref.watch(settingsProvider).navbarVisible; return Scaffold( appBar: AppBar( title: const Text("Settings"), + leading: navbarToggle ? null : const NavbarToggle(), ), body: SingleChildScrollView( child: Column( diff --git a/lib/screens/timetable_screen.dart b/lib/screens/timetable_screen.dart index a5df14f..dfebbfb 100644 --- a/lib/screens/timetable_screen.dart +++ b/lib/screens/timetable_screen.dart @@ -22,15 +22,8 @@ class TimetableScreen extends HookConsumerWidget { return Scaffold( appBar: AppBar( - title: const Row( - children: [ - NavbarToggle(), - SizedBox( - width: 5, - ), - Text('Timetable'), - ], - ), + leading: const NavbarToggle(), + title: const Text('Timetable'), actions: [ if (rotationWeeks) RotationWeekToggle( From 1e14b4290da15f9dff6d22126533d27c829cb5c1 Mon Sep 17 00:00:00 2001 From: Username * Date: Wed, 20 Dec 2023 21:00:24 +0100 Subject: [PATCH 08/17] code improvements and use less SizedBox widgets --- .../subject_configs/time_config.dart | 26 +++++++++---------- .../subject_management/subject_screen.dart | 23 +++++++--------- .../widgets/day_view_subject_builder.dart | 18 ++++++------- ...rid_view_overlapping_subjects_builder.dart | 9 +++++-- .../widgets/grid_view_subject_builder.dart | 2 +- lib/components/widgets/list_tile_group.dart | 24 ++++++++--------- lib/components/widgets/navigation_bar.dart | 2 +- lib/main.dart | 2 +- 8 files changed, 52 insertions(+), 54 deletions(-) diff --git a/lib/components/subject_management/subject_configs/time_config.dart b/lib/components/subject_management/subject_configs/time_config.dart index fad5678..c177936 100644 --- a/lib/components/subject_management/subject_configs/time_config.dart +++ b/lib/components/subject_management/subject_configs/time_config.dart @@ -115,12 +115,11 @@ class TimeConfig extends ConsumerWidget { ), ), ), - const SizedBox( - width: 10, - ), - const Icon(Icons.arrow_forward), - const SizedBox( - width: 10, + const Padding( + padding: EdgeInsets.symmetric( + horizontal: 10, + ), + child: Icon(Icons.arrow_forward), ), ActionChip( side: BorderSide.none, @@ -153,15 +152,14 @@ class TimeConfig extends ConsumerWidget { ), ), ), - if (occupied == true) - const SizedBox( - width: 10, + if (occupied) + const Padding( + padding: EdgeInsets.only(left: 10), + child: Icon( + Icons.cancel, + color: Colors.redAccent, + ), ), - if (occupied == true) - const Icon( - Icons.cancel, - color: Colors.redAccent, - ) ], ); } diff --git a/lib/components/subject_management/subject_screen.dart b/lib/components/subject_management/subject_screen.dart index 2d00ea7..fcfd924 100644 --- a/lib/components/subject_management/subject_screen.dart +++ b/lib/components/subject_management/subject_screen.dart @@ -139,7 +139,7 @@ class SubjectScreen extends HookConsumerWidget { onPressed: () { if (formKey.currentState!.validate()) { if (isSubjectNull) { - if (isOccupied == false) { + if (!isOccupied) { state.addSubject(newSubject); Navigator.pop(context, label.value); } else { @@ -150,7 +150,7 @@ class SubjectScreen extends HookConsumerWidget { ); } } else { - if (isOccupiedExceptSelf == false) { + if (!isOccupiedExceptSelf) { state.updateSubject(subject!, newSubject); Navigator.pop(context, label.value); } else { @@ -220,12 +220,9 @@ class SubjectScreen extends HookConsumerWidget { ), ], ), - const SizedBox( - height: 10, - ), - ColorsConfig(color: color), - const SizedBox( - height: 10, + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: ColorsConfig(color: color), ), TimeDayRotationWeekConfig( day: day, @@ -234,12 +231,12 @@ class SubjectScreen extends HookConsumerWidget { endTime: endTime, occupied: isSubjectNull ? isOccupied : isOccupiedExceptSelf, ), - const SizedBox( - height: 10, + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: NotesTile( + note: note, + ), ), - NotesTile( - note: note, - ) ], ), ), diff --git a/lib/components/widgets/day_view_subject_builder.dart b/lib/components/widgets/day_view_subject_builder.dart index 5e5b89a..89c4f77 100644 --- a/lib/components/widgets/day_view_subject_builder.dart +++ b/lib/components/widgets/day_view_subject_builder.dart @@ -76,6 +76,7 @@ class DayViewSubjectBuilder extends ConsumerWidget { ), ), ), + // SizedBox is for incase the label is too long const SizedBox( width: 20, ), @@ -123,9 +124,6 @@ class DayViewSubjectBuilder extends ConsumerWidget { size: 19, color: subLabelsColor, ), - const SizedBox( - width: 10, - ), Expanded( child: Text( location.toString(), @@ -143,13 +141,13 @@ class DayViewSubjectBuilder extends ConsumerWidget { if (note != null && note.isNotEmpty) Row( children: [ - Icon( - Icons.sticky_note_2_outlined, - size: 19, - color: subLabelsColor, - ), - const SizedBox( - width: 10, + Padding( + padding: const EdgeInsets.only(right: 10), + child: Icon( + Icons.sticky_note_2_outlined, + size: 19, + color: subLabelsColor, + ), ), Expanded( child: Text( diff --git a/lib/components/widgets/grid_view_overlapping_subjects_builder.dart b/lib/components/widgets/grid_view_overlapping_subjects_builder.dart index eb1bfe9..cba7209 100644 --- a/lib/components/widgets/grid_view_overlapping_subjects_builder.dart +++ b/lib/components/widgets/grid_view_overlapping_subjects_builder.dart @@ -87,7 +87,12 @@ class OverlappingSubjBuilder extends ConsumerWidget { height: (startTimeHour - earlierStartTimeHour) * (tileHeight), ), Padding( - padding: const EdgeInsets.all(outerPadding), + padding: const EdgeInsets.fromLTRB( + outerPadding, + outerPadding, + outerPadding, + outerPadding - 1, + ), child: InkWell( onTap: () { Navigator.push( @@ -116,7 +121,7 @@ class OverlappingSubjBuilder extends ConsumerWidget { width: 0, ), ), - width: ((tileWidth / 2) - .75) - (outerPadding * 2), + width: ((tileWidth / 2) - .75) - (outerPadding * 2.25), height: (((endTimeHour - startTimeHour) * (tileHeight)) - 1) - (outerPadding * 2), diff --git a/lib/components/widgets/grid_view_subject_builder.dart b/lib/components/widgets/grid_view_subject_builder.dart index 9043e94..ed76096 100644 --- a/lib/components/widgets/grid_view_subject_builder.dart +++ b/lib/components/widgets/grid_view_subject_builder.dart @@ -106,7 +106,7 @@ class SubjectBuilder extends ConsumerWidget { height: 5, ), if ((location != null)) - if (hideLocation == false) + if (!hideLocation) if (!hideTransparentSubjects) Text( location.toString(), diff --git a/lib/components/widgets/list_tile_group.dart b/lib/components/widgets/list_tile_group.dart index 10396da..f2bed89 100644 --- a/lib/components/widgets/list_tile_group.dart +++ b/lib/components/widgets/list_tile_group.dart @@ -80,18 +80,18 @@ class ListItem extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - ListTile( - title: title, - subtitle: subtitle, - leading: leading, - onTap: () { - onTap; - }, - shape: shape, - tileColor: Theme.of(context).colorScheme.surfaceVariant, - ), - const SizedBox( - height: 2, + Padding( + padding: const EdgeInsets.only(bottom: 2), + child: ListTile( + title: title, + subtitle: subtitle, + leading: leading, + onTap: () { + onTap; + }, + shape: shape, + tileColor: Theme.of(context).colorScheme.surfaceVariant, + ), ), ], ); diff --git a/lib/components/widgets/navigation_bar.dart b/lib/components/widgets/navigation_bar.dart index c4e8736..6df3a18 100644 --- a/lib/components/widgets/navigation_bar.dart +++ b/lib/components/widgets/navigation_bar.dart @@ -62,7 +62,7 @@ class Navigation extends HookConsumerWidget { case 0: return const TimetableScreen(); case 1: - return SettingsScreen(); + return const SettingsScreen(); default: return const TimetableScreen(); } diff --git a/lib/main.dart b/lib/main.dart index d989ee5..1d44fdb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,7 +59,7 @@ class Timetable extends ConsumerWidget { ), useMaterial3: true, ), - home: Navigation(), + home: const Navigation(), ); }, ); From 497c6e65af90f6283913ce3ebcfbd31a54ebb27e Mon Sep 17 00:00:00 2001 From: Username * Date: Thu, 21 Dec 2023 00:05:34 +0100 Subject: [PATCH 09/17] bug fix with the time column and more improvements --- .../widgets/grid_view_subject_builder.dart | 2 +- lib/components/widgets/time_column.dart | 24 ++++---------- lib/constants/custom_times.dart | 32 ++++++------------- 3 files changed, 18 insertions(+), 40 deletions(-) diff --git a/lib/components/widgets/grid_view_subject_builder.dart b/lib/components/widgets/grid_view_subject_builder.dart index ed76096..bb64e75 100644 --- a/lib/components/widgets/grid_view_subject_builder.dart +++ b/lib/components/widgets/grid_view_subject_builder.dart @@ -74,7 +74,7 @@ class SubjectBuilder extends ConsumerWidget { }, borderRadius: BorderRadius.circular(5), child: Ink( - padding: const EdgeInsets.all(5), + padding: const EdgeInsets.all(3), decoration: BoxDecoration( color: color, border: Border.all( diff --git a/lib/components/widgets/time_column.dart b/lib/components/widgets/time_column.dart index c2a0eff..e1ca42e 100644 --- a/lib/components/widgets/time_column.dart +++ b/lib/components/widgets/time_column.dart @@ -17,29 +17,19 @@ class TimeColumn extends ConsumerWidget { return Column(children: [ Column( - children: List.generate( - rows(ref), - (i) => SizedBox( + children: List.generate(rows(ref), (i) { + return SizedBox( height: compactMode ? 125 : 100, child: Text( is24HoursFormat - ? times24h[i + - (customStartTime.hour == 0 - ? 0 - : customTimePeriod - ? customStartTime.hour - : 8)] - : timespmam[i + - (customStartTime.hour == 0 - ? 0 - : customTimePeriod - ? customStartTime.hour - : 8)], + ? times24h[i + (customTimePeriod ? customStartTime.hour : 8)] + : timespmam[ + i + (customTimePeriod ? customStartTime.hour : 8)], style: const TextStyle(fontSize: 13), textAlign: TextAlign.center, ), - ), - ), + ); + }), ), ]); } diff --git a/lib/constants/custom_times.dart b/lib/constants/custom_times.dart index 7b53417..fda3a9f 100644 --- a/lib/constants/custom_times.dart +++ b/lib/constants/custom_times.dart @@ -8,11 +8,8 @@ TimeOfDay getCustomStartTime(TimeOfDay customTime, WidgetRef ref) { final customTimePeriod = ref.watch(settingsProvider).customTimePeriod; if (customTimePeriod) { - if (customTime.hour != 00) { - return TimeOfDay(hour: customTime.hour, minute: customTime.minute); - } else { - return const TimeOfDay(hour: 0, minute: 0); - } + if (customTime.hour != 0) return customTime; + return const TimeOfDay(hour: 0, minute: 0); } else { return const TimeOfDay(hour: 8, minute: 0); } @@ -24,30 +21,21 @@ TimeOfDay getCustomEndTime(TimeOfDay customTime, WidgetRef ref) { final customTimePeriod = ref.watch(settingsProvider).customTimePeriod; if (customTimePeriod) { - if (customTime.hour != 00) { - return TimeOfDay(hour: customTime.hour, minute: customTime.minute); - } else { - return const TimeOfDay(hour: 24, minute: 0); - } + if (customTime.hour != 0) return customTime; + return const TimeOfDay(hour: 24, minute: 0); } else { return const TimeOfDay(hour: 18, minute: 0); } } -/// Returns the hour part of the customTime, formatted. +/// Returns a formatted custom time hour. String getCustomTimeHour(TimeOfDay customTime) { - if (customTime.hour < 10) { - return "0${customTime.hour}"; - } else { - return "${customTime.hour}"; - } + if (customTime.hour < 10) return "0${customTime.hour}"; + return "${customTime.hour}"; } -/// Returns the minute part of the customTime, formatted. +/// Returns a formatted custom time hour. String getCustomTimeMinute(TimeOfDay customTime) { - if (customTime.minute < 10) { - return "0${customTime.minute}"; - } else { - return "${customTime.minute}"; - } + if (customTime.minute < 10) return "0${customTime.minute}"; + return "${customTime.minute}"; } From 92e2baacaa215839197deb889fac9c526d3510fe Mon Sep 17 00:00:00 2001 From: Username * Date: Fri, 22 Dec 2023 22:31:17 +0100 Subject: [PATCH 10/17] feat: change database from hive to drift --- android/app/src/main/AndroidManifest.xml | 1 + lib/components/settings/timetable_data.dart | 4 +- .../subject_management/subject_screen.dart | 35 +- lib/components/timetable_views/day_view.dart | 9 +- lib/components/timetable_views/grid_view.dart | 11 +- .../widgets/day_view_subject_builder.dart | 13 +- ...rid_view_overlapping_subjects_builder.dart | 15 +- .../widgets/grid_view_subject_builder.dart | 6 +- lib/constants/basic_subject.dart | 11 +- lib/constants/rotation_weeks.dart | 8 +- lib/db/connection/native.dart | 24 + lib/db/converters/color_converter.dart | 18 + lib/db/converters/time_of_day_converter.dart | 21 + lib/db/database.dart | 25 + lib/db/database.g.dart | 456 ++++++++++++++++++ lib/db/models.dart | 71 +++ lib/main.dart | 8 +- lib/models/days.g.dart | 17 - lib/models/overlapping_subjects.dart | 6 +- lib/models/rotationWeeks.g.dart | 17 - lib/models/subjects.dart | 131 ----- lib/models/subjects.g.dart | 56 --- lib/models/timeOfDay.g.dart | 25 - lib/screens/timetable_screen.dart | 5 + pubspec.lock | 156 +++--- pubspec.yaml | 14 +- 26 files changed, 793 insertions(+), 370 deletions(-) create mode 100644 lib/db/connection/native.dart create mode 100644 lib/db/converters/color_converter.dart create mode 100644 lib/db/converters/time_of_day_converter.dart create mode 100644 lib/db/database.dart create mode 100644 lib/db/database.g.dart create mode 100644 lib/db/models.dart delete mode 100644 lib/models/days.g.dart delete mode 100644 lib/models/rotationWeeks.g.dart delete mode 100644 lib/models/subjects.dart delete mode 100644 lib/models/subjects.g.dart delete mode 100644 lib/models/timeOfDay.g.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d0c1af4..8dbb2ae 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" + android:enableOnBackInvokedCallback="true" android:windowSoftInputMode="adjustResize">