Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nicklist context #61

Merged
merged 2 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions data/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum Kind {
Quit,
Msg,
Me,
Whois,
}

impl FromStr for Kind {
Expand All @@ -26,6 +27,7 @@ impl FromStr for Kind {
"quit" => Ok(Kind::Quit),
"msg" => Ok(Kind::Msg),
"me" => Ok(Kind::Me),
"whois" => Ok(Kind::Whois),
_ => Err(()),
}
}
Expand All @@ -39,6 +41,7 @@ pub enum Command {
Quit(Option<String>),
Msg(String, String),
Me(String, String),
Whois(Option<String>, String),
Unknown(String, Vec<String>),
}

Expand Down Expand Up @@ -79,11 +82,16 @@ pub fn parse(s: &str, buffer: &Buffer) -> Result<Command, Error> {
Ok(unknown())
}
}
Kind::Whois => validated::<1, 0, false>(args, |[nick], _| {
// Leaving out optional [server] for now.
Command::Whois(None, nick)
}),
},
Err(_) => Ok(unknown()),
}
}

// TODO: Expand `validated` so we can better indicate which parameters is optional.
fn validated<const EXACT: usize, const OPT: usize, const TEXT: bool>(
args: Vec<&str>,
f: impl FnOnce([String; EXACT], [Option<String>; OPT]) -> Command,
Expand Down Expand Up @@ -135,6 +143,7 @@ impl TryFrom<Command> for proto::Command {
Command::Me(target, text) => {
proto::Command::PRIVMSG(target, format!("\u{1}ACTION {text}\u{1}"))
}
Command::Whois(channel, user) => proto::Command::WHOIS(channel, user),
Command::Unknown(command, args) => {
let args = args.iter().map(|arg| arg.as_str()).collect();

Expand Down
7 changes: 7 additions & 0 deletions data/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ pub struct Input {
}

impl Input {
pub fn command(buffer: Buffer, command: Command) -> Self {
Self {
buffer,
content: Content::Command(command),
}
}

pub fn server(&self) -> &Server {
self.buffer.server()
}
Expand Down
41 changes: 21 additions & 20 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use data::{buffer, history};
use iced::Command;

use self::channel::Channel;
use self::empty::Empty;
use self::query::Query;
use self::server::Server;
use crate::widget::Element;
Expand All @@ -14,39 +13,36 @@ mod input_view;
pub mod query;
mod scroll_view;
pub mod server;
pub mod user_context;

#[derive(Clone)]
pub enum Buffer {
Empty(Empty),
Empty,
Channel(Channel),
Server(Server),
Query(Query),
}

#[derive(Debug, Clone)]
pub enum Message {
Empty(empty::Message),
Channel(channel::Message),
Server(server::Message),
Query(query::Message),
}

#[derive(Debug, Clone)]
pub enum Event {
Empty(empty::Event),
Channel(channel::Event),
Server(server::Event),
Query(query::Event),
UserContext(user_context::Event),
}

impl Buffer {
pub fn empty() -> Self {
Self::Empty(Empty::default())
Self::Empty
}

pub fn data(&self) -> Option<data::Buffer> {
match self {
Buffer::Empty(_) => None,
Buffer::Empty => None,
Buffer::Channel(state) => Some(data::Buffer::Channel(
state.server.clone(),
state.channel.clone(),
Expand All @@ -66,23 +62,28 @@ impl Buffer {
history: &mut history::Manager,
) -> (Command<Message>, Option<Event>) {
match (self, message) {
(Buffer::Empty(state), Message::Empty(message)) => {
(Command::none(), state.update(message).map(Event::Empty))
}
(Buffer::Channel(state), Message::Channel(message)) => {
let (command, event) = state.update(message, clients, history);

(command.map(Message::Channel), event.map(Event::Channel))
let event = event.map(|event| match event {
channel::Event::UserContext(event) => Event::UserContext(event),
});

(command.map(Message::Channel), event)
}
(Buffer::Server(state), Message::Server(message)) => {
let (command, event) = state.update(message, clients, history);
let command = state.update(message, clients, history);

(command.map(Message::Server), event.map(Event::Server))
(command.map(Message::Server), None)
}
(Buffer::Query(state), Message::Query(message)) => {
let (command, event) = state.update(message, clients, history);

(command.map(Message::Query), event.map(Event::Query))
let event = event.map(|event| match event {
query::Event::UserContext(event) => Event::UserContext(event),
});

(command.map(Message::Query), event)
}
_ => (Command::none(), None),
}
Expand All @@ -96,7 +97,7 @@ impl Buffer {
is_focused: bool,
) -> Element<'a, Message> {
match self {
Buffer::Empty(state) => empty::view(state).map(Message::Empty),
Buffer::Empty => empty::view(),
Buffer::Channel(state) => {
let status = clients.status(&state.server);

Expand Down Expand Up @@ -138,7 +139,7 @@ impl Buffer {

pub fn focus(&self) -> Command<Message> {
match self {
Buffer::Empty(_) => Command::none(),
Buffer::Empty => Command::none(),
Buffer::Channel(channel) => channel.focus().map(Message::Channel),
Buffer::Server(server) => server.focus().map(Message::Server),
Buffer::Query(query) => query.focus().map(Message::Query),
Expand All @@ -147,7 +148,7 @@ impl Buffer {

pub fn scroll_to_start(&mut self) -> Command<Message> {
match self {
Buffer::Empty(_) => Command::none(),
Buffer::Empty => Command::none(),
Buffer::Channel(channel) => channel
.scroll_view
.scroll_to_start()
Expand All @@ -165,7 +166,7 @@ impl Buffer {

pub fn scroll_to_end(&mut self) -> Command<Message> {
match self {
Buffer::Empty(_) => Command::none(),
Buffer::Empty => Command::none(),
Buffer::Channel(channel) => channel
.scroll_view
.scroll_to_end()
Expand Down
115 changes: 73 additions & 42 deletions src/buffer/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ use std::fmt;

use data::server::Server;
use data::{buffer, client, history};
use iced::widget::{column, container, row, scrollable, text, vertical_space};
use iced::widget::{column, container, row, vertical_space};
use iced::{Command, Length};

use super::{input_view, scroll_view};
use super::{input_view, scroll_view, user_context};
use crate::theme;
use crate::widget::{selectable_text, Collection, Column, Element};
use crate::widget::{selectable_text, Collection, Element};

#[derive(Debug, Clone)]
pub enum Message {
ScrollView(scroll_view::Message),
InputView(input_view::Message),
UserContext(user_context::Message),
}

#[derive(Debug, Clone)]
pub enum Event {}
pub enum Event {
UserContext(user_context::Event),
}

pub fn view<'a>(
state: &'a Channel,
Expand All @@ -40,9 +43,13 @@ pub fn view<'a>(
.map(|timestamp| {
selectable_text(timestamp).style(theme::Text::Alpha04)
});
let nick = selectable_text(settings.nickname.brackets.format(user)).style(
theme::Text::Nickname(user.color_seed(&settings.nickname.color)),
);
let nick = user_context::view(
selectable_text(settings.nickname.brackets.format(user)).style(
theme::Text::Nickname(user.color_seed(&settings.nickname.color)),
),
user.clone(),
)
.map(scroll_view::Message::UserContext);
let message = selectable_text(&message.text);

Some(
Expand Down Expand Up @@ -73,47 +80,18 @@ pub fn view<'a>(
.map(Message::InputView)
});

let user_column = {
let users = clients.get_channel_users(&state.server, &state.channel);
let column = Column::with_children(
users
.iter()
.map(|user| {
container(row![].padding([0, 4]).push(text(format!(
"{}{}",
user.highest_access_level(),
user.nickname()
))))
.into()
})
.collect(),
)
.padding(4)
.spacing(1);

container(
scrollable(column)
.vertical_scroll(
iced::widget::scrollable::Properties::new()
.width(1)
.scroller_width(1),
)
.style(theme::Scrollable::Hidden),
)
.width(Length::Shrink)
.max_width(120)
.height(Length::Fill)
};
let users = clients.get_channel_users(&state.server, &state.channel);
let nick_list = nick_list::view(users).map(Message::UserContext);

let content = match (
settings.channel.users.visible,
settings.channel.users.position,
) {
(true, data::channel::Position::Left) => {
row![user_column, messages]
row![nick_list, messages]
}
(true, data::channel::Position::Right) => {
row![messages, user_column]
row![messages, nick_list]
}
(false, _) => { row![messages] }.height(Length::Fill),
};
Expand Down Expand Up @@ -158,8 +136,13 @@ impl Channel {
) -> (Command<Message>, Option<Event>) {
match message {
Message::ScrollView(message) => {
let command = self.scroll_view.update(message);
(command.map(Message::ScrollView), None)
let (command, event) = self.scroll_view.update(message);

let event = event.map(|event| match event {
scroll_view::Event::UserContext(event) => Event::UserContext(event),
});

(command.map(Message::ScrollView), event)
}
Message::InputView(message) => {
let (command, event) =
Expand All @@ -179,6 +162,10 @@ impl Channel {
None => (command, None),
}
}
Message::UserContext(message) => (
Command::none(),
Some(Event::UserContext(user_context::update(message))),
),
}
}

Expand All @@ -194,3 +181,47 @@ impl fmt::Display for Channel {
write!(f, "{} ({})", channel, self.server)
}
}

mod nick_list {
use data::User;
use iced::widget::{column, container, row, scrollable, text};
use iced::Length;
use user_context::Message;

use crate::buffer::user_context;
use crate::theme;
use crate::widget::Element;

pub fn view<'a>(users: Vec<User>) -> Element<'a, Message> {
let column = column(
users
.iter()
.map(|user| {
let content = container(row![].padding([0, 4]).push(text(format!(
"{}{}",
user.highest_access_level(),
user.nickname()
))));

user_context::view(content, user.clone())
})
.collect(),
)
.padding(4)
.spacing(1);

container(
scrollable(column)
.vertical_scroll(
iced::widget::scrollable::Properties::new()
.width(1)
.scroller_width(1),
)
.style(theme::Scrollable::Hidden),
)
.width(Length::Shrink)
.max_width(120)
.height(Length::Fill)
.into()
}
}
25 changes: 1 addition & 24 deletions src/buffer/empty.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
use core::fmt;

use iced::widget::{column, container, text};
use iced::{alignment, Length};

use crate::widget::Element;

#[derive(Debug, Clone)]
pub enum Message {}

#[derive(Debug, Clone)]
pub enum Event {}

pub fn view<'a>(_state: &Empty) -> Element<'a, Message> {
pub fn view<'a, Message: 'a>() -> Element<'a, Message> {
// TODO: Consider if we can completetly remove this buffer.

let content = column![]
Expand All @@ -25,18 +17,3 @@ pub fn view<'a>(_state: &Empty) -> Element<'a, Message> {
.height(Length::Fill)
.into()
}

#[derive(Debug, Default, Clone)]
pub struct Empty {}

impl Empty {
pub fn update(&mut self, _message: Message) -> Option<Event> {
None
}
}

impl fmt::Display for Empty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "")
}
}
Loading