Skip to content

Commit

Permalink
feat(time-slots): add the capability to select which days the time sl…
Browse files Browse the repository at this point in the history
…ots are the most impacting
  • Loading branch information
vareversat committed May 21, 2023
1 parent 753bd5b commit a88ac68
Show file tree
Hide file tree
Showing 26 changed files with 624 additions and 171 deletions.
36 changes: 4 additions & 32 deletions lib/bloc/notification/notification_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'dart:async';

import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:chabo/bloc/chabo_event.dart';
import 'package:chabo/bloc/time_slots/time_slots_bloc.dart';
import 'package:chabo/const.dart';
import 'package:chabo/models/abstract_forecast.dart';
import 'package:chabo/models/enums/day.dart';
import 'package:chabo/models/time_slot.dart';
import 'package:chabo/service/notification_service.dart';
import 'package:chabo/service/storage_service.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -40,7 +40,6 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
Const.notificationClosingEnabledDefaultValue,
timeSlotsEnabledForNotifications:
Const.notificationFavoriteSlotsEnabledDefaultValue,
timeSlotsValue: Const.notificationFavoriteSlotsDefaultValue,
notificationEnabled: false,
),
) {
Expand Down Expand Up @@ -84,15 +83,11 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
_onEnabledTimeSlotEvent,
transformer: sequential(),
);
on<ValueTimeSlotEvent>(
_onTimeSlotsEventValue,
transformer: sequential(),
);
on<ComputeNotificationEvent>(
_onComputeNotificationEvent,
transformer: sequential(),
);
on<AppEvent>(
on<NotificationAppEvent>(
_onAppEvent,
transformer: sequential(),
);
Expand Down Expand Up @@ -262,38 +257,20 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
));
}

Future<void> _onTimeSlotsEventValue(
ValueTimeSlotEvent event,
Emitter<NotificationState> emit,
) async {
final timeSlots = List<TimeSlot>.from(state.timeSlotsValue);
timeSlots[event.index] = event.timeSlot;
await storageService.saveTimeSlots(
Const.notificationFavoriteSlotsValueKey,
timeSlots,
);
HapticFeedback.lightImpact();

emit(
state.copyWith(
timeSlotsValue: timeSlots,
),
);
}

Future<void> _onComputeNotificationEvent(
ComputeNotificationEvent event,
Emitter<NotificationState> emit,
) async {
await notificationService.computeNotifications(
event.forecasts,
state,
event.timeSlotsState,
event.context,
);
}

void _onAppEvent(
AppEvent event,
NotificationAppEvent event,
Emitter<NotificationState> emit,
) async {
final durationNotificationEnabled =
Expand Down Expand Up @@ -332,10 +309,6 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
storageService.readBool(Const.notificationClosingEnabledKey) ??
Const.notificationClosingEnabledDefaultValue;

final timeSlots =
storageService.readTimeSlots(Const.notificationFavoriteSlotsValueKey) ??
Const.notificationFavoriteSlotsDefaultValue;

final enabledForNotifications =
storageService.readBool(Const.notificationFavoriteSlotsEnabledKey) ??
Const.notificationFavoriteSlotsEnabledDefaultValue;
Expand All @@ -353,7 +326,6 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
dayNotificationTimeValue: dayNotificationTimeValue,
openingNotificationEnabled: openingNotificationEnabled,
closingNotificationEnabled: closingNotificationEnabled,
timeSlotsValue: timeSlots,
timeSlotsEnabledForNotifications: enabledForNotifications,
notificationEnabled: enabled,
),
Expand Down
19 changes: 8 additions & 11 deletions lib/bloc/notification/notification_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,18 @@ class EnabledTimeSlotEvent extends NotificationEvent {
EnabledTimeSlotEvent({required this.enabled}) : super();
}

class ValueTimeSlotEvent extends NotificationEvent {
final TimeSlot timeSlot;
final int index;

ValueTimeSlotEvent({required this.timeSlot, required this.index}) : super();
}

class ComputeNotificationEvent extends NotificationEvent {
final List<AbstractForecast> forecasts;
final BuildContext context;
final TimeSlotsState timeSlotsState;

ComputeNotificationEvent({required this.forecasts, required this.context})
: super();
ComputeNotificationEvent({
required this.forecasts,
required this.context,
required this.timeSlotsState,
}) : super();
}

class AppEvent extends NotificationEvent {
AppEvent() : super();
class NotificationAppEvent extends NotificationEvent {
NotificationAppEvent() : super();
}
4 changes: 0 additions & 4 deletions lib/bloc/notification/notification_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class NotificationState {
final bool openingNotificationEnabled;
final bool closingNotificationEnabled;
final bool timeSlotsEnabledForNotifications;
final List<TimeSlot> timeSlotsValue;
final bool notificationEnabled;

NotificationState({
Expand All @@ -26,7 +25,6 @@ class NotificationState {
required this.openingNotificationEnabled,
required this.closingNotificationEnabled,
required this.timeSlotsEnabledForNotifications,
required this.timeSlotsValue,
});

NotificationState copyWith({
Expand All @@ -40,7 +38,6 @@ class NotificationState {
bool? openingNotificationEnabled,
bool? closingNotificationEnabled,
bool? timeSlotsEnabledForNotifications,
List<TimeSlot>? timeSlotsValue,
bool? notificationEnabled,
}) {
return NotificationState(
Expand All @@ -63,7 +60,6 @@ class NotificationState {
closingNotificationEnabled ?? this.closingNotificationEnabled,
timeSlotsEnabledForNotifications: timeSlotsEnabledForNotifications ??
this.timeSlotsEnabledForNotifications,
timeSlotsValue: timeSlotsValue ?? this.timeSlotsValue,
notificationEnabled: notificationEnabled ?? this.notificationEnabled,
);
}
Expand Down
92 changes: 92 additions & 0 deletions lib/bloc/time_slots/time_slots_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'package:chabo/bloc/chabo_event.dart';
import 'package:chabo/const.dart';
import 'package:chabo/models/enums/day.dart';
import 'package:chabo/models/time_slot.dart';
import 'package:chabo/service/storage_service.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

part 'time_slots_event.dart';
part 'time_slots_state.dart';

class TimeSlotsBloc extends Bloc<TimeSlotsEvent, TimeSlotsState> {
final StorageService storageService;

TimeSlotsBloc({required this.storageService}) : super(TimeSlotsInitial()) {
on<TimeSlotChanged>(
_onTimeSlotChanged,
);

on<DaysChanged>(
_onDaysChanged,
);

on<TimeSlotsAppEvent>(
_onAppEvent,
);
}

Future<void> _onTimeSlotChanged(
TimeSlotChanged event,
Emitter<TimeSlotsState> emit,
) async {
final timeSlots = List<TimeSlot>.from(state.timeSlots);
timeSlots[event.index] = event.timeSlot;
await storageService.saveTimeSlots(
Const.notificationFavoriteSlotsValueKey,
timeSlots,
);
HapticFeedback.lightImpact();

emit(
state.copyWith(
timeSlots: timeSlots,
),
);
}

Future<void> _onDaysChanged(
DaysChanged event,
Emitter<TimeSlotsState> emit,
) async {
final days = List<Day>.from(state.days);
if (event.isSelected) {
days.add(event.day);
} else {
days.remove(event.day);
}

await storageService.saveDays(
Const.notificationFavoriteSlotsDaysValueKey,
days,
);
HapticFeedback.lightImpact();

emit(
state.copyWith(
days: days,
),
);
}

void _onAppEvent(
TimeSlotsAppEvent event,
Emitter<TimeSlotsState> emit,
) {
final days =
storageService.readDays(Const.notificationFavoriteSlotsDaysValueKey) ??
Const.notificationFavoriteSlotsDaysDefaultValue;

final timeSlots =
storageService.readTimeSlots(Const.notificationFavoriteSlotsValueKey) ??
Const.notificationFavoriteSlotsDefaultValue;

emit(
state.copyWith(
days: days,
timeSlots: timeSlots,
),
);
}
}
27 changes: 27 additions & 0 deletions lib/bloc/time_slots/time_slots_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
part of 'time_slots_bloc.dart';

class TimeSlotsEvent extends ChaboEvent {}

class TimeSlotChanged extends TimeSlotsEvent {
final TimeSlot timeSlot;
final int index;

TimeSlotChanged({
required this.timeSlot,
required this.index,
}) : super();
}

class DaysChanged extends TimeSlotsEvent {
final Day day;
final bool isSelected;

DaysChanged({
required this.day,
required this.isSelected,
}) : super();
}

class TimeSlotsAppEvent extends TimeSlotsEvent {
TimeSlotsAppEvent() : super();
}
32 changes: 32 additions & 0 deletions lib/bloc/time_slots/time_slots_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
part of 'time_slots_bloc.dart';

class TimeSlotsState extends Equatable {
final List<TimeSlot> timeSlots;
final List<Day> days;

const TimeSlotsState({
required this.timeSlots,
required this.days,
});

TimeSlotsState copyWith({
List<TimeSlot>? timeSlots,
List<Day>? days,
}) {
return TimeSlotsState(
timeSlots: timeSlots ?? this.timeSlots,
days: days ?? this.days,
);
}

@override
List<Object?> get props => [timeSlots, days];
}

class TimeSlotsInitial extends TimeSlotsState {
TimeSlotsInitial()
: super(
timeSlots: Const.notificationFavoriteSlotsDefaultValue,
days: Const.notificationFavoriteSlotsDaysDefaultValue,
);
}
12 changes: 11 additions & 1 deletion lib/chabo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:chabo/bloc/notification/notification_bloc.dart';
import 'package:chabo/bloc/scroll_status/scroll_status_bloc.dart';
import 'package:chabo/bloc/status/status_bloc.dart';
import 'package:chabo/bloc/theme/theme_bloc.dart';
import 'package:chabo/bloc/time_slots/time_slots_bloc.dart';
import 'package:chabo/cubits/floating_actions_cubit.dart';
import 'package:chabo/helpers/device_helper.dart';
import 'package:chabo/screens/forecast_screen.dart';
Expand Down Expand Up @@ -76,7 +77,16 @@ class Chabo extends StatelessWidget {
storageService: storageService,
notificationService: notificationService,
)..add(
AppEvent(),
NotificationAppEvent(),
),
),

/// Bloc intended to manage all TimeSlots
BlocProvider(
create: (_) => TimeSlotsBloc(
storageService: storageService,
)..add(
TimeSlotsAppEvent(),
),
),
],
Expand Down
9 changes: 9 additions & 0 deletions lib/const.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class Const {
'NOTIFICATION_FAVORITE_SLOTS_SETTINGS_ENABLED';
static const String notificationFavoriteSlotsValueKey =
'NOTIFICATION_FAVORITE_SLOTS_SETTINGS_VALUE';
static const String notificationFavoriteSlotsDaysValueKey =
'NOTIFICATION_FAVORITE_SLOTS_DAYS_SETTINGS_VALUE';

/// Notifications
static const String androidAppLogoPath =
Expand Down Expand Up @@ -112,6 +114,13 @@ class Const {
),
),
];
static List<Day> notificationFavoriteSlotsDaysDefaultValue = [
Day.monday,
Day.tuesday,
Day.wednesday,
Day.thursday,
Day.friday,
];

/// UI
static const bool isRightHandedDefaultValue = true;
Expand Down
Loading

0 comments on commit a88ac68

Please sign in to comment.