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 }