mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-02 01:13:19 +00:00
234 lines
6.4 KiB
Text
234 lines
6.4 KiB
Text
import { Backend, TaskData } from "Backend.slint";
|
|
import { Button, VerticalBox, CheckBox, ScrollView, ComboBox } from "std-widgets.slint";
|
|
import { SideBar } from "SideBar.slint";
|
|
import { TaskLine } from "TaskLine.slint";
|
|
import { EventGroup } from "EventGroup.slint";
|
|
import { VPopupIconMenu, VDatePicker, VTimePicker, VCheckBox, VButton, VTag, VText, VTextInput, Palette } from "@vynui";
|
|
import { NewTaskData, SaveTaskData } from "Backend.slint";
|
|
|
|
export component MainView inherits Rectangle {
|
|
|
|
background: Palette.background;
|
|
private property<image> icon-visible: @image-url("./images/visible.png");
|
|
private property<image> icon-not-visible: @image-url("./images/not-visible.png");
|
|
private property<bool> completed-tasks-visible: false;
|
|
|
|
pure function formatZeroPadding(number: int) -> string {
|
|
if (number < 10) {
|
|
return "0\{number}";
|
|
}
|
|
return number;
|
|
}
|
|
|
|
VerticalLayout {
|
|
horizontal-stretch: 1;
|
|
padding: 16px;
|
|
spacing: 16px;
|
|
alignment: start;
|
|
HorizontalLayout {
|
|
horizontal-stretch: 1;
|
|
alignment: start;
|
|
spacing: 8px;
|
|
VButton {
|
|
text: "New task";
|
|
clicked => { Backend.open_new_task_form({
|
|
eventSourceId: -1,
|
|
eventId: -1,
|
|
})}
|
|
icon-source: @image-url("./images/add.png");
|
|
icon-colorize: Colors.greenyellow;
|
|
}
|
|
|
|
VButton {
|
|
text: "New event";
|
|
clicked => { Backend.open_new_event_form() }
|
|
icon-source: @image-url("./images/add.png");
|
|
icon-colorize: Colors.greenyellow;
|
|
}
|
|
VButton {
|
|
text: "Show/Hide completed tasks";
|
|
clicked => {
|
|
Backend.toggle_show_completed_tasks();
|
|
completed-tasks-visible = !completed-tasks-visible;
|
|
}
|
|
icon-source: completed-tasks-visible ? icon-visible : icon-not-visible;
|
|
icon-colorize: Palette.control-foreground;
|
|
}
|
|
}
|
|
Rectangle {
|
|
horizontal-stretch: 1;
|
|
background: Palette.background.brighter(0.2);
|
|
height: 1px;
|
|
}
|
|
|
|
Rectangle {
|
|
border-color: newTaskTitleInput.text != "" ? Palette.card-background : transparent;
|
|
border-width: newTaskTitleInput.text != "" ? 4px : 0px;
|
|
border-radius: newTaskTitleInput.text != "" ? 8px : 0px;
|
|
animate border-color, border-width {
|
|
duration: 500ms;
|
|
}
|
|
VerticalLayout {
|
|
in-out property <int> task-or-event: 1;
|
|
spacing: 8px;
|
|
padding: newTaskTitleInput.text != "" ? 16px : 0px;
|
|
animate padding {
|
|
duration: 250ms;
|
|
}
|
|
Rectangle {
|
|
min-height: 0px;
|
|
max-height: newTaskTitleInput.text != "" ? 512px : 0px;
|
|
opacity: newTaskTitleInput.text != "" ? 1 : 0;
|
|
clip: true;
|
|
animate max-height, opacity {
|
|
duration: 500ms;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
alignment: start;
|
|
spacing: 8px;
|
|
VerticalLayout {
|
|
alignment: end;
|
|
VButton {
|
|
text: task-or-event == 1 ? "Task" : "Event";
|
|
clicked => { task-or-event = task-or-event == 1 ? 0 : 1 }
|
|
}
|
|
}
|
|
VText { text: "for"; vertical-alignment: bottom;}
|
|
VerticalLayout {
|
|
alignment: end;
|
|
sourceInput := ComboBox {
|
|
model: Backend.sources;
|
|
}
|
|
}
|
|
VText { text: "on"; vertical-alignment: bottom;}
|
|
taskDateInput := VDatePicker {
|
|
label: "Date";
|
|
enabled: true;
|
|
}
|
|
HorizontalLayout {
|
|
visible: task-or-event == 0;
|
|
HorizontalLayout {
|
|
spacing: 4px;
|
|
VText { text: "between"; vertical-alignment: bottom; }
|
|
eventStartTimeInput := VTimePicker {
|
|
label: "Starts at";
|
|
}
|
|
VText { text: "and"; vertical-alignment: bottom; }
|
|
eventEndTimeInput := VTimePicker {
|
|
label: "Ends at";
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
newTaskTitleInput := VTextInput {
|
|
placeholder: "Add task";
|
|
accepted => {
|
|
if (task-or-event == 1) {
|
|
Backend.createTask({
|
|
sourceId: sourceInput.current-index,
|
|
eventId: -1,
|
|
title: newTaskTitleInput.text,
|
|
scheduled: taskDateInput.date.year != 0,
|
|
date: taskDateInput.date
|
|
})
|
|
} else {
|
|
Backend.createEvent({
|
|
sourceId: sourceInput.current-index,
|
|
title: newTaskTitleInput.text,
|
|
date: taskDateInput.date,
|
|
startsAt: eventStartTimeInput.time,
|
|
endsAt: eventEndTimeInput.time,
|
|
});
|
|
}
|
|
newTaskTitleInput.text = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Flickable {
|
|
horizontal-stretch: 1;
|
|
VerticalLayout {
|
|
alignment: start;
|
|
spacing: 16px;
|
|
if Backend.visible_tasks.length == 0 : VText {
|
|
text: "There is no task to show";
|
|
horizontal-alignment: center;
|
|
}
|
|
for day[dayIndex] in Backend.visible_tasks: VerticalLayout {
|
|
Rectangle {
|
|
background: Palette.card-background;
|
|
border-radius: 8px;
|
|
VerticalLayout {
|
|
padding: 16px;
|
|
HorizontalLayout {
|
|
alignment: start;
|
|
VText {
|
|
text: Backend.formatDate(day.date);
|
|
color: day.isLate ? Palette.orange : Palette.foreground;
|
|
font-size: 1.2rem;
|
|
}
|
|
VerticalLayout {
|
|
alignment: center;
|
|
VText {
|
|
text: day.relativeDaysDiff == 0 ? " - today" :
|
|
day.relativeDaysDiff == 1 ? " - tomorrow" :
|
|
day.relativeDaysDiff == -1 ? " - yesterday" :
|
|
day.relativeDaysDiff > 0 ? " - in \{day.relativeDaysDiff} days" :
|
|
" - \{-day.relativeDaysDiff} days ago";
|
|
color: Palette.foreground-hint;
|
|
font-size: 1rem;
|
|
}
|
|
}
|
|
}
|
|
for event[eventIndex] in day.events: VerticalLayout {
|
|
padding-top: 16px;
|
|
EventGroup {
|
|
event: event;
|
|
}
|
|
}
|
|
for task[taskIndex] in day.tasks: VerticalLayout {
|
|
padding-top: taskIndex == 0 ? 16px : 0px;
|
|
padding-bottom: 8px;
|
|
TaskLine {
|
|
task: task;
|
|
source-index: task.sourceId;
|
|
task-index: task.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if Backend.unscheduled-tasks.length > 0 : VerticalLayout {
|
|
Rectangle {
|
|
background: Palette.card-background;
|
|
border-radius: 8px;
|
|
VerticalLayout {
|
|
padding: 16px;
|
|
HorizontalLayout {
|
|
alignment: start;
|
|
VText {
|
|
text: "Unscheduled";
|
|
color: Palette.foreground;
|
|
font-size: 1.2rem;
|
|
}
|
|
}
|
|
for task[taskIndex] in Backend.unscheduled-tasks: VerticalLayout {
|
|
padding-top: taskIndex == 0 ? 16px : 0px;
|
|
padding-bottom: 8px;
|
|
TaskLine {
|
|
task: task;
|
|
source-index: task.sourceId;
|
|
task-index: task.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|