Add basic album list
This commit is contained in:
71
ui/albums.slint
Normal file
71
ui/albums.slint
Normal file
@@ -0,0 +1,71 @@
|
||||
import { AlbumCover } from "types.slint";
|
||||
import { Global } from "global.slint";
|
||||
import { ScrollView, HorizontalBox, Palette } from "std-widgets.slint";
|
||||
import { ImagePreview } from "timeline.slint";
|
||||
|
||||
component AlbumCover {
|
||||
in property <AlbumCover> album;
|
||||
|
||||
states [
|
||||
pressed when touch.pressed: {
|
||||
click-effect.opacity: 0.2;
|
||||
}
|
||||
default: {
|
||||
click-effect.opacity: 0;
|
||||
}
|
||||
]
|
||||
|
||||
Rectangle {
|
||||
background: Palette.alternate-background;
|
||||
border-radius: 24px;
|
||||
clip: true;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 20px;
|
||||
|
||||
ImagePreview {
|
||||
preview: album.thumbnail;
|
||||
size: 100px;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: album.name;
|
||||
horizontal-alignment: left;
|
||||
vertical-alignment: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
click_effect := Rectangle {
|
||||
background: Palette.accent-foreground;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
touch := TouchArea {}
|
||||
}
|
||||
}
|
||||
|
||||
export component Albums {
|
||||
private property <[AlbumCover]> albums: Global.albums;
|
||||
|
||||
property <length> min-image-size: Global.min-image-size;
|
||||
property <length> min-size-with-margin: min-image-size + Global.image-margin;
|
||||
|
||||
ScrollView {
|
||||
mouse-drag-pan-enabled: true;
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: center;
|
||||
VerticalLayout {
|
||||
min-width: min-image-size;
|
||||
alignment: start;
|
||||
spacing: 10px;
|
||||
|
||||
for album[i] in albums : AlbumCover {
|
||||
album: album;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Header } from "header.slint";
|
||||
import { Footer, FooterButton } from "footer.slint";
|
||||
|
||||
import { Global } from "global.slint";
|
||||
import { Albums } from "albums.slint";
|
||||
export { Global }
|
||||
|
||||
enum View {
|
||||
@@ -32,6 +33,7 @@ export component AppWindow inherits Window {
|
||||
|
||||
if !Global.logged-in: LoginView {}
|
||||
if Global.logged-in && view == View.Timeline: Timeline {}
|
||||
if Global.logged-in && view == View.Albums: Albums {}
|
||||
|
||||
Footer {
|
||||
FooterButton {
|
||||
@@ -46,7 +48,10 @@ export component AppWindow inherits Window {
|
||||
FooterButton {
|
||||
title: "Album";
|
||||
icon: @image-url("../assets/album.svg");
|
||||
clicked => { view = View.Albums}
|
||||
clicked => {
|
||||
view = View.Albums;
|
||||
Global.load-albums();
|
||||
}
|
||||
}
|
||||
FooterButton {
|
||||
title: "Library";
|
||||
|
||||
@@ -7,10 +7,10 @@ export component FooterButton inherits Rectangle {
|
||||
|
||||
states [
|
||||
pressed when touch.pressed: {
|
||||
background: #0000ff30;
|
||||
background: #0000ff30; // TODO: palette
|
||||
}
|
||||
hovered when touch.has-hover: {
|
||||
background: #0000ff15;
|
||||
background: #0000ff15; // TODO: palette
|
||||
}
|
||||
default: {
|
||||
background: #0000;
|
||||
@@ -30,7 +30,7 @@ export component FooterButton inherits Rectangle {
|
||||
padding-right: 20px;
|
||||
Image {
|
||||
source: icon;
|
||||
colorize: #accbfa;
|
||||
colorize: Palette.accent-background;
|
||||
}
|
||||
Text {
|
||||
text: title;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ImageBucket, ImagePreview } from "types.slint";
|
||||
import { ImageBucket, ImagePreview, AlbumCover } from "types.slint";
|
||||
|
||||
export global Global {
|
||||
in-out property <bool> logged-in: false;
|
||||
in-out property <length> min-image-size: 88px;
|
||||
in-out property <length> image-margin: 2px;
|
||||
in-out property <ImagePreview> viewed-image;
|
||||
in-out property <[AlbumCover]> albums;
|
||||
in-out property <[ImageBucket]> image-buckets: [
|
||||
{ key: "2026-02-01", title: "Feb 1, 2026", count: 12 },
|
||||
{ key: "2026-02-02", title: "Feb 2, 2026", count: 12 },
|
||||
@@ -17,4 +18,5 @@ export global Global {
|
||||
callback set-timeline-width(length);
|
||||
callback timeline-scrolled(length);
|
||||
callback view-image(string);
|
||||
callback load-albums();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ScrollView } from "std-widgets.slint";
|
||||
import { ScrollView, Palette } from "std-widgets.slint";
|
||||
import { Global } from "global.slint";
|
||||
import { ImageBucket, Visibility, ImagePreview } from "types.slint";
|
||||
|
||||
component ImagePreview inherits Rectangle {
|
||||
export component ImagePreview inherits Rectangle {
|
||||
in property <ImagePreview> preview;
|
||||
in property <length> size: 32px;
|
||||
callback clicked <=> touch.clicked;
|
||||
|
||||
width: size;
|
||||
height: size;
|
||||
clip: true;
|
||||
@@ -15,12 +17,7 @@ component ImagePreview inherits Rectangle {
|
||||
source: preview.image;
|
||||
}
|
||||
|
||||
touch := TouchArea {
|
||||
clicked => {
|
||||
Global.viewed-image = root.preview;
|
||||
Global.view-image(root.preview.asset-id);
|
||||
}
|
||||
}
|
||||
touch := TouchArea {}
|
||||
}
|
||||
|
||||
component TimelineBlock inherits VerticalLayout {
|
||||
@@ -62,14 +59,15 @@ component TimelineBlock inherits VerticalLayout {
|
||||
|
||||
if !checked : Image {
|
||||
source: @image-url("../assets/unchecked.svg");
|
||||
colorize: #aaa;
|
||||
colorize: Palette.foreground;
|
||||
opacity: 0.8;
|
||||
height: title.height;
|
||||
width: self.height;
|
||||
}
|
||||
|
||||
if checked : Image {
|
||||
source: @image-url("../assets/checked.svg");
|
||||
colorize: #accbfa;
|
||||
colorize: Palette.accent-background;
|
||||
height: title.height;
|
||||
width: self.height;
|
||||
}
|
||||
@@ -91,6 +89,10 @@ component TimelineBlock inherits VerticalLayout {
|
||||
size: image-size;
|
||||
x: Global.image-margin / 2 + Math.mod(i, count-x) * (Global.image-margin + image-size);
|
||||
y: Math.floor(i / count-x) * (image-size + Global.image-margin);
|
||||
clicked => {
|
||||
Global.viewed-image = preview;
|
||||
Global.view-image(preview.asset-id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,3 +33,11 @@ export struct ImageBucket {
|
||||
visibility: Visibility,
|
||||
}
|
||||
|
||||
export struct AlbumCover {
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
thumbnail: ImagePreview,
|
||||
asset_count: int,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user