Skip to content

Commit

Permalink
Handle reactions and show them as suffix of messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
boxdot committed May 7, 2021
1 parent 21459f9 commit 254208e
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 19 deletions.
139 changes: 121 additions & 18 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use log::error;
use notify_rust::Notification;
use presage::prelude::{
content::{ContentBody, DataMessage, Metadata, SyncMessage},
proto::{data_message::Quote, sync_message::Sent, GroupContextV2},
proto::{
data_message::{Quote, Reaction},
sync_message::Sent,
GroupContextV2,
},
Content, ServiceAddress,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -142,16 +146,30 @@ pub struct Message {
pub quote: Option<Box<Message>>,
#[serde(default)]
pub attachments: Vec<signal::Attachment>,
#[serde(default)]
pub reactions: Vec<(Uuid, String)>,
}

impl Message {
fn new(from_id: Uuid, message: String, arrived_at: u64) -> Self {
Self {
from_id,
message: Some(message),
arrived_at,
quote: None,
attachments: Default::default(),
reactions: Default::default(),
}
}

fn from_quote(quote: Quote) -> Option<Message> {
Some(Message {
from_id: quote.author_uuid?.parse().ok()?,
message: quote.text,
attachments: Default::default(),
arrived_at: quote.id?,
quote: None,
attachments: Default::default(),
reactions: Default::default(),
})
}
}
Expand Down Expand Up @@ -325,9 +343,10 @@ impl App {
channel.messages.items.push(Message {
from_id: self.signal_manager.uuid(),
message: Some(message),
attachments: Vec::new(),
arrived_at: timestamp,
quote: quote_message,
attachments: Default::default(),
reactions: Default::default(),
});

self.reset_unread_messages();
Expand Down Expand Up @@ -496,13 +515,7 @@ impl App {
}),
) if destination_uuid.parse() == Ok(self_uuid) => {
let channel_idx = self.ensure_own_channel_exists();
let message = Message {
from_id: self_uuid,
message: Some(text),
attachments: Default::default(),
arrived_at: timestamp,
quote: None,
};
let message = Message::new(self_uuid, text, timestamp);
(channel_idx, message)
}
// Direct/group message by us from a different device
Expand Down Expand Up @@ -556,11 +569,8 @@ impl App {

let quote = quote.and_then(Message::from_quote).map(Box::new);
let message = Message {
from_id: self_uuid,
message: Some(text),
attachments: Default::default(),
arrived_at: timestamp,
quote,
..Message::new(self_uuid, text, timestamp)
};
(channel_idx, message)
}
Expand Down Expand Up @@ -617,14 +627,64 @@ impl App {

let quote = quote.and_then(Message::from_quote).map(Box::new);
let message = Message {
from_id: uuid,
message: Some(text),
attachments: Default::default(),
arrived_at: timestamp,
quote,
..Message::new(uuid, text, timestamp)
};
(channel_idx, message)
}
// reactions
(
Metadata {
sender:
ServiceAddress {
uuid: Some(sender_uuid),
..
},
..
},
ContentBody::SynchronizeMessage(SyncMessage {
sent:
Some(Sent {
destination_uuid,
message:
Some(DataMessage {
body: None,
group_v2,
reaction:
Some(Reaction {
emoji: Some(emoji),
remove,
target_sent_timestamp: Some(target_sent_timestamp),
..
}),
..
}),
..
}),
..
}),
) => {
let channel_id = if let Some(GroupContextV2 {
master_key: Some(master_key),
..
}) = group_v2
{
ChannelId::Group(master_key)
} else if let Some(uuid) = destination_uuid {
ChannelId::User(uuid.parse()?)
} else {
return Ok(());
};

self.handle_reaction(
channel_id,
target_sent_timestamp,
sender_uuid,
remove.unwrap_or(false),
emoji,
);
return Ok(());
}
_ => return Ok(()),
};

Expand All @@ -633,6 +693,45 @@ impl App {
Ok(())
}

fn handle_reaction(
&mut self,
channel_id: ChannelId,
target_sent_timestamp: u64,
sender_uuid: Uuid,
remove: bool,
emoji: String,
) -> Option<()> {
let channel_idx = self
.data
.channels
.items
.iter()
.position(|channel| channel.id == channel_id)?;
let channel = &mut self.data.channels.items[channel_idx];
let message = channel
.messages
.items
.iter_mut()
.find(|m| m.arrived_at == target_sent_timestamp)?;
let reaction_idx = message
.reactions
.iter()
.position(|(from_id, _)| from_id == &sender_uuid);
if let Some(idx) = reaction_idx {
if remove {
message.reactions.swap_remove(idx);
self.save().unwrap();
} else {
message.reactions[idx].1 = emoji;
self.touch_channel(channel_idx);
}
} else {
message.reactions.push((sender_uuid, emoji));
self.touch_channel(channel_idx);
}
Some(())
}

async fn ensure_group_channel_exists(
&mut self,
master_key: Vec<u8>,
Expand Down Expand Up @@ -793,6 +892,10 @@ impl App {
channel.messages.state.select(Some(idx + 1));
}

self.touch_channel(channel_idx);
}

fn touch_channel(&mut self, channel_idx: usize) {
if self.data.channels.state.selected() != Some(channel_idx) {
self.data.channels.items[channel_idx].unread_messages += 1;
} else {
Expand Down
16 changes: 15 additions & 1 deletion src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::util;
use crate::{app, App};

use chrono::{Datelike, Timelike};
use itertools::Itertools;
use tui::backend::Backend;
use tui::layout::{Constraint, Corner, Direction, Layout, Rect};
use tui::style::{Color, Style};
Expand All @@ -10,6 +11,8 @@ use tui::widgets::{Block, Borders, List, ListItem, Paragraph};
use tui::Frame;
use unicode_width::UnicodeWidthStr;

use std::borrow::Cow;

pub const CHANNEL_VIEW_RATIO: u32 = 4;

pub fn coords_within_channels_view<B: Backend>(f: &Frame<B>, x: u16, y: u16) -> Option<(u16, u16)> {
Expand Down Expand Up @@ -175,7 +178,18 @@ fn draw_messages<B: Backend>(f: &mut Frame<B>, app: &mut App, area: Rect) {
let wrap_opts = textwrap::Options::new(width.into())
.initial_indent(&indent)
.subsequent_indent(&indent);
let mut lines = textwrap::wrap(msg.message.as_ref()?, wrap_opts);

let text = if msg.reactions.is_empty() {
Cow::from(msg.message.as_ref()?)
} else {
Cow::from(format!(
"{} [{}]",
msg.message.as_ref()?,
msg.reactions.iter().map(|(_, emoji)| emoji).format(""),
))
};

let mut lines = textwrap::wrap(&text, wrap_opts);

// prepend quote if any
let quote = if let Some(displayed_quote) = msg
Expand Down

0 comments on commit 254208e

Please sign in to comment.