daydream

A small matrix web client written in rust
git clone git://archive.git.mtrnord.blog/daydream-mx/daydream.git
Log | Files | Refs | README | LICENSE

text.rs (3904B)


      1 use std::rc::Rc;
      2 
      3 use crate::app::components::events::{EventExt, RoomExt};
      4 use linkify::LinkFinder;
      5 use matrix_sdk::{
      6     events::{room::message::TextMessageEventContent, AnySyncMessageEvent},
      7     Room,
      8 };
      9 use web_sys::Node;
     10 use yew::prelude::*;
     11 use yew::virtual_dom::VNode;
     12 
     13 pub struct Text {
     14     props: Props,
     15 }
     16 
     17 #[derive(Clone, Properties, Debug)]
     18 pub struct Props {
     19     #[prop_or_default]
     20     pub prev_event: Option<AnySyncMessageEvent>,
     21     pub event: AnySyncMessageEvent,
     22     pub text_event: TextMessageEventContent,
     23     pub room: Rc<Room>,
     24 }
     25 
     26 impl Component for Text {
     27     type Message = ();
     28     type Properties = Props;
     29 
     30     fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
     31         Text { props }
     32     }
     33 
     34     fn update(&mut self, _msg: Self::Message) -> bool {
     35         false
     36     }
     37 
     38     fn change(&mut self, _props: Self::Properties) -> bool {
     39         // TODO fix the PartialEq hack
     40         /*if format!("{:?}", self.props) != format!("{:?}", props) {
     41             self.props = props;
     42             true
     43         } else {
     44             false
     45         }*/
     46         true
     47     }
     48 
     49     //noinspection RsTypeCheck
     50     fn view(&self) -> Html {
     51         let new_user = self.props.event.is_new_user(self.props.prev_event.as_ref());
     52         let sender_displayname = if new_user {
     53             self.props.room.get_sender_displayname(&self.props.event)
     54         } else {
     55             ""
     56         };
     57 
     58         let mut pure_content = self.props.text_event.body.clone();
     59         let finder = LinkFinder::new();
     60         let pure_content_clone = pure_content.clone();
     61         let links: Vec<_> = finder.links(&pure_content_clone).collect();
     62 
     63         let content = if !links.is_empty() {
     64             for link in links {
     65                 let html_link = format!("<a href={}>{}</a>", link.as_str(), link.as_str());
     66                 pure_content.replace_range(link.start()..link.end(), &html_link);
     67             }
     68             pure_content
     69         } else {
     70             pure_content
     71         };
     72 
     73         if let Some(formatted) = &self.props.text_event.formatted {
     74             let format_slot;
     75             let message = if new_user {
     76                 format_slot = format!(
     77                     "<displayname>{}:</displayname> {}",
     78                     sender_displayname, formatted.body
     79                 );
     80                 &format_slot
     81             } else {
     82                 &formatted.body
     83             };
     84             let js_text_event = {
     85                 let div = web_sys::window()
     86                     .unwrap()
     87                     .document()
     88                     .unwrap()
     89                     .create_element("p")
     90                     .unwrap();
     91                 div.set_inner_html(message.as_str());
     92                 div
     93             };
     94             let node = Node::from(js_text_event);
     95             VNode::VRef(node)
     96         } else if new_user {
     97             let full_html = format!(
     98                 "<p><displayname>{}: </displayname>{}</p>",
     99                 sender_displayname, content
    100             );
    101             let js_text_event = {
    102                 let div = web_sys::window()
    103                     .unwrap()
    104                     .document()
    105                     .unwrap()
    106                     .create_element("p")
    107                     .unwrap();
    108                 div.set_inner_html(full_html.as_str());
    109                 div
    110             };
    111             let node = Node::from(js_text_event);
    112             VNode::VRef(node)
    113         } else {
    114             let full_html = format!("<p>{}</p>", content);
    115             let js_text_event = {
    116                 let div = web_sys::window()
    117                     .unwrap()
    118                     .document()
    119                     .unwrap()
    120                     .create_element("p")
    121                     .unwrap();
    122                 div.set_inner_html(full_html.as_str());
    123                 div
    124             };
    125             let node = Node::from(js_text_event);
    126             VNode::VRef(node)
    127         }
    128     }
    129 }