Skip to content

Commit

Permalink
Merge pull request #183 from kevinaboos/display_location_message
Browse files Browse the repository at this point in the history
Support displaying location messages in a room's timeline
  • Loading branch information
kevinaboos authored Oct 10, 2024
2 parents bf752c4 + af46754 commit 5d8da58
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 70 additions & 6 deletions src/home/room_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use crate::{
};
use rangemap::RangeSet;

const GEO_URI_SCHEME: &str = "geo:";

live_design! {
import makepad_draw::shader::std::*;
import makepad_widgets::base::*;
Expand Down Expand Up @@ -886,15 +888,17 @@ live_design! {
// Below that, display a view that holds the message input bar and send button.
<View> {
width: Fill, height: Fit
flow: Right, align: {y: 1.0}, padding: 10.
flow: Right,
align: {y: 0.5},
padding: 10.
show_bg: true,
draw_bg: {
color: (COLOR_PRIMARY)
}

location_button = <IconButton> {
draw_icon: {svg_file: (ICO_LOCATION_PERSON)},
icon_walk: {width: 22.0, height: Fit, margin: {left: 0, right: 5, bottom: -5}},
icon_walk: {width: 22.0, height: Fit, margin: {left: 0, right: 5}},
text: "",
}

Expand Down Expand Up @@ -1289,7 +1293,7 @@ impl Widget for RoomScreen {
if self.button(id!(location_preview.send_location_button)).clicked(&actions) {
let location_preview = self.location_preview(id!(location_preview));
if let Some((coords, _system_time_opt)) = location_preview.get_current_data() {
let geo_uri = format!("geo:{},{}", coords.latitude, coords.longitude);
let geo_uri = format!("{}{},{}", GEO_URI_SCHEME, coords.latitude, coords.longitude);
let message = RoomMessageEventContent::new(
MessageType::Location(
LocationMessageEventContent::new(geo_uri.clone(), geo_uri)
Expand Down Expand Up @@ -2243,6 +2247,24 @@ fn populate_message_view(
(item, false)
}
}
MessageType::Location(location) => {
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 is_location_fully_drawn = populate_location_message_content(
&item.html_or_plaintext(id!(content.message)),
location,
);
new_drawn_status.content_drawn = is_location_fully_drawn;
(item, false)
}
}
other => {
let (item, existed) = list.item_with_existed(cx, item_id, live_id!(Message));
if existed && item_drawn_status.content_drawn {
Expand Down Expand Up @@ -2407,6 +2429,45 @@ fn populate_image_message_content(
}
}

/// Draws the given location message's content into the `message_content_widget`.
///
/// Returns whether the location message content was fully drawn.
fn populate_location_message_content(
message_content_widget: &HtmlOrPlaintextRef,
location: &LocationMessageEventContent,
) -> bool {
let coords = location.geo_uri
.get(GEO_URI_SCHEME.len() ..)
.and_then(|s| {
let mut iter = s.split(',');
if let (Some(lat), Some(long)) = (iter.next(), iter.next()) {
Some((lat, long))
} else {
None
}
});
if let Some((lat, long)) = coords {
let short_lat = lat.find('.').and_then(|dot| lat.get(..dot + 7)).unwrap_or(lat);
let short_long = long.find('.').and_then(|dot| long.get(..dot + 7)).unwrap_or(long);
let html_body = format!(
"Location: {short_lat},{short_long}\
<p><a href=\"https://www.openstreetmap.org/?mlat={lat}&amp;mlon={long}#map=15/{lat}/{long}\">Open in OpenStreetMap</a></p>\
<p><a href=\"https://www.google.com/maps/search/?api=1&amp;query={lat},{long}\">Open in Google Maps</a></p>\
<p><a href=\"https://maps.apple.com/?ll={lat},{long}&amp;q={lat},{long}\">Open in Apple Maps</a></p>",
);
message_content_widget.show_html(html_body);
} else {
message_content_widget.show_html(
format!("<i>[Location invalid]</i> {}", location.body)
);
}

// Currently we do not fetch location thumbnail previews, so we consider this as fully drawn.
// In the future, when we do support this, we'll return false until the thumbnail is fetched,
// at which point we can return true.
true
}

/// Draws a ReplyPreview above the given `message` if it was in-reply to another message.
///
/// If the given `message` was *not* in-reply to another message,
Expand Down Expand Up @@ -2916,9 +2977,12 @@ impl Widget for LocationPreview {

fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
let text = match self.coords {
Some(Ok(c)) => format!("Current location: {},{}\n Timestamp: {:?}",
c.latitude, c.longitude, self.timestamp,
),
Some(Ok(c)) => {
// format!("Current location: {},{}\n Timestamp: {:?}",
// c.latitude, c.longitude, self.timestamp,
// )
format!("Current location: {},{}", c.latitude, c.longitude)
}
Some(Err(e)) => format!("Error getting location: {e:?}"),
None => format!("Current location is not yet available."),
};
Expand Down

0 comments on commit 5d8da58

Please sign in to comment.