Skip to content

mentions: Add initial support for sending mentions

enterprisey requested to merge enterprisey/fractal:send-mentions into fractal-next

A Pill in the message field will now result in a ping. There is currently no way to add a Pill; you'll have to hack one in.

I still think doing this with text tags might be a better idea, but I agree that this looks better. It would be pretty easy to switch.

How to test this: you'll have to hack the Pills in yourself. Here's how I did it:

  1. In RoomHistory::constructed, where we register the key listener for the message sending field, add a new handler with whatever key combination you like (I used the exclamation point because I'm not a very emotive person, so that'll be else if key == gdk::keys::constants::exclam. It will call a new function on RoomHistory. I called mine asdf. So the full new set of lines looked like this:
    } else if key == gdk::keys::constants::exclam {
        obj.asdf();
        Inhibit(true)
  2. In RoomHistory, add the new function. I made mine take the current text of the message field as the user ID:
    fn asdf(&self) {
        let priv_ = imp::RoomHistory::from_instance(self);
        let buffer = priv_.message_entry.buffer();
        let (start_iter, end_iter) = buffer.bounds();
        let text = buffer.text(&start_iter, &end_iter, true);
        let text = text.as_str().to_string();
        use std::convert::TryFrom;
        match matrix_sdk::ruma::identifiers::UserId::try_from(text) {
            Ok(user_id) => {
                let pill = crate::components::Pill::new();
                let user = self
                    .room()
                    .unwrap()
                    .members()
                    .member_by_id(&user_id)
                    .upcast::<crate::session::User>();
                pill.set_user(Some(user));
                let buf = priv_.message_entry.buffer();
    
                buf.set_text("");
                priv_
                    .message_entry
                    .add_child_at_anchor(&pill, &buf.create_child_anchor(&mut buf.end_iter()));
            }
            Err(e) => {
                println!("{}", e);
            }
        }
    }

Then while using Fractal, write the user ID you're pinging in the message field, type the key combination you specified, and the field will be cleared and replaced with a ping. The ping should show the correct avatar, but will not show the correct display name (I have no idea why that happens).

The approach is sort of rough: checking for 0xFFFC works, but if the user decides to send a message containing that code point with mentions that occur after that code point, the mentions will instead appear where the earlier 0xFFFC was, not where intended. I doubt it's worth it to support this use case. If we wanted to fix it, we could keep track of all the anchors in the RoomHistory.

...there's a lot of stuff related to message sending in RoomHistory... it might be worth it to move it out at some point.

Dubious division of labor here, I guess (i.e. all this stuff could probably be in the same function, without having to pass mentions around), but I had to put the mentions in after markdown was processed, and I didn't want to mess with that too much.

add_mentions_to_message could've been a lambda, I guess... I have no preference either way.

Interesting little issue with spaces and pings. In element web, if you send a ping, there will generally be a space before the ping in your message (otherwise the @ to start the ping wouldn't be recognized) and element web will automatically insert a space afterwards. Removing either of these spaces will disable the ping! This seems wrong to me, but I don't know if we should do something different. This patch follows Element Web's behavior: if you add a Pill without spaces on either side, sometimes (for example, with letters on either side, so that they merge into the display name when converted to plain text), the mention will correctly render (on Element Web), but won't cause a ping to go through. This might just be an Element Web bug.

This is the second MR for #766 (closed).

Edited by enterprisey

Merge request reports