Depend less on yew for rendering

This commit is contained in:
Edward Shen 2021-10-24 11:40:19 -07:00
parent c12526abc0
commit 95e15b81b7
Signed by: edward
GPG key ID: 19182661E818369F
7 changed files with 186 additions and 51 deletions

5
.gitignore vendored
View file

@ -1,4 +1,5 @@
/target **/target
**/database **/database
/web/dist/ **/dist/
**/node_modules **/node_modules
test.*

61
Cargo.lock generated
View file

@ -197,6 +197,12 @@ dependencies = [
"utf8-width", "utf8-width",
] ]
[[package]]
name = "bytecount"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.7.2" version = "1.7.2"
@ -450,6 +456,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "fixedbitset"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e"
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -989,6 +1001,12 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "minimal-lexical"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.3.7" version = "0.3.7"
@ -1053,6 +1071,17 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "nom"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1"
dependencies = [
"memchr",
"minimal-lexical",
"version_check",
]
[[package]] [[package]]
name = "ntapi" name = "ntapi"
version = "0.3.6" version = "0.3.6"
@ -1174,6 +1203,7 @@ dependencies = [
"js-sys", "js-sys",
"omegaupload-common", "omegaupload-common",
"reqwasm", "reqwasm",
"tree_magic_mini",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
@ -1212,6 +1242,16 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "petgraph"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.0.8" version = "1.0.8"
@ -1969,6 +2009,27 @@ dependencies = [
"tracing-serde", "tracing-serde",
] ]
[[package]]
name = "tree_magic_db"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e73fc24a5427b3b15e2b0bcad8ef61b5affb1da8ac89c8bf3f196c8692d57f02"
[[package]]
name = "tree_magic_mini"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a7581560dc616314f7d73e81419c783d93a92e7fc7331b3041ff57bab240ea6"
dependencies = [
"bytecount",
"fnv",
"lazy_static",
"nom 7.0.0",
"once_cell",
"petgraph",
"tree_magic_db",
]
[[package]] [[package]]
name = "try-lock" name = "try-lock"
version = "0.2.3" version = "0.2.3"

View file

@ -17,6 +17,7 @@ http = "0.2"
image = "0.23" image = "0.23"
js-sys = "0.3" js-sys = "0.3"
reqwasm = "0.2" reqwasm = "0.2"
tree_magic_mini = { version = "3", features = ["with-gpl-data"] }
wasm-bindgen = "0.2" wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4" wasm-bindgen-futures = "0.4"
yew = { version = "0.18", features = ["wasm-bindgen-futures"] } yew = { version = "0.18", features = ["wasm-bindgen-futures"] }

View file

@ -8,7 +8,14 @@ use omegaupload_common::crypto::{open_in_place, Key, Nonce};
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use web_sys::Blob; use web_sys::Blob;
use crate::DecryptedData; #[derive(Clone)]
pub enum DecryptedData {
String(Arc<String>),
Blob(Arc<Blob>),
Image(Arc<Blob>, (u32, u32), usize),
Audio(Arc<Blob>),
Video(Arc<Blob>),
}
pub fn decrypt( pub fn decrypt(
mut container: Vec<u8>, mut container: Vec<u8>,
@ -49,7 +56,15 @@ pub fn decrypt(
container.len(), container.len(),
)) ))
} else { } else {
Ok(DecryptedData::Blob(blob)) let mime_type = tree_magic_mini::from_u8(&container);
log!(mime_type);
if mime_type.starts_with("audio/") {
Ok(DecryptedData::Audio(blob))
} else if mime_type.starts_with("video/") || mime_type.ends_with("x-matroska") {
Ok(DecryptedData::Video(blob))
} else {
Ok(DecryptedData::Blob(blob))
}
} }
} }
} }

View file

@ -5,6 +5,7 @@ use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use byte_unit::Byte; use byte_unit::Byte;
use decrypt::DecryptedData;
use gloo_console::log; use gloo_console::log;
use http::header::EXPIRES; use http::header::EXPIRES;
use http::uri::PathAndQuery; use http::uri::PathAndQuery;
@ -229,6 +230,38 @@ impl Component for Paste {
))); )));
decrypted_object.push(&entry); decrypted_object.push(&entry);
let entry = Array::new();
entry.push(&JsString::from("expiration"));
entry.push(&JsString::from(expires.to_string()));
decrypted_object.push(&entry);
}
DecryptedData::Audio(blob) => {
let entry = Array::new();
entry.push(&JsString::from("data"));
entry.push(blob);
decrypted_object.push(&entry);
let entry = Array::new();
entry.push(&JsString::from("type"));
entry.push(&JsString::from("audio"));
decrypted_object.push(&entry);
let entry = Array::new();
entry.push(&JsString::from("expiration"));
entry.push(&JsString::from(expires.to_string()));
decrypted_object.push(&entry);
}
DecryptedData::Video(blob) => {
let entry = Array::new();
entry.push(&JsString::from("data"));
entry.push(blob);
decrypted_object.push(&entry);
let entry = Array::new();
entry.push(&JsString::from("type"));
entry.push(&JsString::from("video"));
decrypted_object.push(&entry);
let entry = Array::new(); let entry = Array::new();
entry.push(&JsString::from("expiration")); entry.push(&JsString::from("expiration"));
entry.push(&JsString::from(expires.to_string())); entry.push(&JsString::from(expires.to_string()));
@ -292,10 +325,3 @@ impl Component for Paste {
html! {} html! {}
} }
} }
#[derive(Clone)]
pub enum DecryptedData {
String(Arc<String>),
Blob(Arc<Blob>),
Image(Arc<Blob>, (u32, u32), usize),
}

View file

@ -64,11 +64,11 @@ main {
cursor: pointer; cursor: pointer;
} }
img { img, audio, video {
margin-bottom: 4em; border-radius: $padding;
margin-bottom: $padding;
max-height: 75vh; max-height: 75vh;
max-width: 75vw; max-width: 75vw;
border-radius: $padding;
} }
.primary { .primary {

View file

@ -4,10 +4,10 @@ function loadFromDb() {
dbReq.onsuccess = (evt) => { dbReq.onsuccess = (evt) => {
const db = (evt.target as IDBRequest).result; const db = (evt.target as IDBRequest).result;
const obj_store = db const obj_store = db
.transaction("decrypted data", "readonly") .transaction("decrypted data")
.objectStore("decrypted data") .objectStore("decrypted data");
.get(window.location.pathname); let fetchReq = obj_store.get(window.location.pathname);
obj_store.onsuccess = (evt) => { fetchReq.onsuccess = (evt) => {
const data = (evt.target as IDBRequest).result; const data = (evt.target as IDBRequest).result;
switch (data.type) { switch (data.type) {
case "string": case "string":
@ -19,13 +19,32 @@ function loadFromDb() {
case "image": case "image":
createImagePasteUi(data); createImagePasteUi(data);
break; break;
case "audio":
createAudioPasteUi(data);
break;
case "video":
createVideoPasteUi(data);
break;
default: default:
createBrokenStateUi(); createBrokenStateUi();
break; break;
} }
// IDB was only used as a temporary medium;
window.onbeforeunload = (e) => {
// See https://link.eddie.sh/NrIIq on why .commit is necessary.
const transaction = db.transaction("decrypted data", "readwrite");
transaction
.objectStore("decrypted data")
.delete(window.location.pathname);
transaction.commit();
transaction.oncomplete = () => {
console.log("Item deleted from cache");
}
};
}; };
obj_store.onerror = (evt) => { fetchReq.onerror = (evt) => {
console.log("err"); console.log("err");
console.log(evt); console.log(evt);
}; };
@ -58,37 +77,6 @@ function createStringPasteUi(data) {
hljs.initLineNumbersOnLoad(); hljs.initLineNumbersOnLoad();
} }
function createImagePasteUi(data) {
let bodyEle = document.getElementsByTagName("body")[0];
bodyEle.textContent = '';
let mainEle = document.createElement("main");
mainEle.classList.add("hljs");
mainEle.classList.add("centered");
mainEle.classList.add("fullscreen");
const downloadLink = URL.createObjectURL(data.data);
let expirationEle = document.createElement("p");
expirationEle.textContent = data.expiration;
mainEle.appendChild(expirationEle);
let imgEle = document.createElement("img");
imgEle.src = downloadLink;
mainEle.appendChild(imgEle);
let downloadEle = document.createElement("a");
downloadEle.href = downloadLink;
downloadEle.download = window.location.pathname;
downloadEle.classList.add("hljs-meta");
downloadEle.textContent = data.button;
mainEle.appendChild(downloadEle);
bodyEle.appendChild(mainEle);
}
function createBlobPasteUi(data) { function createBlobPasteUi(data) {
let bodyEle = document.getElementsByTagName("body")[0]; let bodyEle = document.getElementsByTagName("body")[0];
bodyEle.textContent = ''; bodyEle.textContent = '';
@ -129,6 +117,49 @@ function createBlobPasteUi(data) {
bodyEle.appendChild(mainEle); bodyEle.appendChild(mainEle);
} }
function createImagePasteUi({ expiration, data, button }) {
createMultiMediaPasteUi("img", expiration, data, button);
}
function createAudioPasteUi({ expiration, data }) {
createMultiMediaPasteUi("audio", expiration, data, "Download");
}
function createVideoPasteUi({ expiration, data }) {
createMultiMediaPasteUi("video", expiration, data, "Download");
}
function createMultiMediaPasteUi(tag, expiration, data, downloadMessage) {
let bodyEle = document.getElementsByTagName("body")[0];
bodyEle.textContent = '';
let mainEle = document.createElement("main");
mainEle.classList.add("hljs");
mainEle.classList.add("centered");
mainEle.classList.add("fullscreen");
const downloadLink = URL.createObjectURL(data);
let expirationEle = document.createElement("p");
expirationEle.textContent = expiration;
mainEle.appendChild(expirationEle);
let videoEle = document.createElement(tag);
videoEle.src = downloadLink;
videoEle.controls = true;
mainEle.appendChild(videoEle);
let downloadEle = document.createElement("a");
downloadEle.href = downloadLink;
downloadEle.download = window.location.pathname;
downloadEle.classList.add("hljs-meta");
downloadEle.textContent = downloadMessage;
mainEle.appendChild(downloadEle);
bodyEle.appendChild(mainEle);
}
// Exported to main.rs // Exported to main.rs
function createNotFoundUi() { function createNotFoundUi() {
let body = document.getElementsByTagName("body")[0]; let body = document.getElementsByTagName("body")[0];