Skip to content

Commit

Permalink
feat: change default subject duration
Browse files Browse the repository at this point in the history
  • Loading branch information
user5522 committed Aug 8, 2024
1 parent c81244f commit 020d0fb
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 8 deletions.
2 changes: 2 additions & 0 deletions assets/translations/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"default_tb_view": "Default View",
"view": "View",
"grid": "Grid",
"default_subject_duration": "Default Subject Duration",
"choose_duration": "Choose a Duration",

"delete_timetable_dialog": "Deleting a timetable will delete its corresponding subjects.",
"reset_timetables_dialog": "Resetting timetables will also delete all subjects.",
Expand Down
2 changes: 2 additions & 0 deletions assets/translations/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"default_tb_view": "Vue par défaut",
"view": "Vue",
"grid": "Grille",
"default_subject_duration": "Durée par défaut d'un matière",
"choose_duration": "Choisir une Durée",

"delete_timetable_dialog": "La suppression d'un tableau supprimera ses sujets correspondants.",
"reset_timetables_dialog": "La réinitialisation des emplois de temps supprimera toutes les matières aussi.",
Expand Down
8 changes: 2 additions & 6 deletions lib/components/settings/general.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,9 @@ class GeneralOptions extends ConsumerWidget {
size: 20,
),
horizontalTitleGap: 8,
title: Row(
children: [
const Text("app_color").tr(),
const Spacer(),
title: const Text("app_color").tr(),
trailing:
ColorIndicator(color: appThemeColor, monetTheming: monetTheming),
],
),
onTap: () {
Navigator.push(
context,
Expand Down
35 changes: 34 additions & 1 deletion lib/components/settings/timetable_features.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:timetable/components/settings/screens/timetable_management.dart';
import 'package:timetable/components/widgets/bottom_sheets/subject_duration_modal_bottom_sheet.dart';
import 'package:timetable/provider/settings.dart';
import 'package:timetable/components/settings/screens/timetable_period.dart';

/// All the settings for changing some timetable features.
class TimetableFeaturesOptions extends ConsumerWidget {
class TimetableFeaturesOptions extends HookConsumerWidget {
const TimetableFeaturesOptions({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final settings = ref.read(settingsProvider.notifier);
final rotationWeeks = ref.watch(settingsProvider).rotationWeeks;
final autoCompleteColor = ref.watch(settingsProvider).autoCompleteColor;
final defaultSubjectDuration =
ref.watch(settingsProvider).defaultSubjectDuration;
final duration = useState(defaultSubjectDuration);

return Column(
children: [
Expand Down Expand Up @@ -49,6 +54,34 @@ class TimetableFeaturesOptions extends ConsumerWidget {
},
title: const Text("manage_timetables").tr(),
),
ListTile(
leading: const Icon(
Icons.timer_outlined,
size: 20,
),
horizontalTitleGap: 8,
title: const Text("default_subject_duration").tr(),
trailing: Text("${defaultSubjectDuration.inMinutes}min"),
onTap: () {
showModalBottomSheet(
showDragHandle: true,
enableDrag: true,
isDismissible: true,
context: context,
builder: (context) {
return Wrap(
children: [
SubjectDurationModalBottomSheet(
duration: duration,
),
],
);
},
).then(
(_) => settings.updateDefaultSubjectDuration(duration.value),
);
},
),
SwitchListTile(
secondary: const Icon(
Icons.rotate_90_degrees_ccw_outlined,
Expand Down
6 changes: 5 additions & 1 deletion lib/components/subject_management/subject_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class SubjectScreen extends HookConsumerWidget {
final tfHours = ref.watch(settingsProvider).twentyFourHours;
final customStartTimeHour =
ref.watch(settingsProvider).customStartTime.hour;
final defaultSubjectDuration =
ref.watch(settingsProvider).defaultSubjectDuration;

final bool isSubjectNull = (subject == null);
final bool isCTimetableNull = (currentTimetable == null);
Expand All @@ -65,7 +67,9 @@ class SubjectScreen extends HookConsumerWidget {
final ValueNotifier<TimeOfDay> endTime = useState(
TimeOfDay(
hour: subject?.endTime.hour ??
(rowIndex! + (tfHours ? 0 : customStartTimeHour) + 1),
(rowIndex! +
(tfHours ? 0 : customStartTimeHour) +
defaultSubjectDuration.inHours),
minute: 0,
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:timetable/components/widgets/bottom_sheets/subject_data_bottom_sheet.dart';
import 'package:timetable/constants/durations.dart';

/// Bottom Sheet Modal Widget used to select the default subject duration.
class SubjectDurationModalBottomSheet extends StatelessWidget {
final ValueNotifier<Duration> duration;

const SubjectDurationModalBottomSheet({
super.key,
required this.duration,
});

@override
Widget build(BuildContext context) {
return SubjectDataBottomSheet(
title: "choose_duration".tr(),
children: List.generate(
durations.length,
(i) {
final d = durations[i];
bool isSelected = (d == duration.value);

return ListTile(
title: Row(
children: [
// writing minutes directly here will only work for now lol
Text(
"${durations[i].inMinutes} minutes",
).tr(),
const Spacer(),
Visibility(
visible: isSelected,
child: const Icon(
Icons.check,
),
),
],
),
visualDensity: VisualDensity.compact,
onTap: () {
duration.value = d;
Navigator.pop(context);
},
);
},
),
);
}
}
6 changes: 6 additions & 0 deletions lib/constants/durations.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const List<Duration> durations = [
Duration(minutes: 60),
Duration(minutes: 120),
Duration(minutes: 180),
Duration(minutes: 240),
];
9 changes: 9 additions & 0 deletions lib/db/models/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Settings {
final bool twentyFourHours;
final TbViews defaultTimetableView;
final Color appThemeColor;
final Duration defaultSubjectDuration;

// settings defaults
Settings({
Expand All @@ -38,6 +39,7 @@ class Settings {
this.twentyFourHours = false,
this.defaultTimetableView = TbViews.grid,
this.appThemeColor = Colors.deepPurple,
this.defaultSubjectDuration = const Duration(minutes: 60),
});

Settings copyWith({
Expand All @@ -57,6 +59,7 @@ class Settings {
bool? twentyFourHours,
TbViews? defaultTimetableView,
Color? appThemeColor,
Duration? defaultSubjectDuration,
}) =>
Settings(
customTimePeriod: customTimePeriod ?? this.customTimePeriod,
Expand All @@ -76,6 +79,8 @@ class Settings {
twentyFourHours: twentyFourHours ?? this.twentyFourHours,
defaultTimetableView: defaultTimetableView ?? this.defaultTimetableView,
appThemeColor: appThemeColor ?? this.appThemeColor,
defaultSubjectDuration:
defaultSubjectDuration ?? this.defaultSubjectDuration,
);

Map<String, dynamic> toJson() => {
Expand All @@ -97,6 +102,7 @@ class Settings {
'twentyFourHours': twentyFourHours,
'defaultTimetableView': defaultTimetableView.name,
'appThemeColorValue': appThemeColor.value,
'defaultSubjectDuration': defaultSubjectDuration.inMinutes,
};

factory Settings.fromJson(Map<String, dynamic> json) {
Expand Down Expand Up @@ -137,6 +143,9 @@ class Settings {
appThemeColor: json['appThemeColorValue'] != null
? Color(json['appThemeColorValue'] as int)
: null,
defaultSubjectDuration: json['defaultSubjectDuration'] != null
? Duration(minutes: json['defaultSubjectDuration'] as int)
: null,
);
}
}
8 changes: 8 additions & 0 deletions lib/provider/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ class SettingsNotifier extends StateNotifier<Settings> {
loadSettings();
}

void updateDefaultSubjectDuration(Duration defaultSubjectDuration) {
final newState = state.copyWith(
defaultSubjectDuration: defaultSubjectDuration,
);
state = newState;
saveSettings();
}

void updateAppThemeColor(Color appThemeColor) {
final newState = state.copyWith(
appThemeColor: appThemeColor,
Expand Down

0 comments on commit 020d0fb

Please sign in to comment.