lali/ui/app-window.slint
2024-11-19 16:57:32 +01:00

169 lines
4.1 KiB
Text

import { State } from "./state.slint";
import { VText, VTextInput , VButton, ToggleButton, VActionButton, Svg, Palette } from "@selenite";
import { ComboBox } from "std-widgets.slint";
export component AppWindow inherits Window {
title: "Lali";
background: Palette.background;
default-font-size: 16px;
padding: 0px;
private property <bool> show-add-list-form: false;
HorizontalLayout {
width: parent.width;
height: parent.height;
sidebar := Rectangle {
horizontal-stretch: 0;
background: Palette.pane;
VerticalLayout {
alignment: start;
padding: 16px;
spacing: 8px;
HorizontalLayout {
alignment: space-between;
spacing: 64px;
VText {
text: "Lists";
font-size: 1.5rem;
}
VActionButton {
icon-svg: Svg.plus;
icon-colorize: Palette.green;
background: transparent;
clicked => { show-add-list-form = true }
}
}
if show-add-list-form : Rectangle {
horizontal-stretch: 0;
border-color: show-add-list-form ? Palette.card-background : transparent;
border-width: show-add-list-form ? 4px : 0px;
border-radius: show-add-list-form ? 8px : 0px;
VerticalLayout {
alignment: start;
padding: 16px;
spacing: 16px;
in-out property <string> name;
in-out property <string> anilist-user-name;
in-out property <string> anilist-list-name;
list-type := ComboBox {
model: ["Anilist"];
}
VTextInput {
label: "List name";
edited => { parent.name = self.text }
}
if list-type.current-value == "Anilist" : VTextInput {
label: "Anilist Username";
edited => { parent.anilist-user-name = self.text }
}
if list-type.current-value == "Anilist" : VTextInput {
label: "Anilist list name";
edited => { parent.anilist-list-name = self.text }
}
VButton {
text: "Add";
clicked => {
if list-type.current-value == "Anilist" {
State.add-anilist-list({
name: parent.name,
anilist-user-name: parent.anilist-user-name,
anilist-list-name: parent.anilist-list-name
});
}
show-add-list-form = false;
}
}
}
}
for list[index] in State.lists : ToggleButton {
text: list.name;
text-alignment: left;
active: list.selected;
clicked => {
State.select-list(index)
}
}
}
}
animes-view := VerticalLayout {
horizontal-stretch: 1;
spacing: 16px;
padding: 16px;
VerticalLayout {
spacing: 8px;
VText {
text: State.current-list.name;
font-size: 1.5rem;
}
VText {
text: "\{State.current-list.animes.length} animes";
font-size: 1rem;
}
}
animes-grid-background := Rectangle {
//background: #111111;
animes-grid := Flickable {
private property <int> number-of-items: State.current-list.animes.length;
private property <length> grid-spacing: 16px;
private property <length> item-min-width: 300px;
private property <int> item-per-row: floor(self.viewport-width / (item-min-width + grid-spacing));
private property <length> item-width: (parent.width - ((item-per-row - 1) * grid-spacing)) / item-per-row;
private property <length> item-height: 512px;
viewport-height: ceil(number-of-items / item-per-row) * (item-height + grid-spacing);
viewport-width: parent.width;
for anime[index] in State.current-list.animes : Rectangle {
x: mod(index, item-per-row) * (item-width + grid-spacing);
y: floor(index / item-per-row) * (item-height + grid-spacing);
width: item-width;
height: item-height;
//background: #444444;
VerticalLayout {
height: parent.height;
width: parent.width;
spacing: 8px;
animeImage := Rectangle {
vertical-stretch: 1;
clip: true;
border-radius: 8px;
Image {
height: parent.height;
width: parent.width;
source: anime.image;
image-fit: ImageFit.cover;
}
}
animeTitle := VText {
text: anime.title;
}
}
}
}
}
}
}
}
export { State }