From 0d29c6ab70a7855feb40b55b55159812425cecf6 Mon Sep 17 00:00:00 2001 From: OFF0 Date: Sun, 19 Mar 2023 22:36:13 +0100 Subject: [PATCH] media: move noxy preview link fetch logic to media.ts --- src/main.js | 68 +----------------------------- src/media.ts | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 67 deletions(-) create mode 100644 src/media.ts diff --git a/src/main.js b/src/main.js index ec8aa15..9897fc3 100644 --- a/src/main.js +++ b/src/main.js @@ -9,6 +9,7 @@ import {clearView, getViewContent, getViewElem, setViewElem, view} from './view' import {closeSettingsView, config, toggleSettingsView} from './settings'; import {getReactions, getReactionContents, handleReaction, handleUpvote} from './reactions'; import {closePublishView, openWriteInput, togglePublishView} from './write'; +import {linkPreview, parseContent} from './media'; // curl -H 'accept: application/nostr+json' https://relay.nostr.ch/ @@ -129,64 +130,6 @@ setInterval(() => { }); }, 10000); -const fetchQue = []; -let fetchPending; -const fetchNext = (href, id, relay) => { - const noxy = getNoxyUrl('meta', href, id, relay); - const previewId = noxy.searchParams.toString(); - if (fetchPending) { - fetchQue.push({href, id, relay}); - return previewId; - } - fetchPending = fetch(noxy.href) - .then(data => { - if (data.status === 200) { - return data.json(); - } - // fetchQue.push({href, id, relay}); // could try one more time - return Promise.reject(data); - }) - .then(meta => { - const container = document.getElementById(previewId); - const content = []; - if (meta.images[0]) { - content.push(elem('img', {className: 'preview-image', loading: 'lazy', src: getNoxyUrl('data', meta.images[0], id, relay).href})); - } - if (meta.title) { - content.push(elem('h2', {className: 'preview-title'}, meta.title)); - } - if (meta.descr) { - content.push(elem('p', {className: 'preview-descr'}, meta.descr)) - } - if (content.length) { - container.append(elem('a', {href, rel: 'noopener noreferrer', target: '_blank'}, content)); - container.classList.add('preview-loaded'); - } - }) - .finally(() => { - fetchPending = false; - if (fetchQue.length) { - const {href, id, relay} = fetchQue.shift(); - return fetchNext(href, id, relay); - } - }) - .catch(err => err.text && err.text()) - .then(errMsg => errMsg && console.warn(errMsg)); - return previewId; -}; - -function linkPreview(href, id, relay) { - if ((/\.(gif|jpe?g|png)$/i).test(href)) { - return elem('div', {}, - [elem('img', {className: 'preview-image-only', loading: 'lazy', src: getNoxyUrl('data', href, id, relay).href})] - ); - } - const previewId = fetchNext(href, id, relay); - return elem('div', { - className: 'preview', - id: previewId - }); -} function createTextNote(evt, relay) { const {host, img, name, time, userName} = getMetadata(evt, relay); @@ -313,15 +256,6 @@ function renderArticle(content, props = {}) { const userList = []; // const tempContactList = {}; -function parseContent(content) { - try { - return JSON.parse(content); - } catch(err) { - console.log(evt); - console.error(err); - } -} - function handleMetadata(evt, relay) { const content = parseContent(evt.content); if (content) { diff --git a/src/media.ts b/src/media.ts new file mode 100644 index 0000000..5fa28c4 --- /dev/null +++ b/src/media.ts @@ -0,0 +1,114 @@ +import { elem } from './utils/dom'; +import { getNoxyUrl } from './utils/url'; + +export const parseContent = (content: string) => { + try { + return JSON.parse(content); + } catch(err) { + console.warn(err, content); + return null; + } +} + +type FetchItem = { + href: string; + id: string; + relay: string; +}; + +type NoxyData = { + title: string; + descr: string; + images: string[]; +}; + +const fetchQue: Array = []; + +let fetchPending: (null | Promise) = null; + +const fetchNext = ( + href: string, + id: string, + relay: string, +) => { + const noxy = getNoxyUrl('meta', href, id, relay); + if (!noxy) { + return false; + } + const previewId = noxy.searchParams.toString(); + if (fetchPending) { + fetchQue.push({href, id, relay}); + return previewId; + } + fetchPending = fetch(noxy.href) + .then(data => { + if (data.status === 200) { + return data.json(); + } + // fetchQue.push({href, id, relay}); // could try one more time + return Promise.reject(data); + }) + .then(meta => { + const container = document.getElementById(previewId); + const content: Array = []; + if (meta.images[0]) { + const img = getNoxyUrl('data', meta.images[0], id, relay); + img && content.push( + elem('img', { + className: 'preview-image', + loading: 'lazy', + src: img.href, + }) + ); + } + if (meta.title) { + content.push(elem('h2', {className: 'preview-title'}, meta.title)); + } + if (meta.descr) { + content.push(elem('p', {className: 'preview-descr'}, meta.descr)) + } + if (container && content.length) { + container.append(elem('a', {href, rel: 'noopener noreferrer', target: '_blank'}, content)); + container.classList.add('preview-loaded'); + } + }) + .finally(() => { + fetchPending = null; + if (fetchQue.length) { + const {href, id, relay} = fetchQue.shift() as FetchItem; + return fetchNext(href, id, relay); + } + }) + .catch(err => err.text && err.text()) + .then(errMsg => errMsg && console.warn(errMsg)); + + return previewId; +}; + +export const linkPreview = ( + href: string, + id: string, + relay: string, +) => { + if ((/\.(gif|jpe?g|png)$/i).test(href)) { + const img = getNoxyUrl('data', href, id, relay); + if (!img) { + return null; + } + return elem('div', {}, + [elem('img', { + className: 'preview-image-only', + loading: 'lazy', + src: img.href, + })] + ); + } + const previewId = fetchNext(href, id, relay); + if (!previewId) { + return null; + } + return elem('div', { + className: 'preview', + id: previewId, + }); +};