Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: opening hours #541

Merged
merged 3 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/core/external/date_service.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
class DateService {
int currentWeekday() => DateTime.now().weekday;
int currentHour() => DateTime.now().hour;
DateTime get currentDateTime => DateTime.now();
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import 'package:coffeecard/features/opening_hours/domain/entities/timeslot.dart';
import 'package:flutter/material.dart';

class OpeningHoursLocalDataSource {
Map<int, Timeslot> getOpeningHours() {
const normalOperation = Timeslot(start: 8, end: 16);
const shortDayOperation = Timeslot(start: 8, end: 14);
const closed = Timeslot();
const openTime = TimeOfDay(hour: 8, minute: 0);
const normalDayCloseTime = TimeOfDay(hour: 15, minute: 30);
const shortDayCloseTime = TimeOfDay(hour: 13, minute: 30);

const normalDayOpeningHours = Timeslot(openTime, normalDayCloseTime);
const shortDayOpeningHours = Timeslot(openTime, shortDayCloseTime);

return {
DateTime.monday: normalOperation,
DateTime.tuesday: normalOperation,
DateTime.wednesday: normalOperation,
DateTime.thursday: normalOperation,
DateTime.friday: shortDayOperation,
DateTime.saturday: closed,
DateTime.sunday: closed,
DateTime.monday: normalDayOpeningHours,
DateTime.tuesday: normalDayOpeningHours,
DateTime.wednesday: normalDayOpeningHours,
DateTime.thursday: normalDayOpeningHours,
DateTime.friday: shortDayOpeningHours,
};
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:coffeecard/core/external/date_service.dart';
import 'package:coffeecard/features/opening_hours/data/datasources/opening_hours_local_data_source.dart';
import 'package:coffeecard/features/opening_hours/domain/entities/opening_hours.dart';
import 'package:coffeecard/features/opening_hours/domain/entities/timeslot.dart';
import 'package:coffeecard/features/opening_hours/domain/repositories/opening_hours_repository.dart';
import 'package:flutter/material.dart';
import 'package:fpdart/fpdart.dart';

class OpeningHoursRepositoryImpl implements OpeningHoursRepository {
final OpeningHoursLocalDataSource dataSource;
Expand All @@ -15,9 +18,11 @@ class OpeningHoursRepositoryImpl implements OpeningHoursRepository {
@override
OpeningHours getOpeningHours() {
final allOpeningHours = dataSource.getOpeningHours();
final currentWeekDay = dateService.currentWeekday();
final currentWeekday = dateService.currentDateTime.weekday;

final todaysOpeningHours = allOpeningHours[currentWeekDay]!;
final todaysOpeningHours = Option.fromNullable(
allOpeningHours[currentWeekday],
);

return OpeningHours(
allOpeningHours: allOpeningHours,
Expand All @@ -28,16 +33,12 @@ class OpeningHoursRepositoryImpl implements OpeningHoursRepository {
@override
bool isOpen() {
final todaysOpeningHours = getOpeningHours().todaysOpeningHours;
final currentTimeOfDay =
TimeOfDay.fromDateTime(dateService.currentDateTime);

if (todaysOpeningHours.isClosed) {
return false;
}

final currentHour = dateService.currentHour();

if (currentHour < todaysOpeningHours.start! ||
currentHour > todaysOpeningHours.end!) return false;

return true;
return todaysOpeningHours.match(
() => false,
currentTimeOfDay.isInTimeslot,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:coffeecard/features/opening_hours/domain/entities/timeslot.dart';
import 'package:equatable/equatable.dart';
import 'package:fpdart/fpdart.dart';

class OpeningHours extends Equatable {
final Map<int, Timeslot> allOpeningHours;
final Timeslot todaysOpeningHours;
final Option<Timeslot> todaysOpeningHours;

const OpeningHours({
required this.allOpeningHours,
Expand Down
38 changes: 28 additions & 10 deletions lib/features/opening_hours/domain/entities/timeslot.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
import 'package:coffeecard/core/strings.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';

/// A timeslot with a start and end time.
class Timeslot extends Equatable {
final int? start;
final int? end;
final TimeOfDay startTime;
final TimeOfDay endTime;

const Timeslot({this.start, this.end});
const Timeslot(this.startTime, this.endTime);

bool get isClosed => start == null || end == null;
String format(BuildContext context) {
final start = startTime.format(context);
final end = endTime.format(context);
return '$start-$end';
}

@override
String toString() => isClosed
? Strings.closed
: '${start.toString().padLeft(2, '0')}:00 - $end:00';
List<Object?> get props => [startTime, endTime];
}

@override
List<Object?> get props => [start, end];
/// Operators for comparing [TimeOfDay]s.
extension TimeOfDayOperators on TimeOfDay {
/// Returns true if [other] is before [this].
bool operator <=(TimeOfDay other) {
if (hour < other.hour) {
return true;
} else if (hour == other.hour) {
return minute <= other.minute;
} else {
return false;
}
}

bool isInTimeslot(Timeslot timeslot) {
return timeslot.startTime <= this && this <= timeslot.endTime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:coffeecard/features/opening_hours/domain/entities/timeslot.dart'
import 'package:coffeecard/features/opening_hours/domain/usecases/check_open_status.dart';
import 'package:coffeecard/features/opening_hours/domain/usecases/get_opening_hours.dart';
import 'package:equatable/equatable.dart';
import 'package:fpdart/fpdart.dart';

part 'opening_hours_state.dart';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class OpeningHoursInitial extends OpeningHoursState {

class OpeningHoursLoaded extends OpeningHoursState {
final Map<int, Timeslot> openingHours;
final Timeslot todaysOpeningHours;
final Option<Timeslot> todaysOpeningHours;
final bool isOpen;

const OpeningHoursLoaded({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ class OpeningHoursPage extends StatelessWidget {
return MaterialPageRoute(builder: (_) => OpeningHoursPage(state: state));
}

List<MapEntry<int, Timeslot>> get openingHours {
return state.openingHours.entries.toList()
..sort((a, b) => a.key.compareTo(b.key));
}

@override
Widget build(BuildContext context) {
return AppScaffold.withTitle(
Expand All @@ -37,7 +32,7 @@ class OpeningHoursPage extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_OpeningHoursView(openingHours: openingHours),
_OpeningHoursView(openingHours: state.openingHours),
const Gap(36),
Row(
children: [
Expand Down Expand Up @@ -65,18 +60,21 @@ class OpeningHoursPage extends StatelessWidget {
class _OpeningHoursView extends StatelessWidget {
const _OpeningHoursView({required this.openingHours});

final List<MapEntry<int, Timeslot>> openingHours;
final Map<int, Timeslot> openingHours;

@override
Widget build(BuildContext context) {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: openingHours.length,
itemCount: Strings.weekdaysPlural.length,
separatorBuilder: (_, __) => const Gap(12),
itemBuilder: (context, index) {
final weekday = openingHours[index].key;
final hours = openingHours[index].value;
itemBuilder: (_, index) {
final weekday = index + 1;
final hours = switch (openingHours[weekday]) {
final Timeslot timeslot => timeslot.format(context),
_ => Strings.closed,
};

return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expand All @@ -85,7 +83,10 @@ class _OpeningHoursView extends StatelessWidget {
Strings.weekdaysPlural[weekday]!,
style: AppTextStyle.settingKey,
),
Text(hours.toString(), style: AppTextStyle.receiptItemKey),
Text(
hours,
style: AppTextStyle.receiptItemKey,
),
],
);
},
Expand Down
Loading