mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-03 01:33:19 +00:00
Add a Calendar view on the right side
This commit is contained in:
parent
a80515ff90
commit
f1ac8a42d1
18 changed files with 406 additions and 130 deletions
|
@ -5,10 +5,13 @@
|
|||
*/
|
||||
|
||||
#include "AppWindowBackend.h"
|
||||
#include "AppWindow.h"
|
||||
#include "SeleniteSetup.h"
|
||||
#include "Utils.h"
|
||||
#include "appwindow.h"
|
||||
#include "mirai-core/DataProvider.h"
|
||||
#include "mirai-core/DateTime.h"
|
||||
#include "mirai-core/Day.h"
|
||||
#include "mirai-core/MarkdownDataProvider.h"
|
||||
#include "mirai-core/Mirai.h"
|
||||
#include "slint.h"
|
||||
#include "slint_string.h"
|
||||
|
@ -34,6 +37,7 @@ AppWindowBackend::AppWindowBackend(mirai::Mirai *miraiInstance)
|
|||
{
|
||||
sources_ = std::make_shared<slint::VectorModel<ui::Source>>();
|
||||
days_ = std::make_shared<slint::VectorModel<ui::Day>>();
|
||||
calendar_ = std::make_shared<slint::VectorModel<ui::CalendarDay>>();
|
||||
unscheduledTasks_ = std::make_shared<slint::VectorModel<ui::TaskData>>();
|
||||
tags_ = std::make_shared<slint::VectorModel<slint::SharedString>>();
|
||||
auto sourcesNames = std::make_shared<slint::MapModel<ui::Source, slint::SharedString>>(
|
||||
|
@ -43,14 +47,23 @@ AppWindowBackend::AppWindowBackend(mirai::Mirai *miraiInstance)
|
|||
}
|
||||
);
|
||||
|
||||
const auto palette =
|
||||
selenite::parseJson(std::string(getenv("HOME")) + "/.config/evalyte/theme.json");
|
||||
const auto palettePath = std::string(getenv("HOME")) + "/.config/evalyte/theme.json";
|
||||
const auto palette = selenite::parseJson(palettePath);
|
||||
if (palette.has_value()) {
|
||||
std::cerr << "Warning, no evalyte/theme.json found" << std::endl;
|
||||
setSelenitePalette(mainWindow_, palette.value());
|
||||
std::cerr << "Warning, no " << palettePath << " found" << std::endl;
|
||||
setSelenitePalette(mainWindow_->global<ui::Palette>(), palette.value());
|
||||
setSelenitePalette(settingsWindow_->global<ui::Palette>(), palette.value());
|
||||
}
|
||||
|
||||
mainWindow_->global<ui::Backend>().set_sources(sourcesNames);
|
||||
settingsWindow_->global<ui::Backend>().set_sources(sourcesNames);
|
||||
|
||||
mainWindow_->global<ui::Backend>().set_sources_selected(sources_);
|
||||
settingsWindow_->global<ui::Backend>().set_sources_selected(sources_);
|
||||
|
||||
mainWindow_->global<ui::Backend>().set_tags(tags_);
|
||||
mainWindow_->global<ui::Backend>().set_days(days_);
|
||||
mainWindow_->global<ui::Backend>().set_calendar(calendar_);
|
||||
|
||||
view_.setAllSources();
|
||||
view_.update();
|
||||
|
@ -92,10 +105,17 @@ void AppWindowBackend::setupUtilsCallbacks()
|
|||
};
|
||||
return std::format("{:%B %d}", chronoDate);
|
||||
});
|
||||
|
||||
mainWindow_->global<ui::Backend>().on_format_date_relative([&](const ui::Date &date) {
|
||||
return formatDateRelative(date);
|
||||
});
|
||||
}
|
||||
|
||||
void AppWindowBackend::setupCallbacks()
|
||||
{
|
||||
mainWindow_->global<ui::Backend>().on_settings_clicked([&]() {
|
||||
settingsWindow_->show();
|
||||
});
|
||||
mainWindow_->global<ui::Backend>().on_task_clicked([&](int sourceId, int taskId) {
|
||||
auto source = miraiInstance_->getSourceById(sourceId);
|
||||
assert(source);
|
||||
|
@ -142,10 +162,6 @@ void AppWindowBackend::setupCallbacks()
|
|||
reloadTasks();
|
||||
});
|
||||
|
||||
mainWindow_->global<ui::Backend>().set_sources_selected(sources_);
|
||||
mainWindow_->global<ui::Backend>().set_tags(tags_);
|
||||
mainWindow_->global<ui::Backend>().set_days(days_);
|
||||
|
||||
mainWindow_->global<ui::Backend>().on_save_task([&](ui::SaveTaskData newTaskData) {
|
||||
auto source = miraiInstance_->getSourceById(newTaskData.sourceId);
|
||||
assert(source);
|
||||
|
@ -326,6 +342,42 @@ void AppWindowBackend::reloadTasks()
|
|||
});
|
||||
}
|
||||
mainWindow_->global<ui::Backend>().set_unscheduled_tasks(unscheduledTasks_);
|
||||
|
||||
calendar_->clear();
|
||||
for (int dayIndex = 0; dayIndex < 7; ++dayIndex) {
|
||||
std::chrono::year_month_day nextDate =
|
||||
std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now()) +
|
||||
std::chrono::days{dayIndex};
|
||||
auto currentDate = mirai::Date{nextDate};
|
||||
auto events = view_.getEventsForDate(currentDate);
|
||||
auto slintEvents = std::make_shared<slint::VectorModel<ui::CalendarDayEvent>>();
|
||||
auto relativeDaysDiff = std::chrono::duration_cast<std::chrono::days>(
|
||||
std::chrono::sys_days(currentDate.toStdChrono()) -
|
||||
std::chrono::sys_days(todayDate.toStdChrono())
|
||||
)
|
||||
.count();
|
||||
if (relativeDaysDiff < 0 || relativeDaysDiff >= 3) {
|
||||
continue;
|
||||
}
|
||||
const std::vector<mirai::Event> eventsForDate = view_.getEventsForDate(currentDate);
|
||||
for (int eventIndex = 0; eventIndex < eventsForDate.size(); ++eventIndex) {
|
||||
auto ¤tEvent = eventsForDate.at(eventIndex);
|
||||
slintEvents->push_back(ui::CalendarDayEvent{
|
||||
.title = slint::SharedString(currentEvent.title()),
|
||||
.startsAt = MiraiTimeToSlintTime(currentEvent.startsAt()),
|
||||
.endsAt = MiraiTimeToSlintTime(currentEvent.endsAt()),
|
||||
});
|
||||
}
|
||||
|
||||
auto calendarDay = ui::CalendarDay{
|
||||
.events = slintEvents,
|
||||
.date = MiraiDateToSlintDate(currentDate),
|
||||
.header =
|
||||
slint::SharedString(capitalize(formatDateRelative(MiraiDateToSlintDate(currentDate))
|
||||
))
|
||||
};
|
||||
calendar_->push_back(calendarDay);
|
||||
}
|
||||
}
|
||||
|
||||
void AppWindowBackend::reloadSources()
|
||||
|
@ -334,9 +386,12 @@ void AppWindowBackend::reloadSources()
|
|||
bool noSourceSelected = miraiInstance_->getSources().size() == view_.activeSourceCount();
|
||||
for (const auto &source : miraiInstance_->getSources()) {
|
||||
bool isSourceSelected = view_.isSourceSelected(*source);
|
||||
mirai::MarkdownDataProvider *sourceProvider =
|
||||
dynamic_cast<mirai::MarkdownDataProvider *>(source->dataProvider());
|
||||
sources_->push_back(
|
||||
{.name = slint::SharedString(source->name()),
|
||||
.selected = isSourceSelected && !noSourceSelected}
|
||||
.selected = isSourceSelected && !noSourceSelected,
|
||||
.path = slint::SharedString(sourceProvider->path())}
|
||||
);
|
||||
}
|
||||
mainWindow_->global<ui::Backend>().set_no_source_selected(noSourceSelected);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "appwindow.h"
|
||||
#include "AppWindow.h"
|
||||
#include "mirai-core/Mirai.h"
|
||||
#include "mirai-core/View.h"
|
||||
#include "slint.h"
|
||||
|
@ -29,9 +29,11 @@ class AppWindowBackend
|
|||
std::shared_ptr<slint::VectorModel<ui::Source>> sources_;
|
||||
std::shared_ptr<slint::VectorModel<slint::SharedString>> tags_;
|
||||
std::shared_ptr<slint::VectorModel<ui::Day>> days_;
|
||||
std::shared_ptr<slint::VectorModel<ui::CalendarDay>> calendar_;
|
||||
std::shared_ptr<slint::VectorModel<ui::TaskData>> unscheduledTasks_;
|
||||
|
||||
slint::ComponentHandle<ui::AppWindow> mainWindow_ = ui::AppWindow::create();
|
||||
slint::ComponentHandle<ui::SettingsWindow> settingsWindow_ = ui::SettingsWindow::create();
|
||||
|
||||
mirai::Mirai *miraiInstance_;
|
||||
mirai::View view_;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "appwindow.h"
|
||||
#include "AppWindow.h"
|
||||
#include "selenite/palette.h"
|
||||
#include "slint_color.h"
|
||||
|
||||
|
@ -15,10 +15,8 @@ slint::Color seleniteColorToSlint(const selenite::Color &color)
|
|||
return slint::Color::from_rgb_uint8(color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void setSelenitePalette(slint::ComponentHandle<ui::AppWindow> ui, const selenite::Palette &palette)
|
||||
void setSelenitePalette(const ui::Palette &uiPalette, const selenite::Palette &palette)
|
||||
{
|
||||
auto &uiPalette = ui->global<ui::Palette>();
|
||||
|
||||
uiPalette.set_background(seleniteColorToSlint(palette.background));
|
||||
uiPalette.set_pane(seleniteColorToSlint(palette.pane));
|
||||
uiPalette.set_foreground(seleniteColorToSlint(palette.foreground));
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
#include <cctype>
|
||||
#include <format>
|
||||
#include <string>
|
||||
|
||||
std::string formatZeroPadding(const int number)
|
||||
{
|
||||
|
@ -14,6 +17,29 @@ std::string formatZeroPadding(const int number)
|
|||
return std::to_string(number);
|
||||
}
|
||||
|
||||
std::string formatDateRelative(const ui::Date &date)
|
||||
{
|
||||
auto todayDate = mirai::Date(std::chrono::system_clock::now());
|
||||
auto relativeDaysDiff = std::chrono::duration_cast<std::chrono::days>(
|
||||
std::chrono::sys_days(SlintDateToMiraiDate(date).toStdChrono()) -
|
||||
std::chrono::sys_days(todayDate.toStdChrono())
|
||||
)
|
||||
.count();
|
||||
|
||||
if (relativeDaysDiff == 0) {
|
||||
return std::string("today");
|
||||
} else if (relativeDaysDiff == 1) {
|
||||
return std::string("tomorrow");
|
||||
}
|
||||
return std::format("in {} days", relativeDaysDiff);
|
||||
};
|
||||
|
||||
std::string capitalize(std::string str)
|
||||
{
|
||||
str[0] = static_cast<char>(toupper(str[0]));
|
||||
return str;
|
||||
};
|
||||
|
||||
std::string SlintDateToStdString(const ui::Date &date)
|
||||
{
|
||||
return std::to_string(date.year) + "-" + formatZeroPadding(date.month) + "-" +
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "appwindow.h"
|
||||
#include "AppWindow.h"
|
||||
#include "mirai-core/DateTime.h"
|
||||
#include <string>
|
||||
|
||||
std::string formatZeroPadding(const int number);
|
||||
std::string formatDateRelative(const ui::Date &date);
|
||||
std::string capitalize(std::string str);
|
||||
std::string SlintDateToStdString(const ui::Date &date);
|
||||
mirai::Date SlintDateToMiraiDate(const ui::Date &date);
|
||||
ui::Date MiraiDateToSlintDate(const mirai::Date &date);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue