Update Pexels and fix binding loops

This commit is contained in:
CanadianBaconBoi 2026-05-08 23:30:01 +02:00
parent 4c7bd2694f
commit 48c493c4f5
4 changed files with 68 additions and 63 deletions

View File

@ -5,7 +5,6 @@ build = "build.rs"
edition = "2024"
[dependencies]
#slint = { version = "1.16.1", default-features = false, features = [
slint = { git = "https://github.com/slint-ui/slint", branch = "master", default-features = false, features = [
"std",
"compat-1-2",
@ -20,7 +19,7 @@ greetd_ipc = { version = "0.10.3", features = [
"tokio-codec",
] }
i-slint-core = { git = "https://github.com/slint-ui/slint", branch = "master" }
toml = { version = "1.1.2+spec-1.1.0", features = ["serde"] }
toml = { version = "1.1.2", features = ["serde"] }
serde = { version = "1.0.228", features = ["derive"] }
serde-aux = "4.7.0"
zbus = { version = "5.15.0", features = ["blocking"] }
@ -29,11 +28,11 @@ tokio-stream = {version = "0.1.18", features = ["fs"]}
greetd-stub = "0.3.0"
chrono = "0.4.44"
pexels-api = "0.0.5"
pexels-api = { git = "https://github.com/houseme/pexels", rev = "b0b692a" }
reqwest = { version = "0.13.3", features = ["json", "default-tls"] }
magick_rust = "2.0.0"
rand = "0.9.4"
[build-dependencies]
#slint-build = "1.16.1"
slint-build = { git = "https://github.com/slint-ui/slint", branch = "master" }

View File

@ -8,7 +8,8 @@ use greetd_ipc::codec::TokioCodec;
use i_slint_core::api::{ComponentHandle, Global, Image, Rgba8Pixel, SharedPixelBuffer, Weak};
use i_slint_core::model::{Model, VecModel};
use magick_rust::MagickWand;
use pexels_api::{Pexels, SearchBuilder};
use pexels_api::{PexelsClient, SearchParams};
use rand::seq::SliceRandom;
use tokio::fs::File;
use tokio::io::{AsyncBufReadExt, BufReader, Lines};
use tokio::net::UnixStream;
@ -273,7 +274,6 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
let reqwest_client = match reqwest::ClientBuilder::new()
.tls_backend_rustls()
// .timeout(std::time::Duration::from_secs(60))
.http2_prior_knowledge()
.http2_keep_alive_timeout(std::time::Duration::from_secs(10))
.build() {
@ -285,7 +285,7 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
};
if let Some(pexels_api_key) = config.pexels_api_key.clone() {
let pexels_client = Arc::new(Pexels::new(pexels_api_key));
let pexels_client = Arc::new(PexelsClient::new(pexels_api_key));
let pexels_query = config
.pexels_query
.clone()
@ -326,18 +326,15 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
}
drop(file_lines);
match tokio::time::timeout(
std::time::Duration::from_secs(30),
pexels_client
.search_photos(
SearchBuilder::new()
.query(pexels_query.as_str())
.page(1)
.per_page(11)
.size(pexels_api::Size::Medium)
.orientation(pexels_api::Orientation::Landscape),
)
).await?
match pexels_client
.search_photos(
pexels_query.as_str(),
&SearchParams::new()
.page(1)
.per_page(11)
.size(pexels_api::Size::Medium)
.orientation(pexels_api::Orientation::Landscape)
).await
{
Ok(photos) => {
if photos.total_results > 0 {
@ -399,7 +396,7 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
drop(pixels);
data.set_wallpaper_author(photo.photographer.into());
data.set_wallpaper_alt(photo.alt.into());
data.set_wallpaper_alt(photo.alt.unwrap_or("".into()).into());
data.set_wallpaper_url(photo.url.into());
display.invoke_switch_background();
@ -424,7 +421,7 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
drop(pixels);
data.set_wallpaper_author(photo.photographer.into());
data.set_wallpaper_alt(photo.alt.into());
data.set_wallpaper_alt(photo.alt.unwrap_or("".into()).into());
data.set_wallpaper_url(photo.url.into());
display.invoke_switch_background();
@ -449,7 +446,11 @@ pub fn register_wallpaper_callback(data: &GreeterData, display_weak: Weak<Greete
== Some(std::ffi::OsStr::new("png"))
}
Err(_) => false,
});
}).collect::<Vec<_>>().await;
photos.shuffle(&mut rand::rng());
let mut photos = tokio_stream::iter(photos);
while let Some(photo) = photos.next().await {
match photo {
@ -552,6 +553,13 @@ pub fn register_clean_inactive_wallpaper_callback(data: &GreeterData, display_we
}
})
}
pub fn register_get_default_font_size(data: &GreeterData, display_weak: Weak<GreeterDisplay>) {
data.on_get_default_font_size(move || {
let display = display_weak.unwrap();
let size = display.window().size();
((size.width as f32).min(size.height as f32)) * 0.01
});
}
pub fn register_callbacks(
display: &GreeterDisplay,
@ -568,4 +576,5 @@ pub fn register_callbacks(
register_lock_state_callback(data, data_weak.clone());
register_wallpaper_callback(data, display_weak.clone(), data_weak.clone(), cache_dir, config);
register_clean_inactive_wallpaper_callback(data, display_weak.clone(), data_weak.clone());
register_get_default_font_size(data, display_weak.clone());
}

View File

@ -5,6 +5,8 @@ export global Data {
in-out property <int> error_count;
pure callback get-default-font-size() -> length;
callback login(username: string, password: string);
callback loginctl(command: string);
callback check-lock-states();

View File

@ -1,4 +1,4 @@
import { ScrollView, Button } from "std-widgets.slint";
import { ScrollView, Button, TabWidget } from "std-widgets.slint";
import { Data, LoginOptionTileData } from "data.slint";
import { LoginOptionTile } from "envtile.slint";
@ -9,7 +9,19 @@ import { IconButton } from "iconbutton.slint";
export { Data as GreeterData } from "data.slint";
export component GreeterDisplay inherits Window {
default-font-size: root.width < root.height ? root.width * 0.01 : root.height * 0.01;
changed width => {
self.default-font-size = Data.get-default-font-size();
login_manager_underlay.width = max(self.width * 0.33, 640px);
login_manager_underlay.height = self.height;
}
changed height => {
self.default-font-size = Data.get-default-font-size();
login_manager_underlay.width = max(self.width * 0.33, 640px);
login_manager_underlay.height = self.height;
}
default-font-size: Data.get-default-font-size();
in-out property <int> selected_index <=> Data.selected_index;
@ -39,6 +51,8 @@ export component GreeterDisplay inherits Window {
}
full-screen: true;
preferred-width: 1920px;
preferred-height: 1080px;
min-width: 640px;
min-height: 480px;
@ -62,9 +76,6 @@ export component GreeterDisplay inherits Window {
source: Data.wallpaper-image;
image-fit: ImageFit.cover;
width: parent.width;
height: parent.height;
opacity: background-toggle && self.source.width > 0 ? 1.0 : 0.0;
background_timer := Timer {
interval: Data.wallpaper-cooldown * 1s;
@ -95,9 +106,6 @@ export component GreeterDisplay inherits Window {
source: Data.wallpaper-image-1;
image-fit: ImageFit.cover;
width: parent.width;
height: parent.height;
opacity: !background-toggle && self.source.width > 0 ? 1.0 : 0.0;
}
@ -112,7 +120,7 @@ export component GreeterDisplay inherits Window {
x: 1rem;
y: root.height - 7.5rem;
height: 6.5rem;
width: parent.width * 0.33;
width: 33%;
private property <bool> show_extended;
VerticalLayout {
@ -174,8 +182,6 @@ export component GreeterDisplay inherits Window {
}
TouchArea {
height: parent.height;
width: parent.width;
clicked => {
show_extended = !show_extended
}
@ -185,19 +191,21 @@ export component GreeterDisplay inherits Window {
login_manager_underlay := Rectangle {
background: rgba(0, 0, 0, 0.5);
drop-shadow-blur: 4rem;
height: parent.height;
height: 0px;
width: 0px;
animate width {
duration: 500ms;
easing: ease-in-sine;
}
z: -1;
width: max(parent.width * 0.33, 640px);
VerticalLayout {
height: parent.height;
width: parent.width;
clock := VerticalLayout {
alignment: center;
height: parent.height * 0.15;
height: 15%;
HorizontalLayout {
width: parent.width;
alignment: center;
Rectangle {
y: 10rem;
@ -243,8 +251,7 @@ export component GreeterDisplay inherits Window {
}
login_model := VerticalLayout {
alignment: center;
height: parent.height * 0.70;
width: parent.width;
height: 70%;
spacing: 1rem;
@ -262,8 +269,7 @@ export component GreeterDisplay inherits Window {
}
environment_selector := FocusScope {
height: max(parent.width * 0.2, parent.height * 0.2);
width: parent.width;
height: 25%;
key-pressed(event) => {
if (event.text == Key.LeftArrow || event.text == "a" || event.text == "A") {
if (Data.selected_index == 0) {
@ -284,22 +290,17 @@ export component GreeterDisplay inherits Window {
}
scroll_view := ScrollView {
height: parent.height;
width: min(((self.height + 1rem) * tiles.length) - 1rem, parent.width);
animate viewport-x { duration: 250ms; }
viewport-width: ((self.height + 1rem) * tiles.length) - 1rem;
// viewport-x: -(Data.selected_index * self.height) + (self.height / 2);
viewport-x: (self.viewport-width - self.height) / 2 - (Data.selected_index * (self.height));
//x: self.viewport-width < self.width ? ((self.width - self.viewport-width) / 2) : 0;
scroll_layout := HorizontalLayout {
height: parent.height;
for tile[i] in tiles: LoginOptionTile {
width: parent.height;
height: parent.height;
icon: tile.image;
label: tile.name;
index: i;
@ -313,13 +314,12 @@ export component GreeterDisplay inherits Window {
}
// Username field
HorizontalLayout {
width: parent.width;
height: 2.5rem;
alignment: center;
username_box := LineEdit {
font-size: 2rem;
font-family: "monospace";
width: parent.width * 0.45;
width: 45%;
placeholder-text: "Username";
text: default_username;
border-color: rgba(185, 15, 220, 0.85);
@ -338,13 +338,12 @@ export component GreeterDisplay inherits Window {
}
// Password field
HorizontalLayout {
width: parent.width;
height: 2.5rem;
alignment: center;
password_box := LineEdit {
font-size: 2rem;
font-family: "monospace";
width: parent.width * 0.45;
width: username_box.width;
placeholder-text: "Password";
input-type: password;
border-color: rgba(185, 15, 220, 0.85);
@ -362,11 +361,10 @@ export component GreeterDisplay inherits Window {
}
// Submit button
HorizontalLayout {
width: parent.width;
height: 2.5rem;
alignment: center;
IconButton {
width: parent.width * 0.45; //min(parent.width * 0.85, 32rem);
width: username_box.width;
icon: @image-url("icons/right_arrow.svg");
icon-width: 4rem;
icon-height: self.icon-width/3;
@ -380,8 +378,7 @@ export component GreeterDisplay inherits Window {
}
}
power_model := VerticalLayout {
height: parent.height * 0.15;
width: parent.width;
height: 15%;
confirm_prompt := Text {
horizontal-alignment: center;
@ -401,7 +398,6 @@ export component GreeterDisplay inherits Window {
}
HorizontalLayout {
width: parent.width;
alignment: center;
Rectangle {
@ -416,7 +412,6 @@ export component GreeterDisplay inherits Window {
private property <string> lastaction;
padding-top: 0.4rem;
width: parent.width;
alignment: center;
spacing: 0.5rem;
@ -477,8 +472,8 @@ export component GreeterDisplay inherits Window {
error_popup := Rectangle {
background: rgba(220, 50, 50, 0.85);
width: min(parent.width * 0.5, 64rem);
height: max(parent.height * 0.125, 6rem);
width: 25%;
height: 12.5%;
y: (parent.height * 0.025);
opacity: 0.0;
@ -489,8 +484,8 @@ export component GreeterDisplay inherits Window {
Text {
color: rgba(240, 240, 240, 1);
width: parent.width * 0.85;
height: parent.height * 0.85;
width: 85%;
height: 85%;
vertical-alignment: center;
horizontal-alignment: center;