From 2f911a482fc705914422a4324a979afd3e3eb5aa Mon Sep 17 00:00:00 2001 From: rupansh Date: Thu, 18 Jan 2024 09:41:24 +0530 Subject: [PATCH] feat: initial upload page --- Cargo.lock | 233 ++++++++++++++++++++++++- Cargo.toml | 9 +- src/app.rs | 6 +- src/component/mod.rs | 2 + src/component/modal.rs | 33 ++++ src/component/toggle.rs | 21 +++ src/consts.rs | 6 + src/main.rs | 16 ++ src/page/mod.rs | 1 + src/page/post_view/video_loader.rs | 10 +- src/page/upload/cf_upload.rs | 163 +++++++++++++++++ src/page/upload/mod.rs | 145 ++++++++++++++++ src/page/upload/validators.rs | 33 ++++ src/page/upload/video_upload.rs | 269 +++++++++++++++++++++++++++++ src/state/cf/direct_upload.rs | 61 +++++++ src/state/cf/enable_mp4.rs | 31 ++++ src/state/cf/error.rs | 28 +++ src/state/cf/mod.rs | 151 ++++++++++++++++ src/state/cf/video_details.rs | 45 +++++ src/state/mod.rs | 4 + src/utils/route.rs | 4 +- 21 files changed, 1264 insertions(+), 7 deletions(-) create mode 100644 src/component/modal.rs create mode 100644 src/component/toggle.rs create mode 100644 src/page/upload/cf_upload.rs create mode 100644 src/page/upload/mod.rs create mode 100644 src/page/upload/validators.rs create mode 100644 src/page/upload/video_upload.rs create mode 100644 src/state/cf/direct_upload.rs create mode 100644 src/state/cf/enable_mp4.rs create mode 100644 src/state/cf/error.rs create mode 100644 src/state/cf/mod.rs create mode 100644 src/state/cf/video_details.rs diff --git a/Cargo.lock b/Cargo.lock index 6cc8edc3..e1e0327e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,6 +250,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "binread" version = "2.2.0" @@ -1151,6 +1160,88 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "gloo" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15282ece24eaf4bd338d73ef580c6714c8615155c4190c781290ee3fa0fd372" +dependencies = [ + "gloo-console", + "gloo-dialogs", + "gloo-events", + "gloo-file", + "gloo-history", + "gloo-net 0.5.0", + "gloo-render", + "gloo-storage", + "gloo-timers", + "gloo-utils 0.2.0", + "gloo-worker", +] + +[[package]] +name = "gloo-console" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261" +dependencies = [ + "gloo-utils 0.2.0", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" +dependencies = [ + "futures-channel", + "gloo-events", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903f432be5ba34427eac5e16048ef65604a82061fe93789f2212afc73d8617d6" +dependencies = [ + "getrandom", + "gloo-events", + "gloo-utils 0.2.0", + "serde", + "serde-wasm-bindgen 0.6.3", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-net" version = "0.2.6" @@ -1171,6 +1262,52 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-net" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.2.0", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" +dependencies = [ + "gloo-utils 0.2.0", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-timers" version = "0.3.0" @@ -1209,6 +1346,37 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-worker" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085f262d7604911c8150162529cefab3782e91adb20202e8658f7275d2aefe5d" +dependencies = [ + "bincode", + "futures", + "gloo-utils 0.2.0", + "gloo-worker-macros", + "js-sys", + "pinned", + "serde", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-worker-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.46", +] + [[package]] name = "group" version = "0.12.1" @@ -1312,6 +1480,7 @@ dependencies = [ name = "hot-or-not-web-leptos-ssr" version = "0.1.0" dependencies = [ + "async-trait", "axum", "candid", "candid_parser", @@ -1320,6 +1489,7 @@ dependencies = [ "console_log", "convert_case", "futures", + "gloo", "hex", "http", "ic-agent", @@ -1331,6 +1501,7 @@ dependencies = [ "leptos_meta", "leptos_router", "log", + "once_cell", "reqwest", "serde", "serde-wasm-bindgen 0.6.3", @@ -1343,6 +1514,7 @@ dependencies = [ "tower-http", "tracing", "wasm-bindgen", + "web-time", ] [[package]] @@ -2123,7 +2295,7 @@ checksum = "c1a2ff8b8e8ae8b17efd8be2a407f7f83ed57c5243f70f2d03e6635f9ff61848" dependencies = [ "cached 0.45.1", "cfg-if", - "gloo-net", + "gloo-net 0.2.6", "itertools 0.11.0", "js-sys", "lazy_static", @@ -2610,6 +2782,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pinned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" +dependencies = [ + "futures", + "rustversion", + "thiserror", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -2665,6 +2848,16 @@ dependencies = [ "syn 2.0.46", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -3305,7 +3498,7 @@ checksum = "cfed18dfcc8d9004579c40482c3419c07f60ffb9c5b250542edca99f508b0ce9" dependencies = [ "ciborium", "const_format", - "gloo-net", + "gloo-net 0.2.6", "inventory", "js-sys", "lazy_static", @@ -3778,6 +3971,23 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -4113,6 +4323,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee269d72cc29bf77a2c4bc689cc750fb39f5cbd493d2205bbb3f5c7779cf7b0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "0.25.3" @@ -4282,6 +4502,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.5.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index f5102dd4..051e96ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,11 +30,15 @@ ic-agent = { version = "0.31.0", default-features = false, features = ["pem", "r serde-wasm-bindgen = { version = "0.6.3" } futures = "0.3.30" leptos-use = "0.9.0" -reqwest = { version = "0.11.23", default-features = false } +reqwest = { version = "0.11.23", default-features = false, features = ["json"] } serde_bytes = "0.11.14" hex = "0.4.3" leptos_icons = "0.2.1" icondata = "0.3.0" +gloo = { version = "0.11.0", features = ["futures", "net", "net"] } +once_cell = "1.19.0" +async-trait = "0.1.77" +web-time = "1.0.0" [build-dependencies] candid_parser = "0.1.1" @@ -57,6 +61,9 @@ ssr = [ "leptos-use/ssr", "reqwest/rustls-tls", ] +cloudflare = [] +release-bin = ["ssr", "cloudflare"] +release-lib = ["hydrate", "cloudflare"] # Defines a size-optimized profile for the WASM bundle in release mode [profile.wasm-release] diff --git a/src/app.rs b/src/app.rs index b0121978..8ba08799 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,9 @@ use crate::{ error_template::{AppError, ErrorTemplate}, - page::{err::ServerErrorPage, post_view::PostView, profile::ProfileView, root::RootPage}, + page::{ + err::ServerErrorPage, post_view::PostView, profile::ProfileView, root::RootPage, + upload::UploadPostPage, + }, state::canisters::Canisters, }; use leptos::*; @@ -30,6 +33,7 @@ pub fn App() -> impl IntoView { + diff --git a/src/component/mod.rs b/src/component/mod.rs index bac27d7b..fca1591e 100644 --- a/src/component/mod.rs +++ b/src/component/mod.rs @@ -1,2 +1,4 @@ pub mod bullet_loader; +pub mod modal; pub mod spinner; +pub mod toggle; diff --git a/src/component/modal.rs b/src/component/modal.rs new file mode 100644 index 00000000..d7fc4667 --- /dev/null +++ b/src/component/modal.rs @@ -0,0 +1,33 @@ +use cfg_if::cfg_if; +use leptos::*; +use leptos_icons::*; + +#[component] +pub fn Modal(#[prop(into)] show: RwSignal, children: Children) -> impl IntoView { + view! { +
(& ev); if target.class_list() + .contains("modal-bg") { show.set(false); } } else { _ = ev } + } + } + + class="cursor-pointer modal-bg w-screen h-screen absolute left-0 top-0 bg-black/60 z-50 justify-center items-center" + style:display=move || if show() { "flex" } else { "none" } + > +
+
+ +
+ {children()} +
+
+ } +} diff --git a/src/component/toggle.rs b/src/component/toggle.rs new file mode 100644 index 00000000..584d9bbe --- /dev/null +++ b/src/component/toggle.rs @@ -0,0 +1,21 @@ +use leptos::{html::Input, *}; + +#[component] +pub fn Toggle( + #[prop(into)] lab: String, + #[prop(optional)] node_ref: Option>, +) -> impl IntoView { + view! { + + } +} diff --git a/src/consts.rs b/src/consts.rs index aca9e19f..5a51afef 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,2 +1,8 @@ +use once_cell::sync::Lazy; +use reqwest::Url; + pub const CF_STREAM_BASE: &str = "https://customer-2p3jflss4r4hmpnz.cloudflarestream.com"; pub const FALLBACK_PROPIC_BASE: &str = "https://api.dicebear.com/7.x/big-smile/svg"; +pub const CF_WATERMARK_UID: &str = "28c721e45583a215d7b2ec1ae16e2679"; +pub static CF_BASE_URL: Lazy = + Lazy::new(|| Url::parse("https://api.cloudflare.com/client/v4/").unwrap()); diff --git a/src/main.rs b/src/main.rs index 18baf23a..6f6e5fe3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,8 @@ mod handlers { raw_query, move || { provide_context(app_state.canisters.clone()); + #[cfg(feature = "cloudflare")] + provide_context(app_state.cloudflare.clone()); }, request, ) @@ -38,6 +40,8 @@ mod handlers { app_state.routes.clone(), move || { provide_context(app_state.canisters.clone()); + #[cfg(feature = "cloudflare")] + provide_context(app_state.cloudflare.clone()); }, App, ); @@ -45,6 +49,16 @@ mod handlers { } } +#[cfg(feature = "ssr")] +#[cfg(feature = "cloudflare")] +fn init_cf() -> hot_or_not_web_leptos_ssr::state::cf::CfApi { + use hot_or_not_web_leptos_ssr::state::cf::{CfApi, CfCredentials}; + let Some(creds) = CfCredentials::from_env("CF_TOKEN", "CF_ACCOUNT_ID") else { + panic!("Cloudlflare credentials are required: CF_TOKEN, CF_ACCOUNT_ID"); + }; + CfApi::::new(creds) +} + #[cfg(feature = "ssr")] #[tokio::main] async fn main() { @@ -73,6 +87,8 @@ async fn main() { leptos_options, canisters: Canisters::default(), routes: routes.clone(), + #[cfg(feature = "cloudflare")] + cloudflare: init_cf(), }; // build our application with a route diff --git a/src/page/mod.rs b/src/page/mod.rs index de9018e6..e020e9c0 100644 --- a/src/page/mod.rs +++ b/src/page/mod.rs @@ -2,3 +2,4 @@ pub mod err; pub mod post_view; pub mod profile; pub mod root; +pub mod upload; diff --git a/src/page/post_view/video_loader.rs b/src/page/post_view/video_loader.rs index d1e27873..3b9b8150 100644 --- a/src/page/post_view/video_loader.rs +++ b/src/page/post_view/video_loader.rs @@ -72,7 +72,15 @@ pub fn HlsVideo(video_ref: NodeRef