Compare commits
4 commits
3393f40482
...
5fa69be1d5
Author | SHA1 | Date | |
---|---|---|---|
5fa69be1d5 | |||
9a8658e744 | |||
6859bffe05 | |||
08f3e940e4 |
22 changed files with 1631 additions and 3586 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@
|
||||||
test.*
|
test.*
|
||||||
dist.tar.zst
|
dist.tar.zst
|
||||||
.env
|
.env
|
||||||
|
web/pkg
|
3
.swcrc
3
.swcrc
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"jsc": {
|
"jsc": {
|
||||||
"parser": {
|
"parser": {
|
||||||
"syntax": "typescript"
|
"syntax": "typescript",
|
||||||
|
"tsx": true
|
||||||
},
|
},
|
||||||
"target": "es2021"
|
"target": "es2021"
|
||||||
}
|
}
|
||||||
|
|
48
Cargo.lock
generated
48
Cargo.lock
generated
|
@ -73,11 +73,12 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.3.4"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6b4e96976b2022b23b2199168ff9b281e9ddc1aa795607d5cb7146868ca5c101"
|
checksum = "310a147401c66e79fc78636e4db63ac68cd6acb9ece056de806ea173a15bce32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"axum-core",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -86,6 +87,7 @@ dependencies = [
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
"matchit",
|
"matchit",
|
||||||
|
"memchr",
|
||||||
"mime",
|
"mime",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -96,11 +98,25 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http 0.2.0",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-core"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ca6c0b218388a7ed6a8d25e94f7dea5498daaa4fd8c711fb3ff166041b06fda"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"mime",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
@ -653,6 +669,12 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-range-header"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
@ -1012,7 +1034,7 @@ dependencies = [
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-tokio",
|
"signal-hook-tokio",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-http",
|
"tower-http 0.1.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
@ -1731,6 +1753,24 @@ dependencies = [
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39ee603d6e665ecc7e0f8d479eedb4626bd4726f0ee6119cee5b3a6bf184cac0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-range-header",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
17
Trunk.toml
17
Trunk.toml
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
[build]
|
|
||||||
target = "web/index.html"
|
|
||||||
release = true
|
|
||||||
dist = "./dist"
|
|
||||||
|
|
||||||
[clean]
|
|
||||||
dist = "./dist"
|
|
||||||
|
|
||||||
[[proxy]]
|
|
||||||
backend = "http://localhost:8081"
|
|
||||||
rewrite = "/api/"
|
|
||||||
|
|
||||||
[[hooks]]
|
|
||||||
stage="post_build"
|
|
||||||
command="npx"
|
|
||||||
command_arguments=["swc", "$TRUNK_SOURCE_DIR/src/main.ts", "-o", "$TRUNK_STAGING_DIR/main.js"]
|
|
17
bin/build.sh
17
bin/build.sh
|
@ -20,21 +20,16 @@ set -euxo pipefail
|
||||||
|
|
||||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||||
|
|
||||||
# Build frontend assets
|
# Clean resources
|
||||||
yarn
|
rm -rf dist
|
||||||
trunk build --release
|
|
||||||
|
|
||||||
sed -i 's#/index#/static/index#g' dist/index.html
|
# Build frontend code
|
||||||
sed -i 's#stylesheet" href="/main#stylesheet" href="/static/main#g' dist/index.html
|
yarn
|
||||||
|
yarn build
|
||||||
|
mv dist/static/index.html dist
|
||||||
|
|
||||||
# Build server
|
# Build server
|
||||||
cargo build --release --bin omegaupload-server
|
cargo build --release --bin omegaupload-server
|
||||||
|
|
||||||
# Prepare assets for upload to webserver
|
|
||||||
mkdir -p dist/static
|
|
||||||
# Move everything that's not index.html into a `static` subdir
|
|
||||||
find dist -not -name index.html -type f -exec mv {} dist/static/ ";"
|
|
||||||
|
|
||||||
strip target/release/omegaupload-server
|
strip target/release/omegaupload-server
|
||||||
cp target/release/omegaupload-server dist/omegaupload-server
|
cp target/release/omegaupload-server dist/omegaupload-server
|
||||||
|
|
||||||
|
|
|
@ -19,17 +19,9 @@
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
|
|
||||||
CUR_DIR=$(pwd)
|
CUR_DIR=$(pwd)
|
||||||
|
|
||||||
PROJECT_TOP_LEVEL=$(git rev-parse --show-toplevel)
|
PROJECT_TOP_LEVEL=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
cd "$PROJECT_TOP_LEVEL" || exit 1
|
cd "$PROJECT_TOP_LEVEL" || exit 1
|
||||||
git submodule foreach git pull
|
git submodule foreach git pull
|
||||||
|
|
||||||
HLJS_PATH=$(git submodule status | cut -d ' ' -f3 | grep highlight.js)
|
|
||||||
|
|
||||||
cd "$HLJS_PATH"
|
|
||||||
npm ci # install without updating package-lock.josn
|
|
||||||
node tools/build
|
|
||||||
mv build/highlight.min.js "$PROJECT_TOP_LEVEL"/"$HLJS_PATH"/..
|
|
||||||
|
|
||||||
cd "$CUR_DIR"
|
cd "$CUR_DIR"
|
22
package.json
22
package.json
|
@ -1,6 +1,26 @@
|
||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc/cli": "^0.1.51",
|
"@swc/cli": "^0.1.51",
|
||||||
"@swc/core": "^1.2.102"
|
"@swc/core": "^1.2.102",
|
||||||
|
"@types/react-dom": "^17.0.11",
|
||||||
|
"@wasm-tool/wasm-pack-plugin": "^1.6.0",
|
||||||
|
"css-loader": "^6.5.1",
|
||||||
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"sass": "^1.48.0",
|
||||||
|
"sass-loader": "^12.4.0",
|
||||||
|
"style-loader": "^3.3.1",
|
||||||
|
"swc-loader": "^0.1.15",
|
||||||
|
"webpack": "^5.66.0",
|
||||||
|
"webpack-cli": "^4.9.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"highlight.js": "^11.4.0",
|
||||||
|
"highlightjs-line-numbers.js": "^2.8.0",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-dom": "^17.0.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --mode production",
|
||||||
|
"clean": "(git rev-parse --show-toplevel && rm -rf node_modules dist web/pkg)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
omegaupload-common = { path = "../common" }
|
omegaupload-common = { path = "../common" }
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
axum = { version = "0.3", features = ["http2", "headers"] }
|
axum = { version = "0.4", features = ["http2", "headers"] }
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
# We don't care about which version (We want to match with axum), we just need
|
# We don't care about which version (We want to match with axum), we just need
|
||||||
# to enable the feature
|
# to enable the feature
|
||||||
|
|
|
@ -22,12 +22,11 @@ use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use axum::body::Bytes;
|
use axum::body::Bytes;
|
||||||
use axum::error_handling::HandleErrorExt;
|
use axum::error_handling::HandleError;
|
||||||
use axum::extract::{Extension, Path, TypedHeader};
|
use axum::extract::{Extension, Path, TypedHeader};
|
||||||
use axum::http::header::EXPIRES;
|
use axum::http::header::EXPIRES;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::response::Html;
|
use axum::routing::{get, get_service, post};
|
||||||
use axum::routing::{get, post, service_method_routing};
|
|
||||||
use axum::{AddExtensionLayer, Router};
|
use axum::{AddExtensionLayer, Router};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
@ -41,7 +40,7 @@ use rocksdb::{Options, DB};
|
||||||
use signal_hook::consts::SIGUSR1;
|
use signal_hook::consts::SIGUSR1;
|
||||||
use signal_hook_tokio::Signals;
|
use signal_hook_tokio::Signals;
|
||||||
use tokio::task::{self, JoinHandle};
|
use tokio::task::{self, JoinHandle};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::{ServeDir, ServeFile};
|
||||||
use tracing::{error, instrument, trace};
|
use tracing::{error, instrument, trace};
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
@ -58,7 +57,6 @@ lazy_static! {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
const INDEX_PAGE: Html<&'static str> = Html(include_str!("../../dist/index.html"));
|
|
||||||
const PASTE_DB_PATH: &str = "database";
|
const PASTE_DB_PATH: &str = "database";
|
||||||
const SHORT_CODE_SIZE: usize = 12;
|
const SHORT_CODE_SIZE: usize = 12;
|
||||||
|
|
||||||
|
@ -83,8 +81,13 @@ async fn main() -> Result<()> {
|
||||||
let signals_handle = signals.handle();
|
let signals_handle = signals.handle();
|
||||||
let signals_task = tokio::spawn(handle_signals(signals, Arc::clone(&db)));
|
let signals_task = tokio::spawn(handle_signals(signals, Arc::clone(&db)));
|
||||||
|
|
||||||
let root_service = service_method_routing::get(ServeDir::new("static"))
|
let root_service = HandleError::new(get_service(ServeDir::new("static")), |_| async {
|
||||||
.handle_error(|_| Ok::<_, Infallible>(StatusCode::NOT_FOUND));
|
Ok::<_, Infallible>(StatusCode::NOT_FOUND)
|
||||||
|
});
|
||||||
|
|
||||||
|
let index_service = HandleError::new(get_service(ServeFile::new("index.html")), |_| async {
|
||||||
|
Ok::<_, Infallible>(StatusCode::NOT_FOUND)
|
||||||
|
});
|
||||||
|
|
||||||
axum::Server::bind(&"0.0.0.0:8080".parse()?)
|
axum::Server::bind(&"0.0.0.0:8080".parse()?)
|
||||||
.serve({
|
.serve({
|
||||||
|
@ -92,9 +95,9 @@ async fn main() -> Result<()> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route(
|
.route(
|
||||||
"/",
|
"/",
|
||||||
post(upload::<SHORT_CODE_SIZE>).get(|| async { INDEX_PAGE }),
|
post(upload::<SHORT_CODE_SIZE>).get_service(index_service.clone()),
|
||||||
)
|
)
|
||||||
.route("/:code", get(|| async { INDEX_PAGE }))
|
.route("/:code", index_service)
|
||||||
.nest("/static", root_service)
|
.nest("/static", root_service)
|
||||||
.route(
|
.route(
|
||||||
&format!("{API_ENDPOINT}/:code"),
|
&format!("{API_ENDPOINT}/:code"),
|
||||||
|
|
|
@ -3,7 +3,8 @@ name = "omegaupload-web"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
omegaupload-common = { path = "../common", features = ["wasm"] }
|
omegaupload-common = { path = "../common", features = ["wasm"] }
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>Omegaupload</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
|
|
||||||
|
|
||||||
<script src="static/main.js" defer></script>
|
|
||||||
<script src="static/highlight.min.js" defer></script>
|
|
||||||
<script src="static/highlightjs-line-numbers.min.js" defer></script>
|
|
||||||
|
|
||||||
<link data-trunk rel="rust" data-wasm-opt="0" data-keep-debug="true" data-no-mangle="true" />
|
|
||||||
<link data-trunk rel="copy-file" href="vendor/MPLUS_FONTS/fonts/ttf/MPLUSCodeLatin[wdth,wght].ttf" dest="/" />
|
|
||||||
<link data-trunk rel="copy-file" href="vendor/highlight.min.js" dest="/" />
|
|
||||||
<link data-trunk rel="copy-file" href="vendor/highlightjs-line-numbers.js/dist/highlightjs-line-numbers.min.js"
|
|
||||||
dest="/" />
|
|
||||||
<link data-trunk rel="scss" href="src/main.scss" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
</html>
|
|
1
web/src/globals.d.ts
vendored
1
web/src/globals.d.ts
vendored
|
@ -1 +0,0 @@
|
||||||
declare var hljs;
|
|
10
web/src/index.html
Normal file
10
web/src/index.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Omegaupload</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
</html>
|
3
web/src/index.js
Normal file
3
web/src/index.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { start } from '../pkg';
|
||||||
|
|
||||||
|
start();
|
|
@ -44,7 +44,7 @@ mod util;
|
||||||
|
|
||||||
const DOWNLOAD_SIZE_LIMIT: u128 = n_mib_bytes!(500);
|
const DOWNLOAD_SIZE_LIMIT: u128 = n_mib_bytes!(500);
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen(raw_module = "../src/render")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[wasm_bindgen(js_name = loadFromDb)]
|
#[wasm_bindgen(js_name = loadFromDb)]
|
||||||
pub fn load_from_db(mime_type: JsString, name: Option<JsString>, language: Option<JsString>);
|
pub fn load_from_db(mime_type: JsString, name: Option<JsString>, language: Option<JsString>);
|
||||||
|
@ -69,7 +69,8 @@ fn open_idb() -> Result<IdbOpenDbRequest> {
|
||||||
.map_err(|_| anyhow!("Failed to open idb"))
|
.map_err(|_| anyhow!("Failed to open idb"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[wasm_bindgen]
|
||||||
|
pub fn start() {
|
||||||
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||||
|
|
||||||
if location().pathname().unwrap() == "/" {
|
if location().pathname().unwrap() == "/" {
|
|
@ -14,13 +14,13 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
@use '../vendor/highlight.js/src/styles/github-dark.css';
|
@use 'node_modules/highlight.js/styles/github-dark.css';
|
||||||
|
|
||||||
$padding: 1em;
|
$padding: 1em;
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Mplus Code";
|
font-family: "Mplus Code";
|
||||||
src: url("./MPLUSCodeLatin[wdth,wght].ttf") format("truetype");
|
src: url("../vendor/MPLUS_FONTS/fonts/ttf/MPLUSCodeLatin[wdth,wght].ttf") format("truetype");
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -43,6 +43,10 @@ main {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
.paste {
|
.paste {
|
||||||
@extend .hljs;
|
@extend .hljs;
|
||||||
border-radius: $padding;
|
border-radius: $padding;
|
||||||
|
|
|
@ -14,7 +14,14 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// Exported to main.rs
|
import './main.scss';
|
||||||
|
import ReactDom from 'react-dom';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const hljs = require('highlight.js');
|
||||||
|
(window as any).hljs = hljs;
|
||||||
|
require('highlightjs-line-numbers.js');
|
||||||
|
|
||||||
function loadFromDb(mimeType: string, name?: string, language?: string) {
|
function loadFromDb(mimeType: string, name?: string, language?: string) {
|
||||||
let resolvedName;
|
let resolvedName;
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -91,36 +98,20 @@ function loadFromDb(mimeType: string, name?: string, language?: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStringPasteUi(data, mimeType: string, name: string, lang?: string) {
|
function createStringPasteUi(data, mimeType: string, name: string, lang?: string) {
|
||||||
const bodyEle = document.getElementsByTagName("body")[0];
|
const html = <main>
|
||||||
bodyEle.textContent = '';
|
<pre className='paste'>
|
||||||
|
<p className='unselectable centered'>{data.expiration}</p>
|
||||||
|
<a href={getObjectUrl([data.data], mimeType)} download={name} className='hljs-meta centered'>
|
||||||
|
Download file.
|
||||||
|
</a>
|
||||||
|
<hr />
|
||||||
|
<code>
|
||||||
|
{data.data}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
</main>;
|
||||||
|
|
||||||
const mainEle = document.createElement("main");
|
ReactDom.render(html, document.body);
|
||||||
const preEle = document.createElement("pre");
|
|
||||||
preEle.classList.add("paste");
|
|
||||||
|
|
||||||
const headerEle = document.createElement("p");
|
|
||||||
headerEle.classList.add("unselectable");
|
|
||||||
headerEle.classList.add("centered");
|
|
||||||
headerEle.textContent = data.expiration;
|
|
||||||
preEle.appendChild(headerEle);
|
|
||||||
|
|
||||||
const downloadEle = document.createElement("a");
|
|
||||||
downloadEle.href = getObjectUrl([data.data], mimeType);
|
|
||||||
downloadEle.download = name;
|
|
||||||
|
|
||||||
downloadEle.classList.add("hljs-meta");
|
|
||||||
downloadEle.classList.add("centered");
|
|
||||||
downloadEle.textContent = "Download file.";
|
|
||||||
preEle.appendChild(downloadEle);
|
|
||||||
|
|
||||||
preEle.appendChild(document.createElement("hr"));
|
|
||||||
|
|
||||||
const codeEle = document.createElement("code");
|
|
||||||
codeEle.textContent = data.data;
|
|
||||||
preEle.appendChild(codeEle);
|
|
||||||
|
|
||||||
mainEle.appendChild(preEle);
|
|
||||||
bodyEle.appendChild(mainEle);
|
|
||||||
|
|
||||||
let languages = undefined;
|
let languages = undefined;
|
||||||
|
|
||||||
|
@ -167,46 +158,28 @@ function createStringPasteUi(data, mimeType: string, name: string, lang?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
hljs.highlightAll();
|
hljs.highlightAll();
|
||||||
hljs.initLineNumbersOnLoad();
|
|
||||||
|
|
||||||
|
(hljs as any).initLineNumbersOnLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBlobPasteUi(data, name: string) {
|
function createBlobPasteUi(data, name: string) {
|
||||||
const bodyEle = document.getElementsByTagName("body")[0];
|
const html = <main className='hljs centered fullscreen'>
|
||||||
bodyEle.textContent = '';
|
<div className='centered'>
|
||||||
|
<p>{data.expiration}</p>
|
||||||
|
<a href={getObjectUrl(data.data, name)} download={name} className='hljs-meta'>
|
||||||
|
Download binary file.
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p className='display-anyways hljs-comment' onClick={() => {
|
||||||
|
data.data.text().then(text => {
|
||||||
|
data.data = text;
|
||||||
|
createStringPasteUi(data, "application/octet-stream", name);
|
||||||
|
})
|
||||||
|
}}>Display anyways?</p>
|
||||||
|
</main>;
|
||||||
|
|
||||||
const mainEle = document.createElement("main");
|
ReactDom.render(html, document.body);
|
||||||
mainEle.classList.add("hljs");
|
|
||||||
mainEle.classList.add("centered");
|
|
||||||
mainEle.classList.add("fullscreen");
|
|
||||||
|
|
||||||
const divEle = document.createElement("div");
|
|
||||||
divEle.classList.add("centered");
|
|
||||||
|
|
||||||
const expirationEle = document.createElement("p");
|
|
||||||
expirationEle.textContent = data.expiration;
|
|
||||||
divEle.appendChild(expirationEle);
|
|
||||||
|
|
||||||
const downloadEle = document.createElement("a");
|
|
||||||
downloadEle.href = getObjectUrl(data.data, name);
|
|
||||||
downloadEle.download = name;
|
|
||||||
downloadEle.classList.add("hljs-meta");
|
|
||||||
downloadEle.textContent = "Download binary file.";
|
|
||||||
divEle.appendChild(downloadEle);
|
|
||||||
|
|
||||||
mainEle.appendChild(divEle);
|
|
||||||
|
|
||||||
const displayAnywayEle = document.createElement("p");
|
|
||||||
displayAnywayEle.classList.add("display-anyways");
|
|
||||||
displayAnywayEle.classList.add("hljs-comment");
|
|
||||||
displayAnywayEle.textContent = "Display anyways?";
|
|
||||||
displayAnywayEle.onclick = () => {
|
|
||||||
data.data.text().then(text => {
|
|
||||||
data.data = text;
|
|
||||||
createStringPasteUi(data, "application/octet-stream", name);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
mainEle.appendChild(displayAnywayEle);
|
|
||||||
bodyEle.appendChild(mainEle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createImagePasteUi({ expiration, data, file_size }, name: string, mimeType: string) {
|
function createImagePasteUi({ expiration, data, file_size }, name: string, mimeType: string) {
|
||||||
|
@ -228,39 +201,6 @@ function createVideoPasteUi({ expiration, data }, name: string, mimeType: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function createArchivePasteUi({ expiration, data, entries }, name: string) {
|
function createArchivePasteUi({ expiration, data, entries }, name: string) {
|
||||||
const bodyEle = document.getElementsByTagName("body")[0];
|
|
||||||
bodyEle.textContent = '';
|
|
||||||
|
|
||||||
const mainEle = document.createElement("main");
|
|
||||||
|
|
||||||
const sectionEle = document.createElement("section");
|
|
||||||
sectionEle.classList.add("paste");
|
|
||||||
|
|
||||||
const expirationEle = document.createElement("p");
|
|
||||||
expirationEle.textContent = expiration;
|
|
||||||
expirationEle.classList.add("centered");
|
|
||||||
sectionEle.appendChild(expirationEle);
|
|
||||||
|
|
||||||
const downloadEle = document.createElement("a");
|
|
||||||
downloadEle.href = getObjectUrl(data);
|
|
||||||
downloadEle.download = name;
|
|
||||||
downloadEle.textContent = "Download";
|
|
||||||
downloadEle.classList.add("hljs-meta");
|
|
||||||
downloadEle.classList.add("centered");
|
|
||||||
sectionEle.appendChild(downloadEle);
|
|
||||||
|
|
||||||
sectionEle.appendChild(document.createElement("hr"));
|
|
||||||
|
|
||||||
const mediaEle = document.createElement("table");
|
|
||||||
mediaEle.classList.add("archive-table");
|
|
||||||
const tr = mediaEle.insertRow();
|
|
||||||
tr.classList.add("hljs-title");
|
|
||||||
const tdName = tr.insertCell();
|
|
||||||
tdName.textContent = "Name";
|
|
||||||
const tdSize = tr.insertCell();
|
|
||||||
tdSize.classList.add("align-right");
|
|
||||||
tdSize.textContent = "File Size";
|
|
||||||
|
|
||||||
// Because it's a stable sort, we can first sort by name (to get all folder
|
// Because it's a stable sort, we can first sort by name (to get all folder
|
||||||
// items grouped together) and then sort by if there's a / or not.
|
// items grouped together) and then sort by if there's a / or not.
|
||||||
entries.sort((a, b) => {
|
entries.sort((a, b) => {
|
||||||
|
@ -273,23 +213,32 @@ function createArchivePasteUi({ expiration, data, entries }, name: string) {
|
||||||
return b.name.includes("/") - a.name.includes("/");
|
return b.name.includes("/") - a.name.includes("/");
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const { name, file_size } of entries) {
|
const html = <main>
|
||||||
const tr = mediaEle.insertRow();
|
<section className='paste'>
|
||||||
const tdName = tr.insertCell();
|
<p className='centered'>{expiration}</p>
|
||||||
tdName.textContent = name;
|
<a href={getObjectUrl(data)} download={name} className='hljs-meta centered'>Download</a>
|
||||||
const tdSize = tr.insertCell();
|
<hr />
|
||||||
tdSize.textContent = file_size;
|
<table className='archive-table'>
|
||||||
tdSize.classList.add("align-right");
|
<thead>
|
||||||
tdSize.classList.add("hljs-number");
|
<tr className='hljs-title'><th>Name</th><th className='align-right'>File Size</th></tr>
|
||||||
}
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{
|
||||||
|
entries.map(({ name, file_size }) => {
|
||||||
|
return <tr><td>{name}</td><td className='align-right hljs-number'>{file_size}</td></tr>;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
</main>;
|
||||||
|
|
||||||
|
ReactDom.render(html, document.body);
|
||||||
|
|
||||||
sectionEle.appendChild(mediaEle);
|
|
||||||
mainEle.appendChild(sectionEle);
|
|
||||||
bodyEle.appendChild(mainEle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMultiMediaPasteUi(tag, expiration, data, name: string, mimeType: string, on_create?: Function | string) {
|
function createMultiMediaPasteUi(tag, expiration, data, name: string, mimeType: string, on_create?: Function | string) {
|
||||||
const bodyEle = document.getElementsByTagName("body")[0];
|
const bodyEle = document.body;
|
||||||
bodyEle.textContent = '';
|
bodyEle.textContent = '';
|
||||||
|
|
||||||
const mainEle = document.createElement("main");
|
const mainEle = document.createElement("main");
|
||||||
|
@ -308,7 +257,6 @@ function createMultiMediaPasteUi(tag, expiration, data, name: string, mimeType:
|
||||||
mediaEle.controls = true;
|
mediaEle.controls = true;
|
||||||
mainEle.appendChild(mediaEle);
|
mainEle.appendChild(mediaEle);
|
||||||
|
|
||||||
|
|
||||||
const downloadEle = document.createElement("a");
|
const downloadEle = document.createElement("a");
|
||||||
downloadEle.href = downloadLink;
|
downloadEle.href = downloadLink;
|
||||||
downloadEle.download = name;
|
downloadEle.download = name;
|
||||||
|
@ -325,14 +273,12 @@ function createMultiMediaPasteUi(tag, expiration, data, name: string, mimeType:
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMessage(message) {
|
function renderMessage(message) {
|
||||||
const body = document.getElementsByTagName("body")[0];
|
ReactDom.render(
|
||||||
body.textContent = '';
|
<main className='hljs centered fullscreen'>
|
||||||
const mainEle = document.createElement("main");
|
{message}
|
||||||
mainEle.classList.add("hljs");
|
</main>,
|
||||||
mainEle.classList.add("centered");
|
document.body,
|
||||||
mainEle.classList.add("fullscreen");
|
);
|
||||||
mainEle.textContent = message;
|
|
||||||
body.appendChild(mainEle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getObjectUrl(data, mimeType?: string) {
|
function getObjectUrl(data, mimeType?: string) {
|
||||||
|
@ -340,3 +286,5 @@ function getObjectUrl(data, mimeType?: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("hashchange", () => location.reload());
|
window.addEventListener("hashchange", () => location.reload());
|
||||||
|
|
||||||
|
export { renderMessage, loadFromDb };
|
1
web/vendor/highlight.js
vendored
1
web/vendor/highlight.js
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 112135fb063af64b7a94155b5d86859e8d52b6f0
|
|
3377
web/vendor/highlight.min.js
vendored
3377
web/vendor/highlight.min.js
vendored
File diff suppressed because one or more lines are too long
1
web/vendor/highlightjs-line-numbers.js
vendored
1
web/vendor/highlightjs-line-numbers.js
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit c2d9209ce356956b86316da3881b125539a2aaa3
|
|
49
webpack.config.js
Normal file
49
webpack.config.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './web/src/index.js',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'swc-loader',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/i,
|
||||||
|
use: [
|
||||||
|
// Creates `style` nodes from JS strings
|
||||||
|
"style-loader",
|
||||||
|
// Translates CSS into CommonJS
|
||||||
|
"css-loader",
|
||||||
|
// Compiles Sass to CSS
|
||||||
|
"sass-loader",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist/static'),
|
||||||
|
filename: 'index.js',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: path.resolve(__dirname, 'web/src/index.html'),
|
||||||
|
publicPath: "/static",
|
||||||
|
}),
|
||||||
|
new WasmPackPlugin({
|
||||||
|
crateDirectory: path.resolve(__dirname, "web"),
|
||||||
|
outDir: path.resolve(__dirname, "web/pkg"),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
experiments: {
|
||||||
|
asyncWebAssembly: true,
|
||||||
|
},
|
||||||
|
mode: 'development'
|
||||||
|
};
|
Loading…
Reference in a new issue