added channels front-end

This commit is contained in:
2025-08-27 19:19:49 +02:00
parent 0bef2b69c2
commit c4f471179c
4 changed files with 159 additions and 70 deletions

47
front/src/buttons.rs Normal file
View File

@@ -0,0 +1,47 @@
use iced::{
Border,
widget::{Button, container},
};
use iced::{Length, Shadow};
use crate::servers::colors;
use crate::Event;
pub trait MessagingGroup {
fn get_id(&self) -> i32;
fn get_name(&self) -> &String;
}
pub fn button<'a, MG>(
messaging_group: MG,
selected: Option<i32>,
press_variant: fn(i32) -> Event,
) -> Button<'a, Event>
where
MG: MessagingGroup + Clone + 'a,
{
let id = messaging_group.get_id();
Button::new(
container(iced::widget::text(messaging_group.get_name().clone()).size(20))
.center_x(Length::Fill)
.center_y(Length::Fill),
)
.padding(10)
.width(iced::Length::Fill)
.height(Length::Fixed(100.0))
.style(move |_theme, _status| iced::widget::button::Style {
background: Some(iced::Background::Color(if Some(id) == selected {
colors::SELECTED_BUTTON_COLOR
} else {
colors::BUTTON_COLOR
})),
border: Border::default().rounded(10),
shadow: Shadow {
offset: iced::Vector { x: 3., y: 3. },
..Default::default()
},
..Default::default()
})
.on_press(press_variant(id))
}

View File

@@ -1,15 +1,53 @@
use crate::buttons::{self, MessagingGroup};
use crate::{Event, Liscord, User};
use iced::widget::{Button, Column};
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Clone, Default)] #[derive(Clone, Default, Debug)]
pub struct Channel { pub struct Channel {
pub channel_id: i32,
pub server_id: i32, pub server_id: i32,
pub channel_name: String, pub channel_name: String,
} }
impl Channel { impl Channel {
fn new(server_id: i32, channel_name: &str) -> Self { fn new(channel_id: i32, server_id: i32, channel_name: &str) -> Self {
Channel { Channel {
channel_id,
server_id, server_id,
channel_name: channel_name.to_string(), channel_name: channel_name.to_string(),
} }
} }
} }
impl MessagingGroup for Channel {
fn get_id(&self) -> i32 {
self.channel_id
}
fn get_name(&self) -> &String {
&self.channel_name
}
}
fn channel_button<'a>(channel: Channel, instance: &'a Liscord) -> Button<'a, Event> {
buttons::button(channel, instance.selected_channel, Event::ChannelPressed)
}
pub fn get_channels(_user: &User, server_id: i32) -> Vec<Channel> {
let friend_serv0 = Channel::new(0, server_id, "Channel 0");
let friend_serv1 = Channel::new(1, server_id, "Channel 1");
let friend_serv2 = Channel::new(2, server_id, "Channel 2");
vec![friend_serv0, friend_serv1, friend_serv2]
}
pub fn get_channels_buttons<'a>(
user: &User,
server_id: i32,
instance: &'a Liscord,
) -> Column<'a, Event> {
get_channels(user, server_id)
.into_iter()
.map(|channel| channel_button(channel, instance))
.fold(Column::new(), |col, btn| col.push(btn))
}

View File

@@ -5,11 +5,14 @@ use iced::{
widget::{Image, column, container::Style, row, text}, widget::{Image, column, container::Style, row, text},
}; };
mod buttons;
mod channels; mod channels;
mod servers; mod servers;
use servers::{User, get_servers_buttons}; use servers::{User, get_servers_buttons};
use crate::channels::get_channels_buttons;
fn main() -> Result<(), iced::Error> { fn main() -> Result<(), iced::Error> {
iced::application(Liscord::title, Liscord::update, Liscord::view) iced::application(Liscord::title, Liscord::update, Liscord::view)
.theme(Liscord::theme) .theme(Liscord::theme)
@@ -19,19 +22,22 @@ fn main() -> Result<(), iced::Error> {
struct Liscord { struct Liscord {
user: Option<User>, user: Option<User>,
selected_server: Option<i32>, selected_server: Option<i32>,
selected_channel: Option<i32>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Event { enum Event {
ServerPressed(i32), ServerPressed(i32),
ChannelPressed(i32),
} }
impl Liscord { impl Liscord {
fn new() -> (Self, Task<Event>) { fn new() -> (Self, Task<Event>) {
( (
Liscord { Self {
user: Some(User::default()), user: Some(User::default()),
selected_server: None, selected_server: None,
selected_channel: None,
}, },
Task::none(), Task::none(),
) )
@@ -44,38 +50,37 @@ impl Liscord {
fn update(&mut self, event: Event) -> Task<Event> { fn update(&mut self, event: Event) -> Task<Event> {
match event { match event {
Event::ServerPressed(server_id) => { Event::ServerPressed(server_id) => {
println!("Server pressed: {server_id}");
self.selected_server = Some(server_id); self.selected_server = Some(server_id);
// println!("Server Pressed ! Id: {server_id}") self.selected_channel = None;
// could kick off async load: return Task::perform(...)
}
Event::ChannelPressed(channel_id) => {
println!("Channel pressed: {channel_id}");
self.selected_channel = Some(channel_id);
// async tasks
} }
} }
Task::none() Task::none()
} }
fn view(&self) -> Element<'_, Event> { fn view(&self) -> Element<'_, Event> {
let app_body = { let server_bar = {
let server_bar = { let mut content = column![text("Servers")];
let mut content = column![text("Servers")]; if let Some(user) = &self.user {
content = content.push(get_servers_buttons(user, self));
}
container(content)
.padding(10)
.width(iced::Length::Fixed(200.))
.height(Fill)
.style(|_| Style {
background: Some(Background::Color(Color::from_rgb(0.0, 0.0, 1.0))),
..Default::default()
})
};
if let Some(user) = &self.user { let app_body = row![server_bar, self.inner_server_content()].height(FillPortion(19));
content = content.push(get_servers_buttons(user, self))
}
container(content)
.padding(10)
.width(iced::Length::Fixed(300.))
.height(Fill)
.style(|_theme| Style {
background: Some(Background::Color(Color::from_rgb(0.0, 0.0, 1.0))),
..Default::default()
})
};
let message_content = container(text("Messages"))
.width(iced::Length::Fill)
.height(Fill);
row![server_bar, message_content]
}
.height(FillPortion(19));
let app_header = { let app_header = {
let liscord_logo = Image::new("assets/liscord.png"); let liscord_logo = Image::new("assets/liscord.png");
@@ -84,7 +89,6 @@ impl Liscord {
.width(Fill) .width(Fill)
.center_x(Length::Fill) .center_x(Length::Fill)
.center_y(Length::Fill); .center_y(Length::Fill);
row![liscord_logo, centered_text].width(Fill).height(Fill) row![liscord_logo, centered_text].width(Fill).height(Fill)
} }
.height(FillPortion(1)); .height(FillPortion(1));
@@ -95,4 +99,23 @@ impl Liscord {
fn theme(&self) -> Theme { fn theme(&self) -> Theme {
Theme::Dark Theme::Dark
} }
fn inner_server_content(&self) -> Element<'_, Event> {
match self.selected_server {
Some(id) => {
let channels = get_channels_buttons(&self.user.clone().unwrap(), id, self)
.width(Length::Fixed(200.))
.padding(10)
.spacing(10);
container(channels)
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into()
}
None => container(text("Select a server"))
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into(),
}
}
} }

View File

@@ -1,12 +1,11 @@
use iced::{ use iced::widget::{Button, Column};
Border,
widget::{Button, Column, container}, use crate::{
Event, Liscord,
buttons::{self, MessagingGroup},
}; };
use iced::{Length, Shadow};
use crate::{Event, Liscord}; pub mod colors {
mod colors {
use iced::Color; use iced::Color;
pub const BUTTON_COLOR: Color = Color::from_rgb(0.2, 0.2, 0.2); pub const BUTTON_COLOR: Color = Color::from_rgb(0.2, 0.2, 0.2);
@@ -14,7 +13,7 @@ mod colors {
} }
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Default, Clone)] #[derive(Default, Clone, Debug)]
pub struct Server { pub struct Server {
pub server_id: i32, pub server_id: i32,
pub server_name: String, pub server_name: String,
@@ -31,6 +30,16 @@ impl Server {
} }
} }
impl MessagingGroup for Server {
fn get_id(&self) -> i32 {
self.server_id
}
fn get_name(&self) -> &String {
&self.server_name
}
}
impl PartialEq for Server { impl PartialEq for Server {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.server_id == other.server_id self.server_id == other.server_id
@@ -38,7 +47,7 @@ impl PartialEq for Server {
} }
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Default)] #[derive(Default, Clone)]
pub struct User { pub struct User {
pub user_id: i32, pub user_id: i32,
pub username: String, pub username: String,
@@ -54,40 +63,12 @@ pub fn get_servers(_user: &User) -> Vec<Server> {
} }
pub fn get_servers_buttons<'a>(user: &User, instance: &'a Liscord) -> Column<'a, Event> { pub fn get_servers_buttons<'a>(user: &User, instance: &'a Liscord) -> Column<'a, Event> {
let servers = get_servers(user); get_servers(user)
.into_iter()
let mut col = Column::new(); .map(|server| server_button(server, instance))
.fold(Column::new(), |col, button| col.push(button))
for server in servers {
col = col.push(server_button(server, instance));
}
col
} }
fn server_button<'a>(server: Server, instance: &'a Liscord) -> Button<'a, Event> { fn server_button<'a>(server: Server, instance: &'a Liscord) -> Button<'a, Event> {
Button::new( buttons::button(server, instance.selected_server, Event::ServerPressed)
container(iced::widget::text(server.server_name).size(20))
.center_x(Length::Fill)
.center_y(Length::Fill),
)
.padding(10)
.width(iced::Length::Fill)
.height(Length::Fixed(100.0))
.style(move |_theme, _status| iced::widget::button::Style {
background: Some(iced::Background::Color(
if Some(server.server_id) == instance.selected_server {
colors::SELECTED_BUTTON_COLOR
} else {
colors::BUTTON_COLOR
},
)),
border: Border::default().rounded(10),
shadow: Shadow {
offset: iced::Vector { x: 3., y: 3. },
..Default::default()
},
..Default::default()
})
.on_press(Event::ServerPressed(server.server_id))
} }