feat: Refactor code structure and optimize performance across multiple modules

This commit is contained in:
Achintha Isuru
2025-11-17 23:29:28 -05:00
parent 831570f2e0
commit a64cbd9edf
1508 changed files with 105319 additions and 0 deletions

View File

@@ -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),
);
}
}

View File

@@ -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';
}
}