feat: Added stuff
Some checks failed
build / checks-matrix (push) Has been cancelled
build / codecov (push) Has been cancelled
docs / docs (push) Has been cancelled
build / checks-build (push) Has been cancelled

This commit is contained in:
uttarayan21
2025-11-19 17:01:14 +05:30
parent 29674df85e
commit f41625e0ed
10 changed files with 271 additions and 151 deletions

View File

@@ -6,12 +6,10 @@ edition = "2024"
[dependencies]
api = { version = "0.1.0", path = "../api" }
blurhash = "0.2.3"
bytes = "1.11.0"
gpui_util = "0.2.2"
iced = { git = "https://github.com/iced-rs/iced", features = [
"advanced",
"canvas",
"image",
"tokio",
] }
iced = { git = "https://github.com/iced-rs/iced", features = ["advanced", "canvas", "image", "sipper", "tokio"] }
reqwest = "0.12.24"
tap = "1.0.1"
tracing = "0.1.41"
uuid = "1.18.1"

View File

@@ -13,6 +13,17 @@ pub struct BlurHash {
punch: f32,
}
impl core::fmt::Debug for BlurHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("BlurHash")
.field("hash", &self.hash)
.field("width", &self.width)
.field("height", &self.height)
.field("punch", &self.punch)
.finish()
}
}
impl BlurHash {
pub fn recompute(&mut self, width: u32, height: u32, punch: f32) {
let pixels = blurhash::decode(&self.hash, width, height, punch)

View File

@@ -4,14 +4,14 @@ use shared_string::SharedString;
mod blur_hash;
use blur_hash::BlurHash;
// mod preview;
// use preview::Preview;
use iced::{Alignment, Element, Length, Task, widget::*};
use std::collections::{BTreeMap, BTreeSet};
#[derive(Debug, Clone)]
pub struct Loading {
to: Screen,
from: Screen,
}
pub struct Loading {}
#[derive(Default, Debug, Clone)]
pub struct ItemCache {
@@ -89,8 +89,10 @@ pub struct Item {
pub enum Screen {
#[default]
Home,
Item(Option<uuid::Uuid>),
Search(String),
Settings,
Profile,
User,
}
#[derive(Debug, Clone)]
struct State {
@@ -100,6 +102,7 @@ struct State {
jellyfin_client: api::JellyfinClient,
messages: Vec<String>,
history: Vec<Option<uuid::Uuid>>,
query: Option<String>,
}
impl State {
@@ -111,6 +114,7 @@ impl State {
jellyfin_client,
messages: Vec::new(),
history: Vec::new(),
query: None,
}
}
}
@@ -119,6 +123,8 @@ impl State {
pub enum Message {
OpenSettings,
Refresh,
Search,
SearchQueryChanged(String),
OpenItem(Option<uuid::Uuid>),
LoadedItem(Option<uuid::Uuid>, Vec<Item>),
Error(String),
@@ -191,6 +197,23 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
state.current = None;
Task::done(Message::Refresh)
}
Message::SearchQueryChanged(query) => {
state.query = Some(query);
// Handle search query change
Task::none()
}
Message::Search => {
// Handle search action
let client = state.jellyfin_client.clone();
let query = state.query.clone().unwrap_or_default();
Task::perform(async move { client.search(query).await }, |r| match r {
Err(e) => Message::Error(format!("Search failed: {}", e)),
Ok(items) => {
let items = items.into_iter().map(Item::from).collect();
Message::LoadedItem(None, items)
}
})
}
}
}
@@ -231,20 +254,15 @@ fn header(state: &State) -> Element<'_, Message> {
.align_y(Alignment::Center)
.style(container::rounded_box)
.into(),
container(
row([
button("Settings").on_press(Message::OpenSettings).into(),
button("Refresh").on_press(Message::Refresh).into(),
])
.spacing(10),
)
.padding(10)
.width(Length::Fill)
.height(Length::Fill)
.align_x(Alignment::End)
.align_y(Alignment::Center)
.style(container::rounded_box)
.into(),
search(state),
container(row([button("Refresh").on_press(Message::Refresh).into()]).spacing(10))
.padding(10)
.width(Length::Fill)
.height(Length::Fill)
.align_x(Alignment::End)
.align_y(Alignment::Center)
.style(container::rounded_box)
.into(),
])
.align_y(Alignment::Center)
.width(Length::Fill)
@@ -252,6 +270,22 @@ fn header(state: &State) -> Element<'_, Message> {
.into()
}
fn search(state: &State) -> Element<'_, Message> {
container(
TextInput::new("Search...", state.query.as_deref().unwrap_or_default())
.padding(10)
.size(16)
.width(Length::Fill)
.on_input(Message::SearchQueryChanged)
.on_submit(Message::Search),
)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(container::rounded_box)
.into()
}
fn footer(state: &State) -> Element<'_, Message> {
container(
column(

105
ui-iced/src/preview.rs Normal file
View File

@@ -0,0 +1,105 @@
use iced::{Animation, advanced::image::Handle, widget::image};
use reqwest::Method;
use std::sync::Arc;
use crate::blur_hash::BlurHash;
#[derive(Clone)]
pub struct ImageDownloader {
client: reqwest::Client,
request_modifier:
Option<Arc<dyn Fn(reqwest::RequestBuilder) -> reqwest::RequestBuilder + Send + Sync>>,
}
impl ImageDownloader {
pub fn new() -> Self {
Self {
client: reqwest::Client::new(),
request_modifier: None,
}
}
pub fn with_modifier<F>(mut self, f: F) -> Self
where
F: Fn(reqwest::RequestBuilder) -> reqwest::RequestBuilder + Send + Sync + 'static,
{
self.request_modifier = Some(Arc::new(f));
self
}
pub async fn download(&self, url: &str) -> reqwest::Result<bytes::Bytes> {
use ::tap::*;
let response = self
.client
.request(Method::GET, url)
.pipe(|builder| {
if let Some(ref modifier) = self.request_modifier {
modifier(builder)
} else {
builder
}
})
.send()
.await?;
let bytes = response.bytes().await?;
Ok(bytes)
}
}
#[derive(Clone, Debug)]
pub enum Preview {
Thumbnail {
thumbnail: Image,
blur_hash: BlurHash,
},
BlurHash {
blur_hash: BlurHash,
},
}
// impl Preview {
// pub fn thumbnail(image: Image, blur_hash: BlurHash) -> Self {
// Preview::Thumbnail {
// thumbnail: image,
// blur_hash,
// }
// }
//
// pub fn blur_hash(blur_hash: BlurHash) -> Self {
// Preview::BlurHash { blur_hash }
// }
//
// pub fn upgrade(
// self,
// fut: impl core::future::Future<Output = bytes::Bytes> + 'static + Send,
// ) -> iced::Task<PreviewMessage> {
// // let sip = iced::task::sipper(async move |mut sender| {
// // let bytes = fut.await;
// // let handle = Handle::from_bytes(bytes.clone());
// // let allocation = image::allocate(handle);
// // let image = Image {
// // bytes,
// // handle,
// // allocation,
// // fade_in: Animation::new(false),
// // };
// // let _ = sender.send(image).await;
// // });
// // iced::Task::sip(sip, ||)
// Task::
// }
// }
//
// enum PreviewMessage {
// BlurHashLoaded(BlurHash),
// ThumbnailLoaded(Image),
// ThumbnailAllocated(image::Allocation),
// }
//
#[derive(Clone, Debug)]
pub struct Image {
bytes: bytes::Bytes,
handle: Handle,
allocation: image::Allocation,
fade_in: Animation<bool>,
}