Skip to content

Commit

Permalink
Add channel fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
tarkah committed Sep 16, 2024
1 parent 584964b commit fcd6403
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 121 deletions.
36 changes: 36 additions & 0 deletions data/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ pub fn parse_fragments(text: String, channel_users: &[User]) -> Content {

Either::Right(std::iter::once(fragment))
})
.flat_map(|fragment| {
if let Fragment::Text(text) = &fragment {
return Either::Left(parse_channel_fragments(text).into_iter());
}

Either::Right(std::iter::once(fragment))
})
.collect::<Vec<_>>();

if fragments.len() == 1 && matches!(&fragments[0], Fragment::Text(_)) {
Expand Down Expand Up @@ -403,6 +410,32 @@ fn parse_user_fragments(text: &str, channel_users: &[User]) -> Vec<Fragment> {
})
}

fn parse_channel_fragments(text: &str) -> Vec<Fragment> {
text.chars()
.group_by(|c| c.is_whitespace())
.into_iter()
.map(|(is_whitespace, chars)| {
let text = chars.collect::<String>();

if !is_whitespace && proto::is_channel(&text) {
return Fragment::Channel(text);
}

Fragment::Text(text)
})
.fold(vec![], |mut acc, fragment| {
if let Some(Fragment::Text(text)) = acc.last_mut() {
if let Fragment::Text(next) = &fragment {
text.push_str(next);
return acc;
}
}

acc.push(fragment);
acc
})
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Content {
Plain(String),
Expand All @@ -421,6 +454,7 @@ impl Content {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Fragment {
Text(String),
Channel(String),
User(User),
Url(Url),
Formatted {
Expand All @@ -433,6 +467,7 @@ impl Fragment {
pub fn as_str(&self) -> &str {
match self {
Fragment::Text(s) => s,
Fragment::Channel(s) => s,
Fragment::User(u) => u.as_str(),
Fragment::Url(u) => u.as_str(),
Fragment::Formatted { text, .. } => text,
Expand Down Expand Up @@ -1013,6 +1048,7 @@ pub fn reference_user_text(sender: NickRef, own_nick: NickRef, text: &str) -> bo

#[derive(Debug, Clone)]
pub enum Link {
Channel(String),
Url(String),
User(User),
}
Expand Down
12 changes: 10 additions & 2 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub enum Message {
#[derive(Debug, Clone)]
pub enum Event {
UserContext(user_context::Event),
OpenChannel(String),
}

impl Buffer {
Expand Down Expand Up @@ -71,20 +72,27 @@ impl Buffer {

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

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

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

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

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

(command.map(Message::Query), event)
Expand Down
6 changes: 4 additions & 2 deletions src/buffer/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum Message {
#[derive(Debug, Clone)]
pub enum Event {
UserContext(user_context::Event),
OpenChannel(String),
}

pub fn view<'a>(
Expand Down Expand Up @@ -120,16 +121,16 @@ pub fn view<'a>(
scroll_view::Message::Link,
theme::selectable_text::default,
move |link| match link {
message::Link::Url(_) => vec![],
message::Link::User(_) => {
user_context::Entry::list(buffer, our_user)
}
_ => vec![],
},
move |link, entry, length| match link {
message::Link::Url(_) => row![].into(),
message::Link::User(user) => entry
.view(user, current_user, length)
.map(scroll_view::Message::UserContext),
_ => row![].into(),
},
config,
);
Expand Down Expand Up @@ -327,6 +328,7 @@ impl Channel {

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

(command.map(Message::ScrollView), event)
Expand Down
6 changes: 4 additions & 2 deletions src/buffer/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum Message {
#[derive(Debug, Clone)]
pub enum Event {
UserContext(user_context::Event),
OpenChannel(String),
}

pub fn view<'a>(
Expand Down Expand Up @@ -80,14 +81,14 @@ pub fn view<'a>(
scroll_view::Message::Link,
theme::selectable_text::default,
move |link| match link {
message::Link::Url(_) => vec![],
message::Link::User(_) => user_context::Entry::list(buffer, None),
_ => vec![],
},
move |link, entry, length| match link {
message::Link::Url(_) => row![].into(),
message::Link::User(user) => entry
.view(user, None, length)
.map(scroll_view::Message::UserContext),
_ => row![].into(),
},
config,
);
Expand Down Expand Up @@ -242,6 +243,7 @@ impl Query {

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

(command.map(Message::ScrollView), event)
Expand Down
4 changes: 4 additions & 0 deletions src/buffer/scroll_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum Message {
#[derive(Debug, Clone)]
pub enum Event {
UserContext(user_context::Event),
OpenChannel(String),
}

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -227,6 +228,9 @@ impl State {
user_context::update(message).map(Event::UserContext),
);
}
Message::Link(message::Link::Channel(channel)) => {
return (Task::none(), Some(Event::OpenChannel(channel)))
}
Message::Link(message::Link::Url(url)) => {
let _ = open::that_detached(url);
}
Expand Down
26 changes: 20 additions & 6 deletions src/buffer/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use data::{history, message, Config};
use iced::widget::{column, container, row, vertical_space};
use iced::{Length, Task};

use super::{input_view, scroll_view};
use super::{input_view, scroll_view, user_context};
use crate::widget::{message_content, selectable_text, Element};
use crate::{theme, Theme};

Expand All @@ -12,6 +12,12 @@ pub enum Message {
InputView(input_view::Message),
}

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

pub fn view<'a>(
state: &'a Server,
clients: &'a data::client::Map,
Expand Down Expand Up @@ -119,25 +125,33 @@ impl Server {
clients: &mut data::client::Map,
history: &mut history::Manager,
config: &Config,
) -> Task<Message> {
) -> (Task<Message>, Option<Event>) {
match message {
Message::ScrollView(message) => {
let (command, _) = self.scroll_view.update(message);
command.map(Message::ScrollView)
let (command, event) = self.scroll_view.update(message);

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

(command.map(Message::ScrollView), event)
}
Message::InputView(message) => {
let (command, event) =
self.input_view
.update(message, &self.buffer, clients, history, config);
let command = command.map(Message::InputView);

match event {
let task = match event {
Some(input_view::Event::InputSent) => Task::batch(vec![
command,
self.scroll_view.scroll_to_end().map(Message::ScrollView),
]),
None => command,
}
};

(task, None)
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/buffer/user_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub enum Event {
SingleClick(Nick),
ToggleAccessLevel(Nick, String),
SendFile(Nick),
OpenChannel(String),
}

pub fn update(message: Message) -> Option<Event> {
Expand All @@ -122,6 +123,7 @@ pub fn update(message: Message) -> Option<Event> {
Message::SingleClick(nick) => Some(Event::SingleClick(nick)),
Message::ToggleAccessLevel(nick, mode) => Some(Event::ToggleAccessLevel(nick, mode)),
Message::SendFile(nick) => Some(Event::SendFile(nick)),
Message::Link(message::Link::Channel(channel)) => Some(Event::OpenChannel(channel)),
Message::Link(message::Link::Url(url)) => {
let _ = open::that_detached(url);
None
Expand Down
Loading

0 comments on commit fcd6403

Please sign in to comment.