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

Display Notice and Emote messages properly #269

Merged
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
7 changes: 7 additions & 0 deletions src/home/room_preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,21 @@ impl RoomPreviewContent {
let message_text_color;
let room_name_color;
let timestamp_color;
let code_bg_color;

// TODO: This is quite verbose, makepad should provide a way to override this at a higher level.
if is_selected {
bg_color = vec3(0.059, 0.533, 0.996); // COLOR_PRIMARY_SELECTED
message_text_color = vec3(1., 1., 1.); // COLOR_PRIMARY
room_name_color = vec3(1., 1., 1.); // COLOR_PRIMARY
timestamp_color = vec3(1., 1., 1.); // COLOR_PRIMARY
code_bg_color = vec3(0.3, 0.3, 0.3); // a darker gray, used for `code_color` and `quote_bg_color`
} else {
bg_color = vec3(1., 1., 1.); // COLOR_PRIMARY
message_text_color = vec3(0.267, 0.267, 0.267); // MESSAGE_TEXT_COLOR
room_name_color = vec3(0., 0., 0.);
timestamp_color = vec3(0.6, 0.6, 0.6);
code_bg_color = vec3(0.929, 0.929, 0.929); // #EDEDED, see `code_color` and `quote_bg_color`
}

self.view.apply_over(
Expand Down Expand Up @@ -312,6 +315,10 @@ impl RoomPreviewContent {
draw_italic: { color: (message_text_color) },
draw_bold: { color: (message_text_color) },
draw_bold_italic: { color: (message_text_color) },
draw_block: {
quote_bg_color: (code_bg_color),
code_color: (code_bg_color),
}
}
}
plaintext_view = {
Expand Down
121 changes: 108 additions & 13 deletions src/home/room_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use matrix_sdk::{
ruma::{
events::room::{
message::{
FormattedBody, ImageMessageEventContent, LocationMessageEventContent, MessageFormat, MessageType, NoticeMessageEventContent, RoomMessageEventContent, TextMessageEventContent
EmoteMessageEventContent, FormattedBody, ImageMessageEventContent, LocationMessageEventContent, MessageFormat, MessageType, NoticeMessageEventContent, RoomMessageEventContent, TextMessageEventContent
},
MediaSource,
}, matrix_uri::MatrixId, uint, EventId, MatrixToUri, MatrixUri, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, UserId
Expand Down Expand Up @@ -37,6 +37,8 @@ use super::loading_modal::{LoadingModalAction, LoadingModalState};

const GEO_URI_SCHEME: &str = "geo:";

const MESSAGE_NOTICE_TEXT_COLOR: Vec3 = Vec3 { x: 0.5, y: 0.5, z: 0.5 };

live_design! {
import makepad_draw::shader::std::*;
import makepad_widgets::base::*;
Expand Down Expand Up @@ -227,7 +229,7 @@ live_design! {
height: Fit,
padding: {top: 5.0}

html_content = <RobrixHtml> {
html_content = <MessageHtml> {
width: Fill,
height: Fit,
padding: { bottom: 5.0, top: 0.0 },
Expand Down Expand Up @@ -2375,6 +2377,8 @@ fn populate_message_view(

let ts_millis = event_tl_item.timestamp();

let mut is_notice = false; // whether this message is a Notice

// Determine whether we can use a more compact UI view that hides the user's profile info
// if the previous message was sent by the same user within 10 minutes.
let use_compact_view = match prev_event.map(|p| p.kind()) {
Expand All @@ -2391,9 +2395,67 @@ fn populate_message_view(
_ => false,
};

// Sometimes we need to call this up-front, so we save the result in this variable
// to avoid having to call it twice.
let mut set_username_and_get_avatar_retval = None;

let (item, used_cached_item) = match message.msgtype() {
MessageType::Text(TextMessageEventContent { body, formatted, .. })
| MessageType::Notice(NoticeMessageEventContent { body, formatted, .. }) => {
MessageType::Text(TextMessageEventContent { body, formatted, .. }) => {
let template = if use_compact_view {
live_id!(CondensedMessage)
} else {
live_id!(Message)
};
let (item, existed) = list.item_with_existed(cx, item_id, template);
if existed && item_drawn_status.content_drawn {
(item, true)
} else {
populate_text_message_content(
&item.html_or_plaintext(id!(content.message)),
&body,
formatted.as_ref(),
);
new_drawn_status.content_drawn = true;
(item, false)
}
}
// A notice message is just a message sent by an automated bot,
// so we treat it just like a message but use a different font color.
MessageType::Notice(NoticeMessageEventContent { body, formatted, .. }) => {
is_notice = true;
let template = if use_compact_view {
live_id!(CondensedMessage)
} else {
live_id!(Message)
};
let (item, existed) = list.item_with_existed(cx, item_id, template);
if existed && item_drawn_status.content_drawn {
(item, true)
} else {
let html_or_plaintext_ref = item.html_or_plaintext(id!(content.message));
html_or_plaintext_ref.apply_over(cx, live!(
html_view = {
html = {
font_color: (MESSAGE_NOTICE_TEXT_COLOR),
draw_normal: { color: (MESSAGE_NOTICE_TEXT_COLOR), }
draw_italic: { color: (MESSAGE_NOTICE_TEXT_COLOR), }
draw_bold: { color: (MESSAGE_NOTICE_TEXT_COLOR), }
draw_bold_italic: { color: (MESSAGE_NOTICE_TEXT_COLOR), }
}
}
));
populate_text_message_content(
&html_or_plaintext_ref,
&body,
formatted.as_ref(),
);
new_drawn_status.content_drawn = true;
(item, false)
}
}
// An emote is just like a message but is prepended with the user's name
// to indicate that it's an "action" that the user is performing.
MessageType::Emote(EmoteMessageEventContent { body, formatted, .. }) => {
let template = if use_compact_view {
live_id!(CondensedMessage)
} else {
Expand All @@ -2403,11 +2465,34 @@ fn populate_message_view(
if existed && item_drawn_status.content_drawn {
(item, true)
} else {
// Draw the profile up front here because we need the username for the emote body.
let (username, profile_drawn) = set_avatar_and_get_username(
cx,
item.avatar(id!(profile.avatar)),
room_id,
event_tl_item.sender(),
event_tl_item.sender_profile(),
event_tl_item.event_id(),
);

// Prepend a "* <username> " to the emote body, as suggested by the Matrix spec.
let (body, formatted) = if let Some(fb) = formatted.as_ref() {
(
Cow::from(&fb.body),
Some(FormattedBody {
format: fb.format.clone(),
body: format!("* {} {}", &username, &fb.body),
})
)
} else {
(Cow::from(format!("* {} {}", &username, body)), None)
};
populate_text_message_content(
&item.html_or_plaintext(id!(content.message)),
&body,
formatted.as_ref(),
);
set_username_and_get_avatar_retval = Some((username, profile_drawn));
new_drawn_status.content_drawn = true;
(item, false)
}
Expand Down Expand Up @@ -2490,15 +2575,25 @@ fn populate_message_view(
new_drawn_status.profile_drawn = true;
} else {
// log!("\t --> populate_message_view(): DRAWING profile draw for item_id: {item_id}");
let (username, profile_drawn) = set_avatar_and_get_username(
cx,
item.avatar(id!(profile.avatar)),
room_id,
event_tl_item.sender(),
event_tl_item.sender_profile(),
event_tl_item.event_id(),
let (username, profile_drawn) = set_username_and_get_avatar_retval.unwrap_or_else(||
set_avatar_and_get_username(
cx,
item.avatar(id!(profile.avatar)),
room_id,
event_tl_item.sender(),
event_tl_item.sender_profile(),
event_tl_item.event_id(),
)
);
item.label(id!(content.username)).set_text(&username);
let username_label = item.label(id!(content.username));
if is_notice {
username_label.apply_over(cx, live!(
draw_text: {
color: (MESSAGE_NOTICE_TEXT_COLOR),
}
));
}
username_label.set_text(&username);
new_drawn_status.profile_drawn = profile_drawn;
}

Expand Down Expand Up @@ -2556,7 +2651,7 @@ fn populate_text_message_content(
body: &str,
formatted_body: Option<&FormattedBody>,
) {
if let Some(formatted_body) = formatted_body
if let Some(formatted_body) = formatted_body.as_ref()
.and_then(|fb| (fb.format == MessageFormat::Html).then(|| fb.body.clone()))
{
message_content_widget.show_html(utils::linkify(formatted_body.as_ref()));
Expand Down
2 changes: 1 addition & 1 deletion src/home/welcome_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ live_design! {
}

// Using the HTML widget to taking advantage of embedding a link within text with proper vertical alignment
<RobrixHtml> {
<MessageHtml> {
padding: {top: 12, left: 0.}
font_size: 14.
font_color: (WELCOME_TEXT_COLOR)
Expand Down
12 changes: 3 additions & 9 deletions src/shared/html_or_plaintext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ live_design! {

// A centralized widget where we define styles and custom elements for HTML
// message content. This is a wrapper around Makepad's built-in `Html` widget.
RobrixHtml = <Html> {
MessageHtml = <Html> {
padding: 0.0,
width: Fill, height: Fit, // see comment in `HtmlOrPlaintext`
font_size: (MESSAGE_FONT_SIZE),
Expand All @@ -59,19 +59,13 @@ live_design! {

a = {
padding: {left: 1.0, right: 1.5},
// draw_text: {
// text_style: <MESSAGE_TEXT_STYLE> { font_size: (MESSAGE_FONT_SIZE), height_factor: (HTML_TEXT_HEIGHT_FACTOR), line_spacing: (HTML_LINE_SPACING), top_drop: 1.2, },
// color: #00f,
// color_pressed: #f00,
// color_hover: #0f0,
// }
}

body: "[<i> HTML message placeholder</i>]",
}

// A view container that displays either plaintext s(a simple `Label`)
// or rich HTML content (an instance of `RobrixHtml`).
// or rich HTML content (an instance of `MessageHtml`).
//
// Key Usage Notes:
// * Labels need their width to be Fill *and* all of their parent views
Expand Down Expand Up @@ -101,7 +95,7 @@ live_design! {
html_view = <View> {
visible: false,
width: Fill, height: Fit, // see above comment
html = <RobrixHtml> {}
html = <MessageHtml> {}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/shared/styles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ live_design! {
TYPING_NOTICE_TEXT_COLOR = #121570

MESSAGE_FONT_SIZE = 11
MESSAGE_TEXT_COLOR = #x444
MESSAGE_TEXT_COLOR = #x333
// notices (automated messages from bots) use a lighter color
MESSAGE_NOTICE_TEXT_COLOR = #x888
MESSAGE_TEXT_LINE_SPACING = 1.35
MESSAGE_TEXT_HEIGHT_FACTOR = 1.55
// This font should only be used for plaintext labels. Don't use this for Html content,
Expand All @@ -44,6 +46,7 @@ live_design! {

MESSAGE_REPLY_PREVIEW_FONT_SIZE = 9.5


SMALL_STATE_FONT_SIZE = 9.0
SMALL_STATE_TEXT_COLOR = #x888
SMALL_STATE_TEXT_STYLE = <THEME_FONT_REGULAR>{
Expand Down