Improved QR code view

- added backlink to pasta page
- added link on QR SVG to its destination
- 404 if incorrect id
- QR code of URL pasta will now redirect to /url endpoint
This commit is contained in:
Daniel Szabo 2022-11-07 20:28:45 +02:00
parent 5854572e87
commit c6e2b026e6
2 changed files with 73 additions and 15 deletions

View file

@ -1,5 +1,8 @@
use crate::args::{Args, ARGS}; use crate::args::{Args, ARGS};
use crate::endpoints::errors::ErrorTemplate;
use crate::pasta::Pasta; use crate::pasta::Pasta;
use crate::util::animalnumbers::to_u64;
use crate::util::hashids::to_u64 as hashid_to_u64;
use crate::util::misc::{self, remove_expired}; use crate::util::misc::{self, remove_expired};
use crate::AppState; use crate::AppState;
use actix_web::{get, web, HttpResponse}; use actix_web::{get, web, HttpResponse};
@ -11,24 +14,57 @@ use std::time::{SystemTime, UNIX_EPOCH};
#[template(path = "qr.html", escape = "none")] #[template(path = "qr.html", escape = "none")]
struct QRTemplate<'a> { struct QRTemplate<'a> {
qr: &'a String, qr: &'a String,
pasta: &'a Pasta,
args: &'a Args, args: &'a Args,
} }
#[get("/qr/{id}")] #[get("/qr/{id}")]
pub async fn getqr(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse { pub async fn getqr(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
// find the index of the pasta in the collection based on u64 id // get access to the pasta collection
let mut pastas = data.pastas.lock().unwrap();
let svg: String = misc::string_to_qr_svg( let u64_id = if ARGS.hash_ids {
format!("{}/pasta/{}", &ARGS.public_path, &*id.into_inner()).as_str(), hashid_to_u64(&id).unwrap_or(0)
); } else {
to_u64(&id).unwrap_or(0)
};
// remove expired pastas (including this one if needed)
remove_expired(&mut pastas);
// find the index of the pasta in the collection based on u64 id
let mut index: usize = 0;
let mut found: bool = false;
for (i, pasta) in pastas.iter().enumerate() {
if pasta.id == u64_id {
index = i;
found = true;
break;
}
}
if found {
// generate the QR code as an SVG - if its a file or text pastas, this will point to the /pasta endpoint, otherwise to the /url endpoint, essentially directly taking the user to the url stored in the pasta
let svg: String = match pastas[index].pasta_type.as_str() {
"url" => misc::string_to_qr_svg(format!("{}/url/{}", &ARGS.public_path, &id).as_str()),
_ => misc::string_to_qr_svg(format!("{}/pasta/{}", &ARGS.public_path, &id).as_str()),
};
// serve qr code in template // serve qr code in template
HttpResponse::Ok().content_type("text/html").body( return HttpResponse::Ok().content_type("text/html").body(
QRTemplate { QRTemplate {
qr: &svg, qr: &svg,
pasta: &pastas[index],
args: &ARGS, args: &ARGS,
} }
.render() .render()
.unwrap(), .unwrap(),
) );
}
// otherwise
// send pasta not found error
HttpResponse::Ok()
.content_type("text/html")
.body(ErrorTemplate { args: &ARGS }.render().unwrap())
} }

View file

@ -1,7 +1,29 @@
{% include "header.html" %} {% include "header.html" %}
<div style="text-align: center"> <div style="float: left">
{{qr}} <a href="{{ args.public_path }}/pasta/{{pasta.id_as_animals()}}">Back to Pasta</a>
</div> </div>
<div style="text-align: center; padding: 3rem;">
{% if pasta.pasta_type == "url" %}
<a href="{{ args.public_path }}/url/{{pasta.id_as_animals()}}">
{{qr}}
</a>
{% else %}
<a href="{{ args.public_path }}/pasta/{{pasta.id_as_animals()}}">
{{qr}}
</a>
{% endif %}
</div>
<style>
.copy-text-button,
.copy-url-button {
font-size: small;
padding: 4px;
width: 6rem;
}
</style>
{% include "footer.html" %} {% include "footer.html" %}