From 02385bbe998f780359351fad5206c855d99013ce Mon Sep 17 00:00:00 2001 From: Akhilesh Thite Date: Sun, 26 May 2024 03:00:08 +0530 Subject: [PATCH] feat: add p2p URL support across all content in the reader --- actor-mini-profile.js | 3 ++- actor-profile.js | 3 ++- db.js | 14 ++++++++++++++ post.js | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/actor-mini-profile.js b/actor-mini-profile.js index 923cf66..f270ee7 100644 --- a/actor-mini-profile.js +++ b/actor-mini-profile.js @@ -1,4 +1,5 @@ import { db } from './dbInstance.js' +import { resolveP2PUrl } from './db.js' class ActorMiniProfile extends HTMLElement { static get observedAttributes () { @@ -50,7 +51,7 @@ class ActorMiniProfile extends HTMLElement { // Actor icon const img = document.createElement('img') img.className = 'profile-mini-icon' - img.src = iconUrl + img.src = resolveP2PUrl(iconUrl) img.alt = actorInfo.name ? actorInfo.name : 'Actor icon' clickableContainer.appendChild(img) diff --git a/actor-profile.js b/actor-profile.js index d04a676..6b78e37 100644 --- a/actor-profile.js +++ b/actor-profile.js @@ -1,4 +1,5 @@ import { db } from './dbInstance.js' +import { resolveP2PUrl } from './db.js' class ActorProfile extends HTMLElement { static get observedAttributes () { @@ -52,7 +53,7 @@ class ActorProfile extends HTMLElement { const img = document.createElement('img') img.classList.add('profile-icon') - img.src = iconUrl + img.src = resolveP2PUrl(iconUrl) img.alt = actorInfo.name ? actorInfo.name : 'Actor icon' actorContainer.appendChild(img) // Append to the actor container diff --git a/db.js b/db.js index f09b0c6..7ec6c64 100644 --- a/db.js +++ b/db.js @@ -42,6 +42,18 @@ export function isP2P (url) { return url.startsWith(HYPER_PREFIX) || url.startsWith(IPNS_PREFIX) } +export function resolveP2PUrl (url) { + if (!url) return url + + if (url.startsWith(HYPER_PREFIX)) { + return url.replace(HYPER_PREFIX, 'https://hyper.hypha.coop/hyper/') + } else if (url.startsWith(IPNS_PREFIX)) { + return url.replace(IPNS_PREFIX, 'https://ipfs.hypha.coop/ipns/') + } + + return url +} + export class ActivityPubDB extends EventTarget { constructor (db, fetch = globalThis.fetch) { super() @@ -103,6 +115,8 @@ export class ActivityPubDB extends EventTarget { if (url && typeof url === 'object') { return url } + url = resolveP2PUrl(url) + let response // Try fetching directly for all URLs (including P2P URLs) // TODO: Signed fetch diff --git a/post.js b/post.js index 2b7bd09..8fd5f3d 100644 --- a/post.js +++ b/post.js @@ -1,6 +1,7 @@ /* global customElements, HTMLElement */ import DOMPurify from './dependencies/dompurify/purify.js' import { db } from './dbInstance.js' +import { resolveP2PUrl } from './db.js' function formatDate (dateString) { const options = { year: 'numeric', month: 'short', day: 'numeric' } @@ -54,6 +55,7 @@ class DistributedPost extends HTMLElement { this.renderErrorContent('No post URL provided') return } + postUrl = resolveP2PUrl(postUrl) try { const content = await db.getNote(postUrl) @@ -120,6 +122,19 @@ class DistributedPost extends HTMLElement { const parser = new DOMParser() const contentDOM = parser.parseFromString(sanitizedContent, 'text/html') + const images = contentDOM.querySelectorAll('img') + images.forEach(img => { + const src = img.getAttribute('src') + console.log('Original src:', src) + img.setAttribute('src', resolveP2PUrl(src)) + }) + + const videos = contentDOM.querySelectorAll('video source') + videos.forEach(video => { + const src = video.getAttribute('src') + video.setAttribute('src', resolveP2PUrl(src)) + }) + // Process all anchor elements to handle actor and posts mentions const anchors = contentDOM.querySelectorAll('a') anchors.forEach(async (anchor) => { @@ -346,7 +361,7 @@ class ActorInfo extends HTMLElement { const img = document.createElement('img') img.classList.add('actor-icon') - img.src = iconUrl + img.src = resolveP2PUrl(iconUrl) img.alt = actorInfo.name ? actorInfo.name : 'Actor icon' img.addEventListener('click', this.navigateToActorProfile.bind(this)) author.appendChild(img)