Basic gallery support (#103)
This commit is contained in:
parent
2a475d127a
commit
cf45d53fdd
@ -72,7 +72,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
|
|||||||
let ratio: f64 = post["data"]["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0;
|
let ratio: f64 = post["data"]["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0;
|
||||||
|
|
||||||
// Determine the type of media along with the media URL
|
// Determine the type of media along with the media URL
|
||||||
let (post_type, media) = media(&post["data"]).await;
|
let (post_type, media, gallery) = media(&post["data"]).await;
|
||||||
|
|
||||||
// Build a post using data parsed from Reddit post API
|
// Build a post using data parsed from Reddit post API
|
||||||
Post {
|
Post {
|
||||||
@ -124,6 +124,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
|
|||||||
rel_time,
|
rel_time,
|
||||||
created,
|
created,
|
||||||
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
|
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
|
||||||
|
gallery,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
src/utils.rs
35
src/utils.rs
@ -46,6 +46,14 @@ pub struct Media {
|
|||||||
pub height: i64,
|
pub height: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GalleryMedia {
|
||||||
|
pub url: String,
|
||||||
|
pub width: i64,
|
||||||
|
pub height: i64,
|
||||||
|
pub caption: String,
|
||||||
|
pub outbound_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
// Post containing content, metadata and media
|
// Post containing content, metadata and media
|
||||||
pub struct Post {
|
pub struct Post {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
@ -65,6 +73,7 @@ pub struct Post {
|
|||||||
pub rel_time: String,
|
pub rel_time: String,
|
||||||
pub created: String,
|
pub created: String,
|
||||||
pub comments: String,
|
pub comments: String,
|
||||||
|
pub gallery: Vec<GalleryMedia>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comment with content, post, score and data/time that it was posted
|
// Comment with content, post, score and data/time that it was posted
|
||||||
@ -188,8 +197,9 @@ pub fn format_num(num: i64) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn media(data: &Value) -> (String, Media) {
|
pub async fn media(data: &Value) -> (String, Media, Vec<GalleryMedia>) {
|
||||||
let post_type: &str;
|
let post_type: &str;
|
||||||
|
let mut gallery = Vec::new();
|
||||||
// If post is a video, return the video
|
// If post is a video, return the video
|
||||||
let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() {
|
let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() {
|
||||||
post_type = "video";
|
post_type = "video";
|
||||||
@ -215,6 +225,25 @@ pub async fn media(data: &Value) -> (String, Media) {
|
|||||||
} else if data["is_self"].as_bool().unwrap_or_default() {
|
} else if data["is_self"].as_bool().unwrap_or_default() {
|
||||||
post_type = "self";
|
post_type = "self";
|
||||||
data["permalink"].as_str().unwrap_or_default().to_string()
|
data["permalink"].as_str().unwrap_or_default().to_string()
|
||||||
|
} else if data["is_gallery"].as_bool().unwrap_or_default() {
|
||||||
|
post_type = "gallery";
|
||||||
|
gallery = data["gallery_data"]["items"]
|
||||||
|
.as_array()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(|item| {
|
||||||
|
let media_id = item["media_id"].as_str().unwrap_or_default();
|
||||||
|
let image = data["media_metadata"][media_id].as_object().unwrap();
|
||||||
|
GalleryMedia {
|
||||||
|
url: format_url(image["s"]["u"].as_str().unwrap_or_default()),
|
||||||
|
width: image["s"]["x"].as_i64().unwrap_or_default(),
|
||||||
|
height: image["s"]["y"].as_i64().unwrap_or_default(),
|
||||||
|
caption: item["caption"].as_str().unwrap_or_default().to_string(),
|
||||||
|
outbound_url: item["outbound_url"].as_str().unwrap_or_default().to_string(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<GalleryMedia>>();
|
||||||
|
data["url"].as_str().unwrap_or_default().to_string()
|
||||||
} else {
|
} else {
|
||||||
post_type = "link";
|
post_type = "link";
|
||||||
data["url"].as_str().unwrap_or_default().to_string()
|
data["url"].as_str().unwrap_or_default().to_string()
|
||||||
@ -227,6 +256,7 @@ pub async fn media(data: &Value) -> (String, Media) {
|
|||||||
width: data["preview"]["images"][0]["source"]["width"].as_i64().unwrap_or_default(),
|
width: data["preview"]["images"][0]["source"]["width"].as_i64().unwrap_or_default(),
|
||||||
height: data["preview"]["images"][0]["source"]["height"].as_i64().unwrap_or_default(),
|
height: data["preview"]["images"][0]["source"]["height"].as_i64().unwrap_or_default(),
|
||||||
},
|
},
|
||||||
|
gallery,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +353,7 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
|
|||||||
let title = val(post, "title");
|
let title = val(post, "title");
|
||||||
|
|
||||||
// Determine the type of media along with the media URL
|
// Determine the type of media along with the media URL
|
||||||
let (post_type, media) = media(&post["data"]).await;
|
let (post_type, media, gallery) = media(&post["data"]).await;
|
||||||
|
|
||||||
posts.push(Post {
|
posts.push(Post {
|
||||||
id: val(post, "id"),
|
id: val(post, "id"),
|
||||||
@ -378,6 +408,7 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
|
|||||||
rel_time,
|
rel_time,
|
||||||
created,
|
created,
|
||||||
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
|
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
|
||||||
|
gallery,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +637,7 @@ a.search_subreddit:hover {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post_media_image, .post .__NoScript_PlaceHolder__, .post_media_video {
|
.post_media_image, .post .__NoScript_PlaceHolder__, .post_media_video, .gallery {
|
||||||
max-width: calc(100% - 40px);
|
max-width: calc(100% - 40px);
|
||||||
grid-area: post_media;
|
grid-area: post_media;
|
||||||
margin: 15px auto 5px auto;
|
margin: 15px auto 5px auto;
|
||||||
@ -664,6 +664,24 @@ a.search_subreddit:hover {
|
|||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gallery img {
|
||||||
|
max-width: 100%;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery figcaption {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .outbound_url {
|
||||||
|
color: var(--accent);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: block;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#post_url {
|
#post_url {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
margin: 5px 20px;
|
margin: 5px 20px;
|
||||||
|
@ -78,6 +78,20 @@
|
|||||||
</a>
|
</a>
|
||||||
{% else if post.post_type == "video" || post.post_type == "gif" %}
|
{% else if post.post_type == "video" || post.post_type == "gif" %}
|
||||||
<video class="post_media_video" src="{{ post.media.url }}" controls autoplay loop></video>
|
<video class="post_media_video" src="{{ post.media.url }}" controls autoplay loop></video>
|
||||||
|
{% else if post.post_type == "gallery" %}
|
||||||
|
<div class="gallery">
|
||||||
|
{% for image in post.gallery -%}
|
||||||
|
<figure>
|
||||||
|
<a href="{{ image.url }}" ><img alt="Gallery image" src="{{ image.url }}"/></a>
|
||||||
|
<figcaption>
|
||||||
|
<p>{{ image.caption }}</p>
|
||||||
|
{% if image.outbound_url.len() > 0 %}
|
||||||
|
<p><a class="outbound_url" href="{{ image.outbound_url }}">{{ image.outbound_url }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
{%- endfor %}
|
||||||
|
</div>
|
||||||
{% else if post.post_type == "link" %}
|
{% else if post.post_type == "link" %}
|
||||||
<a id="post_url" href="{{ post.media.url }}">{{ post.media.url }}</a>
|
<a id="post_url" href="{{ post.media.url }}">{{ post.media.url }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
Loading…
Reference in New Issue
Block a user