feat(ui-iced): implement settings screen with navigation and basic UI elements
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-12-26 21:21:58 +05:30
parent 584495453f
commit 2b2e8060e7
6 changed files with 182 additions and 21 deletions

View File

@@ -140,7 +140,7 @@ struct State {
screen: Screen,
settings: settings::SettingsState,
is_authenticated: bool,
video: Option<Arc<VideoHandle>>,
video: Option<Arc<VideoHandle<Message>>>,
}
impl State {
@@ -187,9 +187,8 @@ pub enum Message {
}
fn update(state: &mut State, message: Message) -> Task<Message> {
// if let Some(client) = state.jellyfin_client.clone() {
match message {
Message::Settings(msg) => settings::update(&mut state.settings, msg),
Message::Settings(msg) => settings::update(state, msg),
Message::OpenItem(id) => {
if let Some(client) = state.jellyfin_client.clone() {
use api::jellyfin::BaseItemKind::*;

View File

@@ -1,16 +1,24 @@
use crate::*;
use iced::Element;
// mod widget;
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 {
SettingsMessage::Open => {}
SettingsMessage::Close => {}
SettingsMessage::Open => {
tracing::trace!("Opening settings");
state.screen = Screen::Settings;
}
SettingsMessage::Close => {
tracing::trace!("Closing settings");
state.screen = Screen::Home;
}
SettingsMessage::Select(screen) => {
tracing::trace!("Switching settings screen to {:?}", screen);
state.settings.screen = screen;
}
}
Task::none()
@@ -70,13 +78,80 @@ pub struct ServerForm {
mod screens {
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> {
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> {
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> {
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()
}

View File

@@ -3,7 +3,7 @@ use super::*;
pub enum VideoMessage {
EndOfStream,
Open(url::Url),
Loaded(VideoHandle),
Loaded(VideoHandle<Message>),
Pause,
Play,
Seek(f64),
@@ -24,7 +24,9 @@ pub fn update(state: &mut State, message: VideoMessage) -> Task<Message> {
})
}
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)
}
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(
Video::new(video)
.width(Length::Fill)
.height(Length::Fill)
.content_fit(iced::ContentFit::Contain)
.on_end_of_stream(Message::Video(VideoMessage::EndOfStream)),
.content_fit(iced::ContentFit::Contain),
)
.style(|_| container::background(iced::Color::BLACK))
.width(Length::Fill)