mirai/ui/MainView.slint

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