feat: Add Settings page and refactor view navigation
This commit is contained in:
+69
-7
@@ -14,6 +14,13 @@ use tokio::sync::Mutex;
|
|||||||
|
|
||||||
static UI_RX: OnceLock<Mutex<Option<tokio::sync::mpsc::Receiver<UiEvent>>>> = OnceLock::new();
|
static UI_RX: OnceLock<Mutex<Option<tokio::sync::mpsc::Receiver<UiEvent>>>> = OnceLock::new();
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Screen {
|
||||||
|
Home,
|
||||||
|
Room,
|
||||||
|
Settings,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum AppMessage {
|
pub enum AppMessage {
|
||||||
NicknameChanged(String),
|
NicknameChanged(String),
|
||||||
@@ -31,6 +38,8 @@ pub enum AppMessage {
|
|||||||
InputDeviceChanged(String),
|
InputDeviceChanged(String),
|
||||||
OutputDeviceChanged(String),
|
OutputDeviceChanged(String),
|
||||||
EventOccurred(Event),
|
EventOccurred(Event),
|
||||||
|
NavigateToSettings,
|
||||||
|
NavigateBack,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn core_subscription() -> impl iced::futures::Stream<Item = UiEvent> {
|
fn core_subscription() -> impl iced::futures::Stream<Item = UiEvent> {
|
||||||
@@ -65,6 +74,7 @@ pub struct AppState {
|
|||||||
peer_volumes: HashMap<EndpointId, f32>,
|
peer_volumes: HashMap<EndpointId, f32>,
|
||||||
audio_levels: HashMap<EndpointId, f32>,
|
audio_levels: HashMap<EndpointId, f32>,
|
||||||
controller: Arc<CoreController>,
|
controller: Arc<CoreController>,
|
||||||
|
current_screen: Screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppState {
|
impl Default for AppState {
|
||||||
@@ -91,6 +101,7 @@ impl Default for AppState {
|
|||||||
peer_volumes: HashMap::new(),
|
peer_volumes: HashMap::new(),
|
||||||
audio_levels: HashMap::new(),
|
audio_levels: HashMap::new(),
|
||||||
controller,
|
controller,
|
||||||
|
current_screen: Screen::Home,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,15 +172,15 @@ fn update(state: &mut AppState, message: AppMessage) -> Task<AppMessage> {
|
|||||||
UiEvent::RoomJoined { ticket, self_id } => {
|
UiEvent::RoomJoined { ticket, self_id } => {
|
||||||
state.ticket = ticket;
|
state.ticket = ticket;
|
||||||
state.self_id = self_id;
|
state.self_id = self_id;
|
||||||
state.status_message = "Connected to room".to_string();
|
state.status_message = "Connected".to_string();
|
||||||
state.peers.clear();
|
state.current_screen = Screen::Room;
|
||||||
state.audio_levels.clear();
|
|
||||||
}
|
}
|
||||||
UiEvent::RoomLeft => {
|
UiEvent::RoomLeft => {
|
||||||
state.ticket = "".to_string();
|
state.ticket = "".to_string();
|
||||||
state.peers.clear();
|
state.peers.clear();
|
||||||
state.audio_levels.clear();
|
state.audio_levels.clear();
|
||||||
state.status_message = "Ready to connect".to_string();
|
state.status_message = "Ready to connect".to_string();
|
||||||
|
state.current_screen = Screen::Home;
|
||||||
}
|
}
|
||||||
UiEvent::PeerJoined { id, state: peer_state } => {
|
UiEvent::PeerJoined { id, state: peer_state } => {
|
||||||
state.peers.insert(id, peer_state);
|
state.peers.insert(id, peer_state);
|
||||||
@@ -229,6 +240,16 @@ fn update(state: &mut AppState, message: AppMessage) -> Task<AppMessage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AppMessage::EventOccurred(_) => {}
|
AppMessage::EventOccurred(_) => {}
|
||||||
|
AppMessage::NavigateToSettings => {
|
||||||
|
state.current_screen = Screen::Settings;
|
||||||
|
}
|
||||||
|
AppMessage::NavigateBack => {
|
||||||
|
if state.ticket.is_empty() {
|
||||||
|
state.current_screen = Screen::Home;
|
||||||
|
} else {
|
||||||
|
state.current_screen = Screen::Room;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
@@ -303,7 +324,43 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if state.ticket.is_empty() {
|
let top_bar = row![
|
||||||
|
horizontal_space(),
|
||||||
|
button(text("⚙ Settings").size(14))
|
||||||
|
.on_press(AppMessage::NavigateToSettings)
|
||||||
|
.style(b_style(color_surface, color_blue, color_text, 6.0))
|
||||||
|
.padding(8)
|
||||||
|
].width(iced::Length::Fill).padding(10);
|
||||||
|
|
||||||
|
if state.current_screen == Screen::Settings {
|
||||||
|
let content = column![
|
||||||
|
text("Settings").size(32).color(color_text),
|
||||||
|
vertical_space(20.0),
|
||||||
|
text("Future settings and controls will be added here.").size(16).color(color_subtext),
|
||||||
|
vertical_space(40.0),
|
||||||
|
button(
|
||||||
|
text("Back")
|
||||||
|
.size(16)
|
||||||
|
.align_x(iced::alignment::Horizontal::Center)
|
||||||
|
)
|
||||||
|
.on_press(AppMessage::NavigateBack)
|
||||||
|
.style(b_style(color_surface, color_blue, color_text, 8.0))
|
||||||
|
.padding(14)
|
||||||
|
.width(iced::Length::Fixed(150.0))
|
||||||
|
]
|
||||||
|
.align_x(iced::alignment::Horizontal::Center)
|
||||||
|
.spacing(10);
|
||||||
|
|
||||||
|
return container(content)
|
||||||
|
.width(iced::Length::Fill)
|
||||||
|
.height(iced::Length::Fill)
|
||||||
|
.center_x(iced::Length::Fill)
|
||||||
|
.center_y(iced::Length::Fill)
|
||||||
|
.style(c_style(color_crust, Color::TRANSPARENT, 0.0))
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.current_screen == Screen::Home {
|
||||||
// --- HOME SCREEN ---
|
// --- HOME SCREEN ---
|
||||||
let logo = text("PEERSPEAK")
|
let logo = text("PEERSPEAK")
|
||||||
.size(36)
|
.size(36)
|
||||||
@@ -384,11 +441,15 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
.padding(30)
|
.padding(30)
|
||||||
.width(420);
|
.width(420);
|
||||||
|
|
||||||
container(content)
|
container(
|
||||||
|
column![
|
||||||
|
top_bar,
|
||||||
|
vertical_space(40.0),
|
||||||
|
content
|
||||||
|
].align_x(iced::alignment::Horizontal::Center)
|
||||||
|
)
|
||||||
.width(iced::Length::Fill)
|
.width(iced::Length::Fill)
|
||||||
.height(iced::Length::Fill)
|
.height(iced::Length::Fill)
|
||||||
.align_x(iced::alignment::Horizontal::Center)
|
|
||||||
.align_y(iced::alignment::Vertical::Center)
|
|
||||||
.style(c_style(color_crust, Color::TRANSPARENT, 0.0))
|
.style(c_style(color_crust, Color::TRANSPARENT, 0.0))
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
@@ -569,6 +630,7 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
|
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
|
top_bar,
|
||||||
header_container,
|
header_container,
|
||||||
vertical_space(15.0),
|
vertical_space(15.0),
|
||||||
main_layout
|
main_layout
|
||||||
|
|||||||
Reference in New Issue
Block a user