2024-10-11 16:26:13 +02:00
|
|
|
/*
|
|
|
|
* Mirai. Copyright (C) 2024 Vyn
|
|
|
|
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
|
|
|
|
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "View.h"
|
|
|
|
#include "utils.h"
|
2024-11-06 18:38:42 +01:00
|
|
|
#include <algorithm>
|
2024-10-11 16:26:13 +02:00
|
|
|
#include <iostream>
|
|
|
|
#include <iterator>
|
|
|
|
#include <ranges>
|
|
|
|
|
|
|
|
namespace mirai
|
|
|
|
{
|
|
|
|
|
|
|
|
View::View(Mirai *mirai) : mirai_(mirai)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::hideCompletedTasks(bool hide)
|
|
|
|
{
|
|
|
|
shouldHideCompletedTasks_ = hide;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool View::shouldHideCompletedTasks() const
|
|
|
|
{
|
|
|
|
return shouldHideCompletedTasks_;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Date> View::getDates()
|
|
|
|
{
|
|
|
|
std::vector<Date> datesVector;
|
|
|
|
for (auto &date : dates) {
|
|
|
|
datesVector.push_back(date.first);
|
|
|
|
}
|
|
|
|
return datesVector;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Task> View::getTasksForDate(const Date &date)
|
|
|
|
{
|
|
|
|
return dates.at(date).tasks;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Event> View::getEventsForDate(const Date &date)
|
|
|
|
{
|
2024-10-29 15:02:46 +01:00
|
|
|
if (!dates.contains(date)) {
|
|
|
|
return {};
|
|
|
|
}
|
2024-10-11 16:26:13 +02:00
|
|
|
return dates.at(date).events;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Task> View::getUnscheduledTasks()
|
|
|
|
{
|
|
|
|
return unscheduledTasks_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::update()
|
|
|
|
{
|
|
|
|
dates.clear();
|
|
|
|
unscheduledTasks_.clear();
|
|
|
|
|
|
|
|
auto todayDate = Date(std::chrono::system_clock::now());
|
|
|
|
|
|
|
|
for (int sourceId : sourcesIds_) {
|
|
|
|
Source *source = mirai_->getSourceById(sourceId);
|
|
|
|
for (auto day : source->getDays()) {
|
|
|
|
// day's tasks
|
|
|
|
auto sourceTasks = day.tasks() | std::ranges::views::filter([&](const Task &task) {
|
2024-10-16 11:04:30 +02:00
|
|
|
if (day.date() >= todayDate) {
|
|
|
|
return true;
|
|
|
|
}
|
2024-10-11 16:26:13 +02:00
|
|
|
if (shouldHideCompletedTasks()) {
|
|
|
|
return task.checked() == false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
2024-10-16 11:04:30 +02:00
|
|
|
if (day.date() >= todayDate || std::ranges::distance(sourceTasks) > 0) {
|
2024-10-11 16:26:13 +02:00
|
|
|
|
|
|
|
if (!dates.contains(day.date())) {
|
|
|
|
dates.insert_or_assign(day.date(), DateView{});
|
|
|
|
}
|
|
|
|
auto &tasks = dates.at(day.date()).tasks;
|
|
|
|
tasks.insert(tasks.end(), sourceTasks.begin(), sourceTasks.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
// day's events
|
2024-11-01 13:43:45 +01:00
|
|
|
auto sourceEvents =
|
|
|
|
day.events() | std::ranges::views::filter([&](const Event &event) {
|
|
|
|
return (!shouldHideCompletedTasks() || day.date() >= todayDate) ||
|
|
|
|
findFirst(event.queryTasks(), [&](const Task &task) {
|
|
|
|
return task.checked() == false;
|
|
|
|
}).has_value();
|
|
|
|
});
|
2024-10-11 16:26:13 +02:00
|
|
|
|
2024-10-16 11:04:30 +02:00
|
|
|
if (day.date() >= todayDate || std::ranges::distance(sourceEvents) > 0) {
|
2024-10-11 16:26:13 +02:00
|
|
|
if (!dates.contains(day.date())) {
|
|
|
|
dates.insert_or_assign(day.date(), DateView{});
|
|
|
|
}
|
|
|
|
auto &events = dates.at(day.date()).events;
|
|
|
|
events.insert(events.end(), sourceEvents.begin(), sourceEvents.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// unscheduled tasks
|
|
|
|
auto tasks = source->getUnscheduledTasks();
|
|
|
|
unscheduledTasks_.insert(unscheduledTasks_.end(), tasks.begin(), tasks.end());
|
|
|
|
}
|
2024-11-06 18:38:42 +01:00
|
|
|
|
|
|
|
for (auto &date : dates) {
|
|
|
|
auto &events = date.second.events;
|
|
|
|
std::sort(events.begin(), events.end(), [](const Event &a, const Event &b) {
|
|
|
|
return a.startsAt() < b.startsAt();
|
|
|
|
});
|
|
|
|
}
|
2024-10-11 16:26:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void View::removeSources()
|
|
|
|
{
|
|
|
|
sourcesIds_.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::addSource(const Source &source)
|
|
|
|
{
|
|
|
|
sourcesIds_.push_back(source.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::setSources(const std::vector<Source> &sources)
|
|
|
|
{
|
|
|
|
sourcesIds_.clear();
|
|
|
|
std::transform(
|
|
|
|
sources.begin(), sources.end(), std::back_inserter(sourcesIds_),
|
|
|
|
[](const Source &source) {
|
|
|
|
return source.id;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::setAllSources()
|
|
|
|
{
|
|
|
|
const auto &sources = mirai_->getSources();
|
|
|
|
sourcesIds_.clear();
|
|
|
|
std::transform(
|
|
|
|
sources.begin(), sources.end(), std::back_inserter(sourcesIds_),
|
|
|
|
[](const std::unique_ptr<Source> &source) {
|
|
|
|
return source->id;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool View::isSourceSelected(const Source &source) const
|
|
|
|
{
|
|
|
|
for (auto &sourceId : sourcesIds_) {
|
|
|
|
if (sourceId == source.id) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t View::activeSourceCount() const
|
|
|
|
{
|
|
|
|
return sourcesIds_.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mirai
|