Skip to content

Commit 9cbe01c

Browse files
committed
chore: embedding external media improvements
1 parent eae8c39 commit 9cbe01c

File tree

1 file changed

+107
-80
lines changed

1 file changed

+107
-80
lines changed

crates/rostra-web-ui/src/routes/content.rs

Lines changed: 107 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -30,96 +30,123 @@ impl UiState {
3030

3131
let mut in_profile_link = vec![];
3232
let mut in_img_to_raw_html = vec![];
33-
let out = jotdown::html::render_to_string(sanitized.flat_map(|event| match event {
34-
Event::Start(Container::Link(s, jotdown::LinkType::AutoLink), attr) => {
35-
if let Some(rostra_id) = Self::extra_rostra_id_link(&s) {
36-
// TODO: blocked on https://github.com/hellux/jotdown/issues/86
37-
// let x = client
38-
// .db()
39-
// .get_social_profile(rostra_id)
40-
// .await
41-
// .map(|record| record.display_name)
42-
// .unwrap_or_else(|| rostra_id.to_string());
43-
in_profile_link.push(rostra_id);
44-
vec![Event::Start(
45-
Container::Link(
33+
let mut in_img_to_img = vec![];
34+
let out = jotdown::html::render_to_string(sanitized.flat_map(|event| {
35+
match event {
36+
Event::Start(Container::Link(s, jotdown::LinkType::AutoLink), attr) => {
37+
if let Some(rostra_id) = Self::extra_rostra_id_link(&s) {
38+
// TODO: blocked on https://github.com/hellux/jotdown/issues/86
39+
// let x = client
40+
// .db()
41+
// .get_social_profile(rostra_id)
42+
// .await
43+
// .map(|record| record.display_name)
44+
// .unwrap_or_else(|| rostra_id.to_string());
45+
in_profile_link.push(rostra_id);
46+
vec![Event::Start(
47+
Container::Link(
48+
format!("/ui/profile/{rostra_id}").into(),
49+
jotdown::LinkType::Span(jotdown::SpanLinkType::Inline),
50+
),
51+
attr,
52+
)]
53+
} else {
54+
vec![Event::Start(
55+
Container::Link(s, jotdown::LinkType::AutoLink),
56+
attr,
57+
)]
58+
}
59+
}
60+
Event::End(Container::Link(s, jotdown::LinkType::AutoLink)) => {
61+
if let Some(rostra_id) = Self::extra_rostra_id_link(&s) {
62+
in_profile_link.pop();
63+
vec![Event::End(Container::Link(
4664
format!("/ui/profile/{rostra_id}").into(),
4765
jotdown::LinkType::Span(jotdown::SpanLinkType::Inline),
48-
),
49-
attr,
50-
)]
51-
} else {
52-
vec![Event::Start(
53-
Container::Link(s, jotdown::LinkType::AutoLink),
54-
attr,
55-
)]
56-
}
57-
}
58-
Event::End(Container::Link(s, jotdown::LinkType::AutoLink)) => {
59-
if let Some(rostra_id) = Self::extra_rostra_id_link(&s) {
60-
in_profile_link.pop();
61-
vec![Event::End(Container::Link(
62-
format!("/ui/profile/{rostra_id}").into(),
63-
jotdown::LinkType::Span(jotdown::SpanLinkType::Inline),
64-
))]
65-
} else {
66-
vec![Event::End(Container::Link(s, jotdown::LinkType::AutoLink))]
66+
))]
67+
} else {
68+
vec![Event::End(Container::Link(s, jotdown::LinkType::AutoLink))]
69+
}
6770
}
68-
}
69-
Event::Start(Container::Image(s, link_type), _attr) => {
70-
let load_msg = format!("Load: {}", s).into();
71-
let img_events = if let Some(html) = maybe_embed_media_html(&s) {
72-
in_img_to_raw_html.push(html.clone());
73-
74-
vec![
75-
Event::Start(
76-
Container::RawInline { format: "html" },
77-
Attributes::try_from("{ loading=lazy }").expect("Can't fail"),
78-
),
79-
Event::Str(html.into()),
80-
]
81-
} else {
71+
Event::Start(Container::Image(s, _link_type), _attr) => {
72+
if let Some(html) = maybe_embed_media_html(&s) {
73+
in_img_to_raw_html.push((html, String::new()));
74+
} else {
75+
in_img_to_img.push(String::new());
76+
};
8277
vec![Event::Start(
83-
Container::Image(s, link_type),
84-
Attributes::try_from("{ loading=lazy }").expect("Can't fail"),
78+
Container::Div {
79+
class: "lazyload-wrapper",
80+
},
81+
jotdown::Attributes::try_from(
82+
"{ onclick=\"this.classList.add('-expanded')\" }",
83+
)
84+
.expect("Can't fail"),
8585
)]
86-
};
87-
[
88-
vec![
89-
Event::Start(
90-
Container::Div {
91-
class: "lazyload-wrapper",
92-
},
93-
jotdown::Attributes::try_from(
94-
"{ onclick=\"this.classList.toggle('-expanded')\" }",
95-
)
96-
.expect("Can't fail"),
97-
),
98-
Event::Start(Container::Paragraph, Attributes::new()),
99-
Event::Str(load_msg),
100-
Event::End(Container::Paragraph),
101-
],
102-
img_events,
103-
]
104-
.concat()
105-
}
106-
Event::End(Container::Image(s, link_type)) => {
107-
vec![
108-
if let Some(_html) = in_img_to_raw_html.pop() {
109-
Event::End(Container::RawInline { format: "html" })
86+
}
87+
Event::End(Container::Image(s, link_type)) => [
88+
if let Some((html, alt)) = in_img_to_raw_html.pop() {
89+
let alt = alt.trim();
90+
let load_msg = if alt.is_empty() {
91+
format!("Load: {}", s).into()
92+
} else {
93+
format!("Load “{}”: {}", alt, s).into()
94+
};
95+
vec![
96+
Event::Start(Container::Paragraph, Attributes::new()),
97+
Event::Str(load_msg),
98+
Event::End(Container::Paragraph),
99+
Event::Start(
100+
Container::RawInline { format: "html" },
101+
Attributes::try_from("{ loading=lazy }").expect("Can't fail"),
102+
),
103+
Event::Str(html.into()),
104+
Event::End(Container::RawInline { format: "html" }),
105+
]
106+
} else if let Some(alt) = in_img_to_img.pop() {
107+
let alt = alt.trim();
108+
let load_msg = if alt.is_empty() {
109+
format!("Load: {}", s).into()
110+
} else {
111+
format!("Load “{}”: {}", alt, s).into()
112+
};
113+
vec![
114+
Event::Start(Container::Paragraph, Attributes::new()),
115+
Event::Str(load_msg),
116+
Event::End(Container::Paragraph),
117+
Event::Start(
118+
Container::Image(s.clone(), link_type),
119+
Attributes::try_from("{ loading=lazy }").expect("Can't fail"),
120+
),
121+
Event::Str(alt.to_string().into()),
122+
Event::End(Container::Image(s, link_type)),
123+
]
110124
} else {
111-
Event::End(Container::Image(s, link_type))
125+
panic!("Can't be here")
112126
},
113-
Event::End(Container::Div {
127+
vec![Event::End(Container::Div {
114128
class: "img-wrapper",
115-
}),
129+
})],
116130
]
131+
.concat(),
132+
Event::Str(s) => {
133+
if !in_profile_link.is_empty() {
134+
let profile = in_profile_link.last().expect("Not empty just checked");
135+
vec![Event::Str(format!("@{profile}").into())]
136+
} else if let Some(last) = in_img_to_raw_html.last_mut() {
137+
last.1 = s.to_string();
138+
// skip the img alt tag
139+
vec![]
140+
} else if let Some(last) = in_img_to_img.last_mut() {
141+
*last = s.to_string();
142+
// skip the img alt tag
143+
vec![]
144+
} else {
145+
vec![Event::Str(s)]
146+
}
147+
}
148+
event => vec![event],
117149
}
118-
Event::Str(_s) if !in_profile_link.is_empty() => {
119-
let profile = in_profile_link.last().expect("Not empty just checked");
120-
vec![Event::Str(format!("@{profile}").into())]
121-
}
122-
event => vec![event],
123150
}));
124151

125152
PreEscaped(out)

0 commit comments

Comments
 (0)