Add video playback support, fix upload page on small screens
This commit is contained in:
parent
13dc22d79f
commit
cc744eafa1
|
@ -15,15 +15,15 @@ ul {
|
||||||
.imagebox {
|
.imagebox {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
max-height: 400px;
|
|
||||||
|
|
||||||
img {
|
img,
|
||||||
max-width: 400px;
|
video {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img,
|
||||||
|
video {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
border: 1px solid #e5e5e5;
|
border: 1px solid #e5e5e5;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
53
src/main.rs
53
src/main.rs
|
@ -60,6 +60,13 @@ impl Config {
|
||||||
url.to_string()
|
url.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn upstream_details_url(&self, name: &str) -> String {
|
||||||
|
let mut url = self.upstream.clone();
|
||||||
|
url.set_path(&format!("image/details/original/{}", name));
|
||||||
|
|
||||||
|
url.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn upstream_image_url(&self, name: &str) -> String {
|
fn upstream_image_url(&self, name: &str) -> String {
|
||||||
let mut url = self.upstream.clone();
|
let mut url = self.upstream.clone();
|
||||||
url.set_path(&format!("image/original/{}", name));
|
url.set_path(&format!("image/original/{}", name));
|
||||||
|
@ -179,10 +186,16 @@ impl Images {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
pub struct Details {
|
||||||
|
content_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
file: String,
|
file: String,
|
||||||
delete_token: String,
|
delete_token: String,
|
||||||
|
details: Details,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
|
@ -190,6 +203,14 @@ impl Image {
|
||||||
&self.file
|
&self.file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_video(&self) -> bool {
|
||||||
|
self.details.content_type.starts_with("video")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mime(&self) -> &str {
|
||||||
|
&self.details.content_type
|
||||||
|
}
|
||||||
|
|
||||||
fn link(&self) -> String {
|
fn link(&self) -> String {
|
||||||
CONFIG.image_url(&self.file)
|
CONFIG.image_url(&self.file)
|
||||||
}
|
}
|
||||||
|
@ -298,16 +319,19 @@ async fn thumbs(
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let file = query.into_inner().image;
|
let file = query.into_inner().image;
|
||||||
|
|
||||||
let url = CONFIG.upstream_image_url(&file);
|
let url = CONFIG.upstream_details_url(&file);
|
||||||
let res = client.get(url).send().await?;
|
let mut res = client.get(url).send().await?;
|
||||||
|
|
||||||
if res.status() == StatusCode::NOT_FOUND {
|
if res.status() == StatusCode::NOT_FOUND {
|
||||||
return Ok(to_404());
|
return Ok(to_404());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let details: Details = res.json().await?;
|
||||||
|
|
||||||
let image = Image {
|
let image = Image {
|
||||||
file,
|
file,
|
||||||
delete_token: String::new(),
|
delete_token: String::new(),
|
||||||
|
details,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cursor = Cursor::new(vec![]);
|
let mut cursor = Cursor::new(vec![]);
|
||||||
|
@ -351,16 +375,19 @@ async fn view_original(
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let file = file.into_inner();
|
let file = file.into_inner();
|
||||||
|
|
||||||
let url = CONFIG.upstream_image_url(&file);
|
let url = CONFIG.upstream_details_url(&file);
|
||||||
let res = client.get(url).send().await?;
|
let mut res = client.get(url).send().await?;
|
||||||
|
|
||||||
if res.status() == StatusCode::NOT_FOUND {
|
if res.status() == StatusCode::NOT_FOUND {
|
||||||
return Ok(to_404());
|
return Ok(to_404());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let details: Details = res.json().await?;
|
||||||
|
|
||||||
let image = Image {
|
let image = Image {
|
||||||
file,
|
file,
|
||||||
delete_token: String::new(),
|
delete_token: String::new(),
|
||||||
|
details,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cursor = Cursor::new(vec![]);
|
let mut cursor = Cursor::new(vec![]);
|
||||||
|
@ -381,16 +408,19 @@ async fn view(
|
||||||
return Ok(to_404());
|
return Ok(to_404());
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = CONFIG.upstream_image_url(&file);
|
let url = CONFIG.upstream_details_url(&file);
|
||||||
let res = client.get(url).send().await?;
|
let mut res = client.get(url).send().await?;
|
||||||
|
|
||||||
if res.status() == StatusCode::NOT_FOUND {
|
if res.status() == StatusCode::NOT_FOUND {
|
||||||
return Ok(to_404());
|
return Ok(to_404());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let details: Details = res.json().await?;
|
||||||
|
|
||||||
let image = Image {
|
let image = Image {
|
||||||
file,
|
file,
|
||||||
delete_token: String::new(),
|
delete_token: String::new(),
|
||||||
|
details,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cursor = Cursor::new(vec![]);
|
let mut cursor = Cursor::new(vec![]);
|
||||||
|
@ -468,8 +498,8 @@ async fn delete(
|
||||||
confirm,
|
confirm,
|
||||||
} = query.into_inner();
|
} = query.into_inner();
|
||||||
|
|
||||||
let url = CONFIG.upstream_image_url(&file);
|
let url = CONFIG.upstream_details_url(&file);
|
||||||
let res = client.get(url).send().await?;
|
let mut res = client.get(url).send().await?;
|
||||||
|
|
||||||
if res.status() == StatusCode::NOT_FOUND {
|
if res.status() == StatusCode::NOT_FOUND {
|
||||||
return Ok(to_404());
|
return Ok(to_404());
|
||||||
|
@ -482,11 +512,14 @@ async fn delete(
|
||||||
|
|
||||||
self::templates::deleted(&mut cursor, &file)?;
|
self::templates::deleted(&mut cursor, &file)?;
|
||||||
} else {
|
} else {
|
||||||
|
let details: Details = res.json().await?;
|
||||||
|
|
||||||
self::templates::confirm_delete(
|
self::templates::confirm_delete(
|
||||||
&mut cursor,
|
&mut cursor,
|
||||||
&Image {
|
&Image {
|
||||||
file,
|
file,
|
||||||
delete_token: token,
|
delete_token: token,
|
||||||
|
details,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +540,9 @@ async fn not_found() -> Result<HttpResponse, Error> {
|
||||||
|
|
||||||
self::templates::not_found(&mut cursor)?;
|
self::templates::not_found(&mut cursor)?;
|
||||||
|
|
||||||
Ok(HttpResponse::NotFound().body(cursor.into_inner()))
|
Ok(HttpResponse::NotFound()
|
||||||
|
.content_type(mime::TEXT_HTML.essence_str())
|
||||||
|
.body(cursor.into_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn go_home() -> HttpResponse {
|
async fn go_home() -> HttpResponse {
|
||||||
|
|
|
@ -25,8 +25,22 @@
|
||||||
</picture>
|
</picture>
|
||||||
<p><a href="@image.thumb(size, FileType::Jpg)">Direct Link</a></p>
|
<p><a href="@image.thumb(size, FileType::Jpg)">Direct Link</a></p>
|
||||||
} else {
|
} else {
|
||||||
<img src="@image.link()" alt="@image.filename()" title="@image.filename()" />
|
@if image.is_video() {
|
||||||
<p><a href="@image.link()">Direct Link</a></p>
|
<video
|
||||||
|
src="@image.link()"
|
||||||
|
alt="@image.filename()"
|
||||||
|
title="@image.filename()"
|
||||||
|
type="@image.mime()"
|
||||||
|
autoplay
|
||||||
|
muted
|
||||||
|
loop
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<p><a href="@image.link()">Direct Link</a></p>
|
||||||
|
} else {
|
||||||
|
<img src="@image.link()" alt="@image.filename()" title="@image.filename()" />
|
||||||
|
<p><a href="@image.link()">Direct Link</a></p>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
Loading…
Reference in a new issue