flutter_timetable/lib/src/block_service.dart
2022-11-18 10:20:11 +01:00

140 lines
3.6 KiB
Dart

// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:flutter/material.dart';
import 'package:timetable/src/models/time_block.dart';
/// Combine blocks that have the same id and the same time.
List<TimeBlock> combineBlocksWithId(List<TimeBlock> blocks) {
var newBlocks = <TimeBlock>[];
var groupedBlocks = <List<TimeBlock>>[];
for (var block in blocks) {
var found = false;
if (block.id == 0) {
newBlocks.add(block);
found = true;
} else {
found = _checkIfBlockWithIdExists(groupedBlocks, block);
}
if (!found) {
if (blocks
.where(
(b) =>
b != block &&
b.id == block.id &&
b.start == block.start &&
b.end == block.end,
)
.isNotEmpty) {
groupedBlocks.add([block]);
} else {
newBlocks.add(block);
}
}
}
_combineGroupedBlocks(groupedBlocks, newBlocks);
return newBlocks;
}
void _combineGroupedBlocks(
List<List<TimeBlock>> groupedBlocks,
List<TimeBlock> newBlocks,
) {
for (var block in groupedBlocks) {
var startMinute = block.first.start.minute +
block.first.start.hour * Duration.minutesPerHour;
var endMinute =
block.first.end.minute + block.first.end.hour * Duration.minutesPerHour;
var durationMinute = (endMinute - startMinute) * block.length;
var endTime = TimeOfDay(
hour: (startMinute + durationMinute) ~/ Duration.minutesPerHour,
minute: (startMinute + durationMinute) % Duration.minutesPerHour,
);
var newBlock = TimeBlock(
start: block.first.start,
end: endTime,
id: block.first.id,
// combine the childDimension of all the children
childDimension: block.fold(
0.0,
(previousValue, element) =>
(previousValue ?? 0.0) + (element.childDimension ?? 0.0),
),
child: Column(
children: [
for (var b in block) ...[b.child ?? Container()],
],
),
);
newBlocks.add(newBlock);
}
}
bool _checkIfBlockWithIdExists(
List<List<TimeBlock>> groupedBlocks,
TimeBlock block,
) {
for (var groupedBlock in groupedBlocks) {
if (groupedBlock.first.id == block.id &&
groupedBlock.first.start == block.start &&
groupedBlock.first.end == block.end) {
groupedBlock.add(block);
return true;
}
}
return false;
}
/// Group blocks with the same id together.
/// Items in the same group will be displayed in the same column.
List<List<TimeBlock>> groupBlocksById(List<TimeBlock> blocks) {
var groupedBlocks = <List<TimeBlock>>[];
var defaultGroup = <TimeBlock>[];
for (var block in blocks) {
var found = false;
if (block.id == 0) {
defaultGroup.add(block);
} else {
for (var groupedBlock in groupedBlocks) {
if (groupedBlock.first.id == block.id) {
groupedBlock.add(block);
found = true;
break;
}
}
if (!found) {
groupedBlocks.add([block]);
}
}
}
for (var block in defaultGroup) {
groupedBlocks.add([block]);
}
return groupedBlocks;
}
/// Merge blocks that fit below eachother into one column.
List<List<TimeBlock>> mergeBlocksInColumns(List<TimeBlock> blocks) {
var mergedBlocks = <List<TimeBlock>>[];
for (var block in blocks) {
var mergeIndex = 0;
for (var mergedBlock in mergedBlocks) {
if (!mergedBlock.any((b) => b.collidesWith(block))) {
mergedBlock.add(block);
break;
} else {
mergeIndex++;
}
}
if (mergedBlocks.length == mergeIndex) {
mergedBlocks.add([block]);
}
}
return mergedBlocks;
}