forked from alemi/upub
feat(web): show audio, video and generic attachments
not only images anymore!!!
This commit is contained in:
parent
0e30d98c32
commit
9faae6f627
2 changed files with 85 additions and 17 deletions
|
@ -154,23 +154,37 @@
|
||||||
img.inline-avatar {
|
img.inline-avatar {
|
||||||
max-height: 2em;
|
max-height: 2em;
|
||||||
}
|
}
|
||||||
|
p.box {
|
||||||
|
border: 3px solid #bf616a;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
p.cursor {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
video.attachment {
|
||||||
|
height: 10em;
|
||||||
|
}
|
||||||
img.attachment {
|
img.attachment {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 10em;
|
height: 10em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 5px solid #bf616a;
|
border: 3px solid #bf616a;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
img.expand {
|
img.expand,
|
||||||
|
video.expand {
|
||||||
height: unset;
|
height: unset;
|
||||||
max-height: 50vh;
|
max-height: 55vh;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
div.tl-header {
|
div.tl-header {
|
||||||
background-color: #bf616a55;
|
background-color: #bf616a55;
|
||||||
color: #bf616a;
|
color: #bf616a;
|
||||||
}
|
}
|
||||||
|
p.tiny-text {
|
||||||
|
line-height: .75em;
|
||||||
|
}
|
||||||
table.post-table {
|
table.post-table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,25 @@ use crate::{prelude::*, URL_SENSITIVE};
|
||||||
|
|
||||||
use apb::{target::Addressed, Base, Object};
|
use apb::{target::Addressed, Base, Object};
|
||||||
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Object(object: serde_json::Value) -> impl IntoView {
|
pub fn Attachment(
|
||||||
let uid = object.id().unwrap_or_default().to_string();
|
object: serde_json::Value,
|
||||||
let content = dissolve::strip_html_tags(object.content().unwrap_or_default());
|
#[prop(optional)]
|
||||||
let author_id = object.attributed_to().id().unwrap_or_default();
|
sensitive: bool
|
||||||
let author = CACHE.get_or(&author_id, serde_json::Value::String(author_id.clone()));
|
) -> impl IntoView {
|
||||||
let sensitive = object.sensitive().unwrap_or_default();
|
|
||||||
let attachments = object.attachment()
|
|
||||||
.map(|x| {
|
|
||||||
let (expand, set_expand) = create_signal(false);
|
let (expand, set_expand) = create_signal(false);
|
||||||
let href = x.url().id().unwrap_or_default();
|
let href = object.url().id().unwrap_or_default();
|
||||||
|
let media_type = object.media_type()
|
||||||
|
.unwrap_or("image/png") // TODO weird defaulting to png?????
|
||||||
|
.to_string();
|
||||||
|
let kind = media_type
|
||||||
|
.split('/')
|
||||||
|
.next()
|
||||||
|
.unwrap_or("image")
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
match kind.as_str() {
|
||||||
|
"image" =>
|
||||||
view! {
|
view! {
|
||||||
<p class="center">
|
<p class="center">
|
||||||
<img
|
<img
|
||||||
|
@ -25,12 +32,59 @@ pub fn Object(object: serde_json::Value) -> impl IntoView {
|
||||||
} else {
|
} else {
|
||||||
href.clone()
|
href.clone()
|
||||||
}}
|
}}
|
||||||
title={x.name().unwrap_or_default().to_string()}
|
title={object.name().unwrap_or_default().to_string()}
|
||||||
on:click=move |_| set_expand.set(!expand.get())
|
on:click=move |_| set_expand.set(!expand.get())
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
}.into_view(),
|
||||||
|
|
||||||
|
"video" =>
|
||||||
|
view! {
|
||||||
|
<p class="center cursor box ml-1"
|
||||||
|
on:click=move |_| set_expand.set(!expand.get())
|
||||||
|
title={object.name().unwrap_or_default().to_string()}
|
||||||
|
>
|
||||||
|
<video controls loop class="attachment" class:expand=expand >
|
||||||
|
<source src={href.clone()} type={media_type} />
|
||||||
|
<a href={href} target="_blank">audio clip</a>
|
||||||
|
</video>
|
||||||
|
</p>
|
||||||
|
}.into_view(),
|
||||||
|
|
||||||
|
"audio" =>
|
||||||
|
view! {
|
||||||
|
<p class="center">
|
||||||
|
<audio controls class="w-100">
|
||||||
|
<source src={href.clone()} type={media_type} />
|
||||||
|
<a href={href} target="_blank">audio clip</a>
|
||||||
|
</audio>
|
||||||
|
</p>
|
||||||
|
}.into_view(),
|
||||||
|
|
||||||
|
_ =>
|
||||||
|
view! {
|
||||||
|
<p class="center box">
|
||||||
|
<code class="cw color center">
|
||||||
|
<a href={href} target="_blank">{media_type}</a>
|
||||||
|
</code>
|
||||||
|
<p class="tiny-text">
|
||||||
|
<small>{object.name().unwrap_or_default().to_string()}</small>
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
}.into_view(),
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Object(object: serde_json::Value) -> impl IntoView {
|
||||||
|
let uid = object.id().unwrap_or_default().to_string();
|
||||||
|
let content = dissolve::strip_html_tags(object.content().unwrap_or_default());
|
||||||
|
let author_id = object.attributed_to().id().unwrap_or_default();
|
||||||
|
let author = CACHE.get_or(&author_id, serde_json::Value::String(author_id.clone()));
|
||||||
|
let sensitive = object.sensitive().unwrap_or_default();
|
||||||
|
let attachments = object.attachment()
|
||||||
|
.map(|x| view! { <Attachment object=x sensitive=sensitive /> })
|
||||||
.collect_view();
|
.collect_view();
|
||||||
let attachments_padding = if object.attachment().is_empty() {
|
let attachments_padding = if object.attachment().is_empty() {
|
||||||
None
|
None
|
||||||
|
|
Loading…
Reference in a new issue