feat: Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import 'package:flutter/foundation.dart' show immutable;
|
||||
import 'package:krow/core/application/common/date_time_extension.dart';
|
||||
import 'package:krow/features/profile/schedule/domain/entities/schedule_slot.dart';
|
||||
|
||||
@immutable
|
||||
class DaySchedule {
|
||||
const DaySchedule({
|
||||
required this.date,
|
||||
required this.slots,
|
||||
this.isWeekly = false,
|
||||
this.deletedSlots,
|
||||
});
|
||||
|
||||
final DateTime date;
|
||||
final List<ScheduleSlot> slots;
|
||||
final bool isWeekly;
|
||||
final List<ScheduleSlot>? deletedSlots;
|
||||
|
||||
bool get isValid {
|
||||
bool isValid = true;
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
for (int k = i; k < slots.length; k++) {
|
||||
if (k == i) continue; // Skip validation for same slot
|
||||
|
||||
isValid = slots[i].isNotOverlappingWith(slots[k]);
|
||||
if (!isValid) return isValid;
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
bool get isViableForSaving {
|
||||
return slots.isNotEmpty || deletedSlots != null;
|
||||
}
|
||||
|
||||
DaySchedule copyWith({
|
||||
DateTime? date,
|
||||
List<ScheduleSlot>? slots,
|
||||
bool? isWeekly,
|
||||
List<ScheduleSlot>? deletedSlots,
|
||||
}) {
|
||||
return DaySchedule(
|
||||
date: date ?? this.date,
|
||||
slots: slots ?? this.slots,
|
||||
isWeekly: isWeekly ?? this.isWeekly,
|
||||
deletedSlots: deletedSlots ?? this.deletedSlots,
|
||||
);
|
||||
}
|
||||
|
||||
String getIdKey() => isWeekly ? date.getWeekdayId() : date.getDayDateId();
|
||||
|
||||
DateTime getLatestSlot() {
|
||||
if (slots.isEmpty) return date.copyWith(hour: 8, minute: 0);
|
||||
|
||||
var lastSlot = slots.first;
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (lastSlot.endTime.isBefore(slots[i].endTime)) {
|
||||
lastSlot = slots[i];
|
||||
}
|
||||
}
|
||||
|
||||
return lastSlot.endTime;
|
||||
}
|
||||
|
||||
DaySchedule removeSlotAtIndex(int slotIndex) {
|
||||
return copyWith(
|
||||
deletedSlots: slots[slotIndex].remoteId != null
|
||||
? [...?deletedSlots, slots[slotIndex]]
|
||||
: null,
|
||||
slots: List.from(slots)..removeAt(slotIndex),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import 'package:flutter/foundation.dart' show immutable;
|
||||
|
||||
@immutable
|
||||
class ScheduleSlot {
|
||||
const ScheduleSlot({
|
||||
required this.id,
|
||||
required this.startTime,
|
||||
required this.endTime,
|
||||
this.remoteId,
|
||||
});
|
||||
|
||||
factory ScheduleSlot.minFromStartTime({required DateTime start}) {
|
||||
if (start.hour > 19) start = start.copyWith(hour: 8);
|
||||
|
||||
return ScheduleSlot(
|
||||
id: start.millisecondsSinceEpoch.toString(),
|
||||
startTime: start.copyWith(minute: 0, second: 0),
|
||||
endTime: start.copyWith(minute: 0, second: 0).add(
|
||||
const Duration(hours: 5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final String id;
|
||||
final DateTime startTime;
|
||||
final DateTime endTime;
|
||||
final String? remoteId;
|
||||
|
||||
ScheduleSlot copyWith({
|
||||
String? id,
|
||||
DateTime? startTime,
|
||||
DateTime? endTime,
|
||||
String? remoteId,
|
||||
}) {
|
||||
return ScheduleSlot(
|
||||
id: id ?? this.id,
|
||||
startTime: startTime ?? this.startTime,
|
||||
endTime: endTime ?? this.endTime,
|
||||
remoteId: remoteId ?? this.remoteId,
|
||||
);
|
||||
}
|
||||
|
||||
ScheduleSlot editTime({
|
||||
DateTime? startTime,
|
||||
DateTime? endTime,
|
||||
}) {
|
||||
ScheduleSlot? slot;
|
||||
if (endTime != null) {
|
||||
slot = copyWith(
|
||||
startTime: endTime.difference(this.startTime).inHours.abs() < 5 ||
|
||||
endTime.isBefore(this.startTime)
|
||||
? endTime.subtract(const Duration(hours: 5))
|
||||
: this.startTime,
|
||||
endTime: endTime,
|
||||
);
|
||||
if (slot.startTime.day != slot.endTime.day) {
|
||||
final DateTime midnight = DateTime(
|
||||
endTime.year,
|
||||
endTime.month,
|
||||
endTime.day,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
slot = copyWith(
|
||||
startTime: midnight,
|
||||
endTime: midnight.add(const Duration(hours: 5)),
|
||||
);
|
||||
}
|
||||
return slot;
|
||||
} else if (startTime == null) {
|
||||
slot = this;
|
||||
} else {
|
||||
slot = copyWith(
|
||||
startTime: startTime,
|
||||
endTime: startTime.difference(this.endTime).inHours.abs() < 5 ||
|
||||
startTime.isAfter(this.endTime)
|
||||
? startTime.add(const Duration(hours: 5))
|
||||
: this.endTime,
|
||||
);
|
||||
|
||||
if (slot.startTime.day != slot.endTime.day) {
|
||||
final DateTime midnight = DateTime(
|
||||
startTime.year,
|
||||
startTime.month,
|
||||
startTime.day + 1,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
slot = copyWith(
|
||||
startTime: midnight.subtract(const Duration(hours: 5)),
|
||||
endTime: midnight,
|
||||
);
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
bool isNotOverlappingWith(ScheduleSlot other) {
|
||||
// End and start time should be before other slot's start time
|
||||
if (((endTime.isBefore(other.startTime) ||
|
||||
endTime.isAtSameMomentAs(other.startTime)) &&
|
||||
startTime.isBefore(other.startTime))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Or start and end time should be after other slot's end time
|
||||
return ((startTime.isAfter(other.endTime) ||
|
||||
startTime.isAtSameMomentAs(other.endTime)) &&
|
||||
endTime.isAfter(other.endTime));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Slot data: ID $id\n'
|
||||
'Start time: $startTime\n'
|
||||
'End time: $endTime';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user