feat(ui-iced): implement settings screen with navigation and basic UI elements
This commit is contained in:
84
Cargo.lock
generated
84
Cargo.lock
generated
@@ -688,6 +688,26 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740"
|
||||||
|
dependencies = [
|
||||||
|
"bincode_derive",
|
||||||
|
"serde",
|
||||||
|
"unty",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode_derive"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09"
|
||||||
|
dependencies = [
|
||||||
|
"virtue",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.71.1"
|
version = "0.71.1"
|
||||||
@@ -1038,6 +1058,18 @@ dependencies = [
|
|||||||
"wayland-client",
|
"wayland-client",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-hot-protocol"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6a718cb9648aec5f3088527d5e5fa4fb2304672c452d157e233f31e39258806"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode 2.0.1",
|
||||||
|
"log",
|
||||||
|
"subsecond",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cbc"
|
name = "cbc"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -3441,7 +3473,7 @@ name = "iced_beacon"
|
|||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/uttarayan21/iced?branch=0.14#5846d52983d7e2eecc478130ba6373f0c1f82c94"
|
source = "git+https://github.com/uttarayan21/iced?branch=0.14#5846d52983d7e2eecc478130ba6373f0c1f82c94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode 1.3.3",
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"log",
|
"log",
|
||||||
@@ -3485,6 +3517,7 @@ name = "iced_debug"
|
|||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/uttarayan21/iced?branch=0.14#5846d52983d7e2eecc478130ba6373f0c1f82c94"
|
source = "git+https://github.com/uttarayan21/iced?branch=0.14#5846d52983d7e2eecc478130ba6373f0c1f82c94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cargo-hot-protocol",
|
||||||
"iced_beacon",
|
"iced_beacon",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
@@ -4435,6 +4468,15 @@ version = "2.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memfd"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227"
|
||||||
|
dependencies = [
|
||||||
|
"rustix 1.1.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.9.9"
|
version = "0.9.9"
|
||||||
@@ -7148,6 +7190,34 @@ dependencies = [
|
|||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subsecond"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c09bc2c9ef0381b403ab8b58122961cb83266d16b1f55f9486d5857ba4a9ae26"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"libc",
|
||||||
|
"libloading",
|
||||||
|
"memfd",
|
||||||
|
"memmap2",
|
||||||
|
"serde",
|
||||||
|
"subsecond-types",
|
||||||
|
"thiserror 2.0.17",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subsecond-types"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d07aa455c66ddfdbb51507537402b961e027846468954ef8d974bce65dff9eb0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@@ -8036,6 +8106,12 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unty"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.7"
|
version = "2.5.7"
|
||||||
@@ -8183,6 +8259,12 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "virtue"
|
||||||
|
version = "0.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vswhom"
|
name = "vswhom"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ pub fn main() -> iced::Result {
|
|||||||
.with(tracing_subscriber::EnvFilter::from_default_env())
|
.with(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
.init();
|
.init();
|
||||||
iced::application(State::new, update, view)
|
iced::application(State::new, update, view)
|
||||||
.subscription(|state| match &state.video {
|
.subscription(|state| {
|
||||||
|
// Foo
|
||||||
|
match &state.video {
|
||||||
Some(video) => video.subscription_with(state, keyboard_event),
|
Some(video) => video.subscription_with(state, keyboard_event),
|
||||||
None => keyboard_event(state),
|
None => keyboard_event(state),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,15 @@ api = { version = "0.1.0", path = "../api" }
|
|||||||
blurhash = "0.2.3"
|
blurhash = "0.2.3"
|
||||||
bytes = "1.11.0"
|
bytes = "1.11.0"
|
||||||
gpui_util = "0.2.2"
|
gpui_util = "0.2.2"
|
||||||
iced = { workspace = true, default-features = true, features = [
|
iced = { workspace = true, features = [
|
||||||
"advanced",
|
"advanced",
|
||||||
"canvas",
|
"canvas",
|
||||||
"image",
|
"image",
|
||||||
"sipper",
|
"sipper",
|
||||||
"tokio",
|
"tokio",
|
||||||
"debug",
|
"debug",
|
||||||
] }
|
"hot",
|
||||||
|
], default-features = true }
|
||||||
|
|
||||||
|
|
||||||
iced-video = { workspace = true }
|
iced-video = { workspace = true }
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ struct State {
|
|||||||
screen: Screen,
|
screen: Screen,
|
||||||
settings: settings::SettingsState,
|
settings: settings::SettingsState,
|
||||||
is_authenticated: bool,
|
is_authenticated: bool,
|
||||||
video: Option<Arc<VideoHandle>>,
|
video: Option<Arc<VideoHandle<Message>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@@ -187,9 +187,8 @@ pub enum Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update(state: &mut State, message: Message) -> Task<Message> {
|
fn update(state: &mut State, message: Message) -> Task<Message> {
|
||||||
// if let Some(client) = state.jellyfin_client.clone() {
|
|
||||||
match message {
|
match message {
|
||||||
Message::Settings(msg) => settings::update(&mut state.settings, msg),
|
Message::Settings(msg) => settings::update(state, msg),
|
||||||
Message::OpenItem(id) => {
|
Message::OpenItem(id) => {
|
||||||
if let Some(client) = state.jellyfin_client.clone() {
|
if let Some(client) = state.jellyfin_client.clone() {
|
||||||
use api::jellyfin::BaseItemKind::*;
|
use api::jellyfin::BaseItemKind::*;
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use iced::Element;
|
use iced::Element;
|
||||||
|
// mod widget;
|
||||||
|
|
||||||
pub fn settings(state: &State) -> Element<'_, Message> {
|
pub fn settings(state: &State) -> Element<'_, Message> {
|
||||||
empty()
|
screens::settings(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(_state: &mut SettingsState, message: SettingsMessage) -> Task<Message> {
|
pub fn update(state: &mut State, message: SettingsMessage) -> Task<Message> {
|
||||||
match message {
|
match message {
|
||||||
SettingsMessage::Open => {}
|
SettingsMessage::Open => {
|
||||||
SettingsMessage::Close => {}
|
tracing::trace!("Opening settings");
|
||||||
|
state.screen = Screen::Settings;
|
||||||
|
}
|
||||||
|
SettingsMessage::Close => {
|
||||||
|
tracing::trace!("Closing settings");
|
||||||
|
state.screen = Screen::Home;
|
||||||
|
}
|
||||||
SettingsMessage::Select(screen) => {
|
SettingsMessage::Select(screen) => {
|
||||||
tracing::trace!("Switching settings screen to {:?}", screen);
|
tracing::trace!("Switching settings screen to {:?}", screen);
|
||||||
|
state.settings.screen = screen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
@@ -70,13 +78,80 @@ pub struct ServerForm {
|
|||||||
|
|
||||||
mod screens {
|
mod screens {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
pub fn settings(state: &State) -> Element<'_, Message> {
|
||||||
|
row([settings_list(state), settings_screen(state)]).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings_screen(state: &State) -> Element<'_, Message> {
|
||||||
|
container(match state.settings.screen {
|
||||||
|
SettingsScreen::Main => main(state),
|
||||||
|
SettingsScreen::Servers => server(state),
|
||||||
|
SettingsScreen::Users => user(state),
|
||||||
|
})
|
||||||
|
.width(Length::FillPortion(10))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings_list(state: &State) -> Element<'_, Message> {
|
||||||
|
scrollable(
|
||||||
|
column(
|
||||||
|
[
|
||||||
|
button(center_text("Main")).on_press(Message::Settings(
|
||||||
|
SettingsMessage::Select(SettingsScreen::Main),
|
||||||
|
)),
|
||||||
|
button(center_text("Servers")).on_press(Message::Settings(
|
||||||
|
SettingsMessage::Select(SettingsScreen::Servers),
|
||||||
|
)),
|
||||||
|
button(center_text("Users")).on_press(Message::Settings(
|
||||||
|
SettingsMessage::Select(SettingsScreen::Users),
|
||||||
|
)),
|
||||||
|
]
|
||||||
|
.map(|p| p.clip(true).width(Length::Fill).into()),
|
||||||
|
)
|
||||||
|
.width(Length::FillPortion(2))
|
||||||
|
// .max_width(Length::FillPortion(3))
|
||||||
|
.spacing(10)
|
||||||
|
.padding(10),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main(state: &State) -> Element<'_, Message> {
|
pub fn main(state: &State) -> Element<'_, Message> {
|
||||||
empty()
|
// placeholder for now
|
||||||
|
container(
|
||||||
|
Column::new()
|
||||||
|
.push(text("Main Settings"))
|
||||||
|
.push(toggler(true).label("Foobar"))
|
||||||
|
.spacing(20)
|
||||||
|
.padding(20),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
pub fn server(state: &State) -> Element<'_, Message> {
|
pub fn server(state: &State) -> Element<'_, Message> {
|
||||||
empty()
|
container(
|
||||||
|
Column::new()
|
||||||
|
.push(text("Server Settings"))
|
||||||
|
.push(toggler(false).label("Enable Server"))
|
||||||
|
.spacing(20)
|
||||||
|
.padding(20),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
pub fn user(state: &State) -> Element<'_, Message> {
|
pub fn user(state: &State) -> Element<'_, Message> {
|
||||||
empty()
|
container(
|
||||||
|
Column::new()
|
||||||
|
.push(text("User Settings"))
|
||||||
|
.push(toggler(true).label("Enable User"))
|
||||||
|
.spacing(20)
|
||||||
|
.padding(20),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn center_text(content: &str) -> Element<'_, Message> {
|
||||||
|
text(content)
|
||||||
|
.align_x(Alignment::Center)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use super::*;
|
|||||||
pub enum VideoMessage {
|
pub enum VideoMessage {
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
Open(url::Url),
|
Open(url::Url),
|
||||||
Loaded(VideoHandle),
|
Loaded(VideoHandle<Message>),
|
||||||
Pause,
|
Pause,
|
||||||
Play,
|
Play,
|
||||||
Seek(f64),
|
Seek(f64),
|
||||||
@@ -24,7 +24,9 @@ pub fn update(state: &mut State, message: VideoMessage) -> Task<Message> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
VideoMessage::Loaded(video) => {
|
VideoMessage::Loaded(video) => {
|
||||||
state.video = Some(Arc::new(video));
|
state.video = Some(Arc::new(
|
||||||
|
video.on_end_of_stream(Message::Video(VideoMessage::EndOfStream)),
|
||||||
|
));
|
||||||
Task::done(VideoMessage::Play).map(Message::Video)
|
Task::done(VideoMessage::Play).map(Message::Video)
|
||||||
}
|
}
|
||||||
VideoMessage::Pause => {
|
VideoMessage::Pause => {
|
||||||
@@ -62,13 +64,12 @@ pub fn update(state: &mut State, message: VideoMessage) -> Task<Message> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn player(video: &VideoHandle) -> Element<'_, Message> {
|
pub fn player(video: &VideoHandle<Message>) -> Element<'_, Message> {
|
||||||
container(
|
container(
|
||||||
Video::new(video)
|
Video::new(video)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.content_fit(iced::ContentFit::Contain)
|
.content_fit(iced::ContentFit::Contain),
|
||||||
.on_end_of_stream(Message::Video(VideoMessage::EndOfStream)),
|
|
||||||
)
|
)
|
||||||
.style(|_| container::background(iced::Color::BLACK))
|
.style(|_| container::background(iced::Color::BLACK))
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|||||||
Reference in New Issue
Block a user