feat(ui): comment out gpui ui code and improve iced ui logic

This commit is contained in:
uttarayan21
2025-12-09 23:46:00 +05:30
parent 73fcf9bad1
commit d75a2fb7e4
2 changed files with 320 additions and 310 deletions

View File

@@ -1,262 +1,262 @@
use ::tap::*;
use std::{collections::BTreeMap, sync::Arc};
use gpui::{
App, Application, Bounds, ClickEvent, Context, ImageId, ImageSource, RenderImage, Resource,
SharedString, Window, WindowBounds, WindowOptions, actions, div, prelude::*, px, rgb, size,
};
#[derive(Clone, Debug)]
pub struct AppState {
pub title: SharedString,
pub items: BTreeMap<SharedString, Item>,
pub item_ids: BTreeMap<usize, SharedString>,
pub current_item: Option<SharedString>,
pub errors: Vec<String>,
pub jellyfin_client: api::JellyfinClient,
}
#[derive(Clone, Debug)]
pub struct Item {
pub id: SharedString,
pub name: SharedString,
pub item_type: SharedString,
pub media_type: SharedString,
}
impl Render for AppState {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.flex_col()
.size_full()
.justify_center()
.text_color(rgb(0xffffff))
.child(Self::header())
.child(Self::body(self, window, cx))
.child(Self::footer())
}
}
actions!(jello_actions, [OpenItem, OnLoadItem, MouseDownEvent]);
impl AppState {
fn new(title: impl AsRef<str>, jellyfin_client: api::JellyfinClient) -> Self {
AppState {
title: SharedString::new(title.as_ref()),
items: BTreeMap::new(),
item_ids: BTreeMap::new(),
current_item: None,
errors: Vec::new(),
jellyfin_client,
}
}
// fn on_mouse_down(
// &mut self,
// event: &MouseDownEvent,
// window: &mut Window,
// cx: &mut Context<Self>,
// ) {
// // Handle mouse down event
// }
fn load_item(id: usize) -> impl Fn(&mut Self, &ClickEvent, &mut Window, &mut Context<Self>) {
move |state: &mut Self, event: &ClickEvent, window: &mut Window, cx: &mut Context<Self>| {
let item_id = id;
cx.spawn(async move |entity, app| {
tracing::info!("Loading item with id: {}", item_id);
});
}
}
fn hover_item(id: usize) -> impl Fn(&mut Self, &bool, &mut Window, &mut Context<Self>) {
move |state: &mut Self, item: &bool, window: &mut Window, cx: &mut Context<Self>| {
dbg!("Hovering over item: {:?}", id);
}
}
fn header() -> impl IntoElement {
div()
.flex()
.flex_row()
.w_full()
.justify_end()
.h_20()
.border_10()
.bg(rgb(0x333333))
.child(Self::button("Refresh"))
}
fn footer() -> impl IntoElement {
div().flex().flex_row().w_full().h_20().bg(rgb(0x333333))
}
fn body(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
div()
.flex()
.flex_row()
.size_full()
.child(Self::content(self, window, cx))
.child(Self::sidebar(self, window, cx))
}
fn button(label: &str) -> impl IntoElement {
div()
.flex()
.justify_center()
.items_center()
.bg(rgb(0xff00ff))
.text_color(rgb(0xffffff))
.border_5()
.rounded_lg()
.child(label.to_string())
}
fn content(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
div()
.debug_below()
.w_3_4()
// .flex()
// .flex_wrap()
.bg(rgb(0x111111))
.justify_start()
.items_start()
.overflow_hidden()
.child(
div()
.size_full()
.flex()
.flex_wrap()
.justify_start()
.items_start()
.content_start()
.gap_y_10()
.gap_x_10()
.border_t_10()
.p_5()
.child(Self::card(cx, 1))
.child(Self::card(cx, 2))
.child(Self::card(cx, 3))
.child(Self::card(cx, 4))
.child(Self::card(cx, 5))
.child(Self::card(cx, 6))
.child(Self::card(cx, 7))
.child(Self::card(cx, 8))
.child(Self::card(cx, 9)),
)
}
fn sidebar(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
div()
.flex()
.flex_col()
.w_1_4()
.min_w_1_6()
.bg(rgb(0x222222))
.child(div().size_full().bg(gpui::yellow()))
}
fn card(cx: &mut Context<AppState>, number: usize) -> impl IntoElement {
div()
.id(number)
.on_click(cx.listener(Self::load_item(number)))
.on_hover(cx.listener(Self::hover_item(number)))
.flex()
.flex_col()
.w_48()
.h_64()
.p_10()
.bg(rgb(0xff00ff))
.rounded_lg()
}
}
pub fn ui(jellyfin_client: api::JellyfinClient) {
Application::new().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| cx.new(|_| AppState::new("Jello Media Browser", jellyfin_client)),
)
.expect("Failed to open window");
})
}
#[derive(Clone, Debug)]
pub struct Card {
pub id: usize,
pub title: SharedString,
pub description: SharedString,
pub image: SharedString,
pub image_blurhash: BlurHash,
pub media_type: SharedString,
pub loading: bool,
}
impl Render for Card {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.id(self.id)
.flex()
.flex_col()
.w_48()
.h_64()
.p_10()
.bg(rgb(0xff00ff))
.rounded_lg()
.pipe(|card| {
if self.loading {
card.child(self.image_blurhash.clone())
} else {
card.child(gpui::img(self.image.clone()))
}
})
}
}
#[derive(Clone, Debug)]
pub struct BlurHash {
pub id: ImageId,
pub data: Arc<RenderImage>,
}
impl BlurHash {
pub fn new(
data: impl AsRef<str>,
width: u32,
height: u32,
punch: f32,
) -> Result<Self, error_stack::Report<crate::Error>> {
use error_stack::ResultExt;
let decoded =
blurhash::decode(data.as_ref(), width, height, punch).change_context(crate::Error)?;
let buffer = image::RgbaImage::from_raw(width, height, decoded)
.ok_or(crate::Error)
.attach("Failed to convert")?;
let frame = image::Frame::new(buffer);
let render_image = RenderImage::new([frame]);
Ok(Self {
id: render_image.id,
data: Arc::from(render_image),
})
}
}
impl Render for BlurHash {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
gpui::img(ImageSource::Render(self.data.clone()))
}
}
impl IntoElement for BlurHash {
type Element = gpui::Img;
fn into_element(self) -> Self::Element {
gpui::img(ImageSource::Render(self.data.clone()))
}
}
// use ::tap::*;
//
// use std::{collections::BTreeMap, sync::Arc};
//
// use gpui::{
// App, Application, Bounds, ClickEvent, Context, ImageId, ImageSource, RenderImage, Resource,
// SharedString, Window, WindowBounds, WindowOptions, actions, div, prelude::*, px, rgb, size,
// };
//
// #[derive(Clone, Debug)]
// pub struct AppState {
// pub title: SharedString,
// pub items: BTreeMap<SharedString, Item>,
// pub item_ids: BTreeMap<usize, SharedString>,
// pub current_item: Option<SharedString>,
// pub errors: Vec<String>,
// pub jellyfin_client: api::JellyfinClient,
// }
//
// #[derive(Clone, Debug)]
// pub struct Item {
// pub id: SharedString,
// pub name: SharedString,
// pub item_type: SharedString,
// pub media_type: SharedString,
// }
//
// impl Render for AppState {
// fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
// div()
// .flex()
// .flex_col()
// .size_full()
// .justify_center()
// .text_color(rgb(0xffffff))
// .child(Self::header())
// .child(Self::body(self, window, cx))
// .child(Self::footer())
// }
// }
//
// actions!(jello_actions, [OpenItem, OnLoadItem, MouseDownEvent]);
//
// impl AppState {
// fn new(title: impl AsRef<str>, jellyfin_client: api::JellyfinClient) -> Self {
// AppState {
// title: SharedString::new(title.as_ref()),
// items: BTreeMap::new(),
// item_ids: BTreeMap::new(),
// current_item: None,
// errors: Vec::new(),
// jellyfin_client,
// }
// }
//
// // fn on_mouse_down(
// // &mut self,
// // event: &MouseDownEvent,
// // window: &mut Window,
// // cx: &mut Context<Self>,
// // ) {
// // // Handle mouse down event
// // }
//
// fn load_item(id: usize) -> impl Fn(&mut Self, &ClickEvent, &mut Window, &mut Context<Self>) {
// move |state: &mut Self, event: &ClickEvent, window: &mut Window, cx: &mut Context<Self>| {
// let item_id = id;
// cx.spawn(async move |entity, app| {
// tracing::info!("Loading item with id: {}", item_id);
// });
// }
// }
//
// fn hover_item(id: usize) -> impl Fn(&mut Self, &bool, &mut Window, &mut Context<Self>) {
// move |state: &mut Self, item: &bool, window: &mut Window, cx: &mut Context<Self>| {
// dbg!("Hovering over item: {:?}", id);
// }
// }
//
// fn header() -> impl IntoElement {
// div()
// .flex()
// .flex_row()
// .w_full()
// .justify_end()
// .h_20()
// .border_10()
// .bg(rgb(0x333333))
// .child(Self::button("Refresh"))
// }
//
// fn footer() -> impl IntoElement {
// div().flex().flex_row().w_full().h_20().bg(rgb(0x333333))
// }
//
// fn body(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
// div()
// .flex()
// .flex_row()
// .size_full()
// .child(Self::content(self, window, cx))
// .child(Self::sidebar(self, window, cx))
// }
//
// fn button(label: &str) -> impl IntoElement {
// div()
// .flex()
// .justify_center()
// .items_center()
// .bg(rgb(0xff00ff))
// .text_color(rgb(0xffffff))
// .border_5()
// .rounded_lg()
// .child(label.to_string())
// }
//
// fn content(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
// div()
// .debug_below()
// .w_3_4()
// // .flex()
// // .flex_wrap()
// .bg(rgb(0x111111))
// .justify_start()
// .items_start()
// .overflow_hidden()
// .child(
// div()
// .size_full()
// .flex()
// .flex_wrap()
// .justify_start()
// .items_start()
// .content_start()
// .gap_y_10()
// .gap_x_10()
// .border_t_10()
// .p_5()
// .child(Self::card(cx, 1))
// .child(Self::card(cx, 2))
// .child(Self::card(cx, 3))
// .child(Self::card(cx, 4))
// .child(Self::card(cx, 5))
// .child(Self::card(cx, 6))
// .child(Self::card(cx, 7))
// .child(Self::card(cx, 8))
// .child(Self::card(cx, 9)),
// )
// }
//
// fn sidebar(&mut self, window: &mut Window, cx: &mut Context<AppState>) -> impl IntoElement {
// div()
// .flex()
// .flex_col()
// .w_1_4()
// .min_w_1_6()
// .bg(rgb(0x222222))
// .child(div().size_full().bg(gpui::yellow()))
// }
//
// fn card(cx: &mut Context<AppState>, number: usize) -> impl IntoElement {
// div()
// .id(number)
// .on_click(cx.listener(Self::load_item(number)))
// .on_hover(cx.listener(Self::hover_item(number)))
// .flex()
// .flex_col()
// .w_48()
// .h_64()
// .p_10()
// .bg(rgb(0xff00ff))
// .rounded_lg()
// }
// }
//
// pub fn ui(jellyfin_client: api::JellyfinClient) {
// Application::new().run(|cx: &mut App| {
// let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
// cx.open_window(
// WindowOptions {
// window_bounds: Some(WindowBounds::Windowed(bounds)),
// ..Default::default()
// },
// |_, cx| cx.new(|_| AppState::new("Jello Media Browser", jellyfin_client)),
// )
// .expect("Failed to open window");
// })
// }
//
// #[derive(Clone, Debug)]
// pub struct Card {
// pub id: usize,
// pub title: SharedString,
// pub description: SharedString,
// pub image: SharedString,
// pub image_blurhash: BlurHash,
// pub media_type: SharedString,
// pub loading: bool,
// }
//
// impl Render for Card {
// fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
// div()
// .id(self.id)
// .flex()
// .flex_col()
// .w_48()
// .h_64()
// .p_10()
// .bg(rgb(0xff00ff))
// .rounded_lg()
// .pipe(|card| {
// if self.loading {
// card.child(self.image_blurhash.clone())
// } else {
// card.child(gpui::img(self.image.clone()))
// }
// })
// }
// }
//
// #[derive(Clone, Debug)]
// pub struct BlurHash {
// pub id: ImageId,
// pub data: Arc<RenderImage>,
// }
//
// impl BlurHash {
// pub fn new(
// data: impl AsRef<str>,
// width: u32,
// height: u32,
// punch: f32,
// ) -> Result<Self, error_stack::Report<crate::Error>> {
// use error_stack::ResultExt;
// let decoded =
// blurhash::decode(data.as_ref(), width, height, punch).change_context(crate::Error)?;
// let buffer = image::RgbaImage::from_raw(width, height, decoded)
// .ok_or(crate::Error)
// .attach("Failed to convert")?;
// let frame = image::Frame::new(buffer);
// let render_image = RenderImage::new([frame]);
// Ok(Self {
// id: render_image.id,
// data: Arc::from(render_image),
// })
// }
// }
//
// impl Render for BlurHash {
// fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
// gpui::img(ImageSource::Render(self.data.clone()))
// }
// }
//
// impl IntoElement for BlurHash {
// type Element = gpui::Img;
//
// fn into_element(self) -> Self::Element {
// gpui::img(ImageSource::Render(self.data.clone()))
// }
// }