From 2adce0ead1341f9079cffd87893dbc3afe37f15f Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 27 Jul 2023 15:31:34 +0100 Subject: [PATCH] New spotlight media --- packages/app/public/icons.svg | 5 + packages/app/src/Element/MediaElement.css | 15 -- packages/app/src/Element/MediaElement.tsx | 199 +------------------- packages/app/src/Element/RevealMedia.tsx | 8 +- packages/app/src/Element/SpotlightMedia.css | 45 +++++ packages/app/src/Element/SpotlightMedia.tsx | 54 ++++++ packages/app/src/Element/Text.tsx | 33 +++- packages/app/src/Pages/Layout.css | 4 + packages/app/src/Pages/Layout.tsx | 18 +- 9 files changed, 151 insertions(+), 230 deletions(-) delete mode 100644 packages/app/src/Element/MediaElement.css create mode 100644 packages/app/src/Element/SpotlightMedia.css create mode 100644 packages/app/src/Element/SpotlightMedia.tsx diff --git a/packages/app/public/icons.svg b/packages/app/public/icons.svg index 2e204b46..1aa8ce5b 100644 --- a/packages/app/public/icons.svg +++ b/packages/app/public/icons.svg @@ -282,6 +282,11 @@ + + + + + \ No newline at end of file diff --git a/packages/app/src/Element/MediaElement.css b/packages/app/src/Element/MediaElement.css deleted file mode 100644 index 47480d0a..00000000 --- a/packages/app/src/Element/MediaElement.css +++ /dev/null @@ -1,15 +0,0 @@ -.modal.spotlight .modal-body { - max-width: 100vw; - width: unset; -} - -.modal.spotlight img, -.modal.spotlight video { - max-width: 90vw; - max-height: 90vh; - aspect-ratio: unset; -} - -.modal.spotlight .close { - text-align: right; -} diff --git a/packages/app/src/Element/MediaElement.tsx b/packages/app/src/Element/MediaElement.tsx index 2abe27b9..3db43944 100644 --- a/packages/app/src/Element/MediaElement.tsx +++ b/packages/app/src/Element/MediaElement.tsx @@ -1,18 +1,5 @@ import { ProxyImg } from "Element/ProxyImg"; -import React, { MouseEvent, useEffect, useState } from "react"; -import { FormattedMessage, FormattedNumber } from "react-intl"; -import { Link } from "react-router-dom"; -import { decodeInvoice, InvoiceDetails } from "@snort/shared"; - -import "./MediaElement.css"; -import Modal from "Element/Modal"; -import Icon from "Icons/Icon"; -import { kvToObject } from "SnortUtils"; -import AsyncButton from "Element/AsyncButton"; -import { useWallet } from "Wallet"; -import { PaymentsCache } from "Cache"; -import { Payment } from "Db"; -import PageSpinner from "Element/PageSpinner"; +import React from "react"; /* [ @@ -28,162 +15,16 @@ interface MediaElementProps { magnet?: string; sha256?: string; blurHash?: string; - disableSpotlight?: boolean; -} - -interface L402Object { - macaroon: string; - invoice: string; + onMediaClick?: (e: React.MouseEvent) => void; } export function MediaElement(props: MediaElementProps) { - const [invoice, setInvoice] = useState(); - const [l402, setL402] = useState(); - const [auth, setAuth] = useState(); - const [error, setError] = useState(""); - const [url, setUrl] = useState(props.url); - const [loading, setLoading] = useState(false); - const wallet = useWallet(); - - async function probeFor402() { - const cached = await PaymentsCache.get(props.url); - if (cached) { - setAuth(cached); - return; - } - - try { - const req = new Request(props.url, { - method: "OPTIONS", - headers: { - accept: "L402", - }, - }); - const rsp = await fetch(req); - if (rsp.status === 402) { - const auth = rsp.headers.get("www-authenticate"); - if (auth?.startsWith("L402")) { - const vals = kvToObject(auth.substring(5)); - console.debug(vals); - setL402(vals); - - if (vals.invoice) { - const decoded = decodeInvoice(vals.invoice); - setInvoice(decoded); - } - } - } - } catch (e) { - console.error(e); - } - } - - async function payInvoice() { - if (wallet.wallet && l402) { - try { - const res = await wallet.wallet.payInvoice(l402.invoice); - console.debug(res); - if (res.preimage) { - const pmt = { - pr: l402.invoice, - url: props.url, - macaroon: l402.macaroon, - preimage: res.preimage, - }; - await PaymentsCache.set(pmt); - setAuth(pmt); - } - } catch (e) { - if (e instanceof Error) { - setError(e.message); - } - } - } - } - - async function loadMedia() { - if (!auth) return; - setLoading(true); - - const mediaReq = new Request(props.url, { - headers: { - Authorization: `L402 ${auth.macaroon}:${auth.preimage}`, - }, - }); - const rsp = await fetch(mediaReq); - if (rsp.ok) { - const buf = await rsp.blob(); - setUrl(URL.createObjectURL(buf)); - } - setLoading(false); - } - - useEffect(() => { - if (auth) { - loadMedia().catch(console.error); - } - }, [auth]); - - if (auth && loading) { - return ; - } - - if (invoice) { - return ( -
-

- -

-
-
- , - }} - /> -
-
- {wallet.wallet && ( - payInvoice()}> - - - )} -
-
- {!wallet.wallet && ( - - e.stopPropagation()}> - - - ), - }} - /> - - )} - {error && {error}} -
- ); - } - if (props.mime.startsWith("image/")) { - if (!(props.disableSpotlight ?? false)) { - return ( - - probeFor402()} /> - - ); - } else { - return probeFor402()} />; - } + return ; } else if (props.mime.startsWith("audio/")) { - return