Update Pexels and fix binding loops
This commit is contained in:
parent
4c7bd2694f
commit
48c493c4f5
@ -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" }
|
||||
|
||||
@ -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());
|
||||
}
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user