From d88d4688374db5468c174239352268cb01cb62e9 Mon Sep 17 00:00:00 2001 From: Joey Boerwinkel Date: Tue, 2 Jul 2024 08:50:40 +0200 Subject: [PATCH] feat(flutter_availability_data_interface): define the models and interface for availabilities --- .../lib/src/data_interface.dart | 40 +++++++ .../lib/src/models/availability.dart | 105 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 packages/flutter_availability_data_interface/lib/src/data_interface.dart create mode 100644 packages/flutter_availability_data_interface/lib/src/models/availability.dart diff --git a/packages/flutter_availability_data_interface/lib/src/data_interface.dart b/packages/flutter_availability_data_interface/lib/src/data_interface.dart new file mode 100644 index 0000000..ca0e62e --- /dev/null +++ b/packages/flutter_availability_data_interface/lib/src/data_interface.dart @@ -0,0 +1,40 @@ +import "package:flutter_availability_data_interface/src/models/availability.dart"; + +/// A base interface that defines the communication from the availability user +/// story to its persistance solution. +/// +/// This class needs to be implemented for your use case, for example a REST API +/// or a Firebase database. +abstract interface class AvailabilityDataInterface { + /// Retrieves a list of availabilities for the given [userId]. + /// + /// Whether this is a one time value or a continuous stream of values is up to + /// the implementation. + Stream> getAvailabilityForUser(String userId); + + /// Retrieves a specific availability for the given + /// [userId] and [availabilityId] + Stream getAvailabilityForUserById( + String userId, + String availabilityId, + ); + + /// Deletes a specific availability for the given + /// [userId] and [availabilityId] + Future deleteAvailabilityForUser(String userId, String availabilityId); + + /// Updates the availability for the given [userId] and [availabilityId] + /// + /// This will not work if no [availabilityId] for [userId] exists + Future updateAvailabilityForUser( + String userId, + String availabilityId, + AvailabilityModel updatedModel, + ); + + /// Creates a new persistant representation of an availability model + Future createAvailabilityForUser( + String userId, + AvailabilityModel availability, + ); +} diff --git a/packages/flutter_availability_data_interface/lib/src/models/availability.dart b/packages/flutter_availability_data_interface/lib/src/models/availability.dart new file mode 100644 index 0000000..120503c --- /dev/null +++ b/packages/flutter_availability_data_interface/lib/src/models/availability.dart @@ -0,0 +1,105 @@ +/// A model defining the data structure for an availability +class AvailabilityModel { + /// Creates a new availability + const AvailabilityModel({ + required this.userId, + required this.startDate, + required this.endDate, + required this.breaks, + this.id, + }); + + /// the identifier for this availability + final String? id; + + /// The uniquely identifiable string for who or what the + final String userId; + + /// The from date of this availability. + /// + /// [startDate] will always have to be before the end date. + final DateTime startDate; + + /// The until date of this availability + /// + /// [endDate] will always be before the start date. + final DateTime endDate; + + /// A list of breaks during the specified time period + final List breaks; + + /// Copies the current properties into a new instance of [AvailabilityModel], + /// except for the properties provided to this method. + AvailabilityModel copyWith({ + String? id, + String? userId, + DateTime? startDate, + DateTime? endDate, + List? breaks, + }) => + AvailabilityModel( + id: id ?? this.id, + userId: userId ?? this.userId, + startDate: startDate ?? this.startDate, + endDate: endDate ?? this.endDate, + breaks: breaks ?? this.breaks, + ); +} + +/// A model defining the structure of a break within an [AvailabilityModel] +class AvailabilityBreakModel { + /// Create a new AvailabilityBreakModel + const AvailabilityBreakModel({ + required this.startTime, + required this.endTime, + Duration? duration, + }) : _duration = duration; + + /// The start time for this break + /// + /// If duration is not the same as the difference between [startTime] and + /// [endTime], the [startTime] is considered the start of the period of which + /// a break of [_duration] can be held. + final DateTime startTime; + + /// The end time for this break + /// + /// If duration is not the same as the difference between [startTime] and + /// [endTime], the [endTime] is considered the end of the period of which + /// a break of [_duration] can be held. + final DateTime endTime; + + /// The full duration of the actual break. + /// + /// This is allowed to diverge from the difference between [startTime] and + /// [endTime] to indicate that the break is somewhere between [startTime] and + /// [endTime] + final Duration? _duration; + + /// Results in the set duration, or the difference between [startTime] and + /// [endTime] if no duration is set. + Duration get duration => _duration ?? period; + + /// The period in which the break will take place. + /// + /// Will be the same as [duration] if the initial [_duration] is null + Duration get period => endTime.difference(startTime); + + /// Whether the duration of the break matches the difference between + /// [startTime] and [endTime] + bool get isTight => _duration == null || _duration == period; + + /// Copies the current properties into a new instance of + /// [AvailabilityBreakModel], except for the properties provided + /// to this method. + AvailabilityBreakModel copyWith({ + DateTime? startTime, + DateTime? endTime, + Duration? duration, + }) => + AvailabilityBreakModel( + startTime: startTime ?? this.startTime, + endTime: endTime ?? this.endTime, + duration: duration ?? _duration, + ); +}