Depend less on yew for rendering
This commit is contained in:
parent
c12526abc0
commit
95e15b81b7
7 changed files with 186 additions and 51 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
/target
|
**/target
|
||||||
**/database
|
**/database
|
||||||
/web/dist/
|
**/dist/
|
||||||
**/node_modules
|
**/node_modules
|
||||||
|
test.*
|
61
Cargo.lock
generated
61
Cargo.lock
generated
|
@ -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"
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
103
web/src/main.ts
103
web/src/main.ts
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue