diff --git a/CSS/cards.css b/CSS/cards.css index 7a7802f..230cb23 100644 --- a/CSS/cards.css +++ b/CSS/cards.css @@ -18,6 +18,7 @@ display: inline-block; /* makes each card flow naturally into columns */ margin-bottom: 16px; /* adds space between items vertically */ width: 100%; /* ensures card takes up the column width */ + cursor: pointer; } @@ -130,6 +131,7 @@ margin-top: 12px; width: 100%; text-align: right; + cursor: default; } /* repost section styling */ @@ -251,6 +253,7 @@ display: flex; justify-content: space-between; margin-top: 10px; + cursor: default; } /* individual action buttons */ @@ -374,3 +377,16 @@ background-color: #ffcc00; color: #4e004e; } + +.external-embed-container img { + width: -webkit-fill-available; +} + +.notallowed { + cursor: not-allowed !important; + color: #737373 !important; +} + +.notallowed:hover { + background-color: transparent !important; +} \ No newline at end of file diff --git a/CSS/singlepost.css b/CSS/singlepost.css new file mode 100644 index 0000000..330f719 --- /dev/null +++ b/CSS/singlepost.css @@ -0,0 +1,228 @@ +/* General Styles */ +body, html { + margin: 0; + padding: 0; + font-family: 'Arial', sans-serif; + background-color: #1a001a; /* Dark purple background */ + color: #e6e6ff; /* Light text for readability */ +} + +#post-container { + max-width: 700px; + margin: 0 auto; + padding: 20px; +} + +/* Card Styles */ +.post-card, .reply-card, .pinned-card { + background: #2a002e; /* Slightly lighter purple for cards */ + border-radius: 8px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); /* Subtle shadow for depth */ + padding: 16px; + margin-bottom: 16px; + cursor: pointer; +} + +/* Author Section */ +.author-section { + display: flex; + align-items: center; + gap: 12px; +} + +.card-avatar { + width: 50px; + height: 50px; + border-radius: 50%; + border: 2px solid #ffcc00; /* Golden border */ +} + +.author-info { + display: flex; + flex-direction: column; +} + +.author-name { + font-weight: bold; + font-size: 1.1rem; + color: #ffcc00; /* Golden for emphasis */ + margin: 0; +} + +.author-handle { + font-size: 0.9rem; + color: #b399ff; /* Muted light purple */ + margin: 0; +} + +/* Post Content */ +.post-text { + margin: 16px 0; + font-size: 1rem; + line-height: 1.5; + word-wrap: break-word; + color: #e6e6ff; /* Standard text color */ +} + +/* Media Embeds */ +.post-image, .reply-image { + max-width: 100%; + border-radius: 8px; + margin-top: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +.post-video { + max-width: 100%; + border-radius: 8px; + margin-top: 12px; + outline: none; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +/* External Links */ +.external-embed-container { + margin-top: 12px; + padding: 10px; + border-radius: 8px; + background: #3d1c3d; + color: #e6e6ff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +.external-embed-title { + font-weight: bold; + color: #ffcc00; + margin: 0 0 8px; +} + +.external-embed-description { + font-size: 0.9rem; + margin: 0 0 8px; + color: #b399ff; +} + +.external-embed-link { + color: #ffcc00; + text-decoration: none; + font-weight: bold; +} + +.external-embed-link:hover { + text-decoration: underline; +} + +.external-embed-container img { + width: -webkit-fill-available; +} + +/* Interaction buttons */ +.interaction-section { + display: flex; + justify-content: space-around; + margin-top: 12px; +} + +.interaction-button { + background: none; + border: none; + font-size: 1rem; + color: #b399ff; /* Muted light purple for buttons */ + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + transition: color 0.3s ease, transform 0.2s ease; +} + +.interaction-button:hover { + color: #ffcc00; /* Golden hover effect for buttons */ + transform: scale(1.1); /* Slightly enlarge button on hover */ +} + +/* Replies */ +.reply-card { + margin-left: 20px; + border-left: 2px solid #4e004e; /* Accent line for threading */ + padding-left: 16px; + background-color: #3d1c3d; +} + +/* Pinned Posts */ +.pinned-card { + border: 2px solid #ffcc00; /* Highlight pinned posts */ + background: #3d1c3d; +} + +.pinned-label { + font-size: 0.9rem; + font-weight: bold; + color: #ffcc00; + margin-bottom: 10px; +} + +/* Reposts or Shared Posts */ +.repost-section { + display: flex; + gap: 12px; + background: #3d1c3d; + padding: 10px; + border-radius: 8px; + margin-bottom: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} + +.repost-avatar { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.repost-info { + display: flex; + flex-direction: column; +} + +.repost-author { + font-size: 1rem; + font-weight: bold; + color: #ffcc00; +} + +.repost-text { + font-size: 0.85rem; + color: #b399ff; +} + +/* Threads */ +.reply-thread { + margin-left: 20px; + padding-left: 10px; + border-left: 2px solid #4e004e; +} + +#back-button-container { + position: fixed; + top: 20px; + left: 20px; + z-index: 1000; /* Ensures it stays on top */ +} + +#back-button { + display: inline-block; + padding: 10px 20px; + background-color: #4e004e; /* Dark purple background */ + color: #ffcc00; /* Golden text for contrast */ + font-size: 1rem; + font-weight: bold; + border: 2px solid #ffcc00; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +#back-button:hover { + background-color: #ffcc00; /* Golden hover effect */ + color: #4e004e; /* Dark purple text on hover */ + transform: scale(1.05); /* Slight zoom effect */ +} diff --git a/CSS/zoom.css b/CSS/zoom.css index 5bf1215..a1cf9b5 100644 --- a/CSS/zoom.css +++ b/CSS/zoom.css @@ -1,10 +1,9 @@ - /* zoom container styles */ .zoom-container { top: 5vh; position: fixed; display: inline-block; - overflow: hidden; + /* overflow: hidden; */ cursor: pointer; max-height: 90vh; max-width: 90vw; @@ -12,6 +11,10 @@ z-index: 9999; } +.hidden { + display: none; +} + /* initial image styling */ .zoom-video, .zoom-image { max-height: 88vh; @@ -20,6 +23,7 @@ cursor: pointer; border-radius: 8px; border: solid 2px lightblue; + width: auto; } /* styles for full-screen zoomed view */ diff --git a/HTML/index.html b/HTML/index.html index d375914..ddfde01 100644 --- a/HTML/index.html +++ b/HTML/index.html @@ -30,7 +30,7 @@ -
+ diff --git a/HTML/post.html b/HTML/post.html new file mode 100644 index 0000000..23f4303 --- /dev/null +++ b/HTML/post.html @@ -0,0 +1,20 @@ + + + + + + + + + Post Viewer + + + +
+ +
+ +
+ + + \ No newline at end of file diff --git a/JS/posts.cjs b/JS/posts.cjs index 02b9db5..9105390 100644 --- a/JS/posts.cjs +++ b/JS/posts.cjs @@ -9,9 +9,10 @@ function zoomimg(e) { zoomContainer.querySelector('img').style.display = ''; zoomContainer.querySelector('img').src = src; - zoomContainer.classList.toggle('zoomed'); overlayEl.classList.toggle('hidden'); - overlayEl.classList.toggle('show'); + zoomContainer.classList.toggle('zoomed'); + zoomContainer.classList.toggle('hidden'); + document.querySelector('.profile-container').classList.toggle('.noscroll'); } @@ -374,6 +375,8 @@ function setupWorker(name = 'bktemp') { } } +const statArr = [0, 0]; + /** * @param {*} post * @param {*} a @@ -387,11 +390,19 @@ function renderPostSingle(post, a, likes, ipcRenderer, container, idkey = 'bskyi const cardId = (post?.reply?.root?.uri || post.post.uri)?.trim(); // if the card exists, use it; otherwise, create a new card - if (a.has(cardId)) card = a.get(cardId); + if (a.has(cardId)) { + card = a.get(cardId); + statArr[0]++; + } else { card = document.createElement('div'); card.classList.add('post-card'); card.dataset[`${idkey}`] = cardId; + card.onclick = (e) => { + if (e.target !== card && !e.target.classList.contains('post-text')) return; + window.location.href = `../HTML/post.html?id=${encodeURI(card.dataset[`${idkey}`])}`; + } + statArr[1]++; } // handle repost reason if it hasn't been added to this card @@ -529,7 +540,7 @@ function renderPostSingle(post, a, likes, ipcRenderer, container, idkey = 'bskyi card.appendChild(textContent); } - // handle video embed (if present and not added yet) + // handle video embed if (post.post.embed && post.post.embed.$type === 'app.bsky.embed.video#view' && !card.querySelector('.post-video')) { const videoContainer = createVideoEl(), videoPlayer = videoContainer.querySelector('video'); @@ -599,11 +610,10 @@ function renderPostSingle(post, a, likes, ipcRenderer, container, idkey = 'bskyi const linkElement = document.createElement('a'); linkElement.classList.add('external-embed-link'); linkElement.href = embed.uri; - linkElement.target = '_blank'; // opens in a new tab - linkElement.rel = 'noopener noreferrer'; // improves security + linkElement.target = '_blank'; + linkElement.rel = 'noopener noreferrer'; // improves security (apparently) linkElement.textContent = 'Visit'; - // append elements to the container embedContainer.appendChild(titleElement); embedContainer.appendChild(descriptionElement); embedContainer.appendChild(linkElement); @@ -622,7 +632,7 @@ function renderPostSingle(post, a, likes, ipcRenderer, container, idkey = 'bskyi // add the card to the container if it's a new card if (!a.has(cardId)) { - const lurl = likes.find(o => (o.posturi === cardId)); + const lurl = likes?.find(o => (o.posturi === cardId)); if (lurl) card.dataset.likeuri = lurl.likeuri; card.appendChild(createButtonEls(card, ipcRenderer, idkey, containerid)); container.appendChild(card); @@ -652,12 +662,15 @@ module.exports = function renderPosts(posts, likes, pinnedPost, ipcRenderer, idk a = new Map(); } + statArr[0] = 0; + statArr[1] = 0; + for (const post of posts) { try { renderPostSingle( post, a, - likes.map(o => ({ posturi: o.post.uri, likeuri: o.post.viewer?.like })), + likes?.map(o => ({ posturi: o.post.uri, likeuri: o.post.viewer?.like })), ipcRenderer, container, idkey, @@ -669,8 +682,10 @@ module.exports = function renderPosts(posts, likes, pinnedPost, ipcRenderer, idk } } - const postids = Array.from(document.querySelectorAll(`[data-${idkey}]`)).map(o => o.dataset[`${idkey} `]); - console.log(postids); + console.info(`added ${statArr[1]} and updated ${statArr[0]} posts in "${containerid}"!`); + + // const postids = Array.from(document.querySelectorAll(`[data-${idkey}]`)).map(o => o.dataset[`${idkey} `]); + // console.log('duplicate ids', postids); // "force" garbage collection // delete a; diff --git a/JS/script.js b/JS/script.js index 827eab7..2a8c456 100644 --- a/JS/script.js +++ b/JS/script.js @@ -95,7 +95,7 @@ function togglerelaxed(e) { container.classList.remove('cards-container-relaxed'); container.classList.add('cards-container'); } else { - container.style.gridTemplateColumns = (value !== 'large') ? 'repeat(auto-fill, minmax(280px, 1fr))' : ''; + container.style.gridTemplateColumns = (value?.trim() !== 'large') ? 'repeat(auto-fill, minmax(280px, 1fr))' : 'none'; container.classList.remove('cards-container'); container.classList.add('cards-container-relaxed'); } diff --git a/JS/singlepost.cjs b/JS/singlepost.cjs new file mode 100644 index 0000000..c46ee5b --- /dev/null +++ b/JS/singlepost.cjs @@ -0,0 +1,185 @@ +const { formatStr } = require("../src/renderer.cjs"); + + +function renderPost(postData, post, isReply = false) { + const card = document.createElement('div'); + card.classList.add(isReply ? 'reply-card' : 'post-card'); + + if (post.pinned) { + const pinnedLabel = document.createElement('div'); + pinnedLabel.classList.add('pinned-label'); + pinnedLabel.textContent = '📌 Pinned'; + card.appendChild(pinnedLabel); + } + + card.dataset.bskyid = post.uri; + card.onclick = (e) => { + if (e.target !== card && !e.target.classList.contains('post-text')) return; + window.location.href = `../HTML/post.html?id=${encodeURI(card.dataset.bskyid)}`; + } + + // Author section + const authorSection = document.createElement('div'); + authorSection.classList.add('author-section'); + const avatar = document.createElement('img'); + avatar.loading = 'lazy'; + avatar.src = post.author.avatar; + avatar.alt = `${post.author.displayName}'s avatar`; + avatar.classList.add('card-avatar'); + const authorInfo = document.createElement('div'); + authorInfo.classList.add('author-info'); + const displayName = document.createElement('p'); + + displayName.innerHTML = formatStr(`@${post.author.handle}`); + if (post.author.displayName) displayName.textContent = post.author.displayName; + + displayName.classList.add('author-name'); + const handle = document.createElement('p'); + handle.innerHTML = formatStr(`@${post.author.handle}`); + handle.classList.add('author-handle'); + authorInfo.append(displayName, handle); + authorSection.append(avatar, authorInfo); + + // Post content + const postContent = document.createElement('p'); + postContent.textContent = post.record.text; + postContent.classList.add('post-text'); + + // Media (if exists) + if (post.embed?.images?.length > 0) { + const postMedia = document.createElement('img'); + postMedia.loading = 'lazy'; + postMedia.src = post.embed.images[0].fullsize; + postMedia.alt = post.embed.images[0].alt; + postMedia.classList.add('post-image'); + card.append(postMedia); + } + + if (post.embed && post.embed.$type === 'app.bsky.embed.external#view') { + const embedContainer = document.createElement('div'), + embed = post.embed.external; + + embedContainer.classList.add('external-embed-container'); + + // Check for thumbnail + if (embed.thumb) { + const thumbnail = document.createElement('img'); + thumbnail.loading = 'lazy'; + thumbnail.classList.add('external-embed-thumb'); + + // Use embed.uri for GIFs, otherwise use thumbnail + thumbnail.src = embed.uri.match(/\.gif(?:\?.*|$)/) ? embed.uri : embed.thumb; + + // Handle ALT descriptions if provided + if (embed.description.startsWith('ALT:') && embed.title === embed.description.substring(4).trim()) { + thumbnail.alt = embed.description.substring(4).trim(); + } else { + thumbnail.alt = `${embed.title} thumbnail`; + } + + embedContainer.appendChild(thumbnail); + } + + // Handle the case of an image with ALT only + if (!(embed.description.startsWith('ALT:') && embed.title === embed.description.substring(4).trim())) { + // Title + const titleElement = document.createElement('h3'); + titleElement.classList.add('external-embed-title'); + titleElement.textContent = embed.title; + + // Description + const descriptionElement = document.createElement('p'); + descriptionElement.classList.add('external-embed-description'); + descriptionElement.textContent = embed.description; + + // Link + const linkElement = document.createElement('a'); + linkElement.classList.add('external-embed-link'); + linkElement.href = embed.uri; + linkElement.target = '_blank'; + linkElement.rel = 'noopener noreferrer'; // Security improvement + linkElement.textContent = 'Visit'; + + // Append title, description, and link + embedContainer.appendChild(titleElement); + embedContainer.appendChild(descriptionElement); + embedContainer.appendChild(linkElement); + } + + card.appendChild(embedContainer); + } + + let interactionSection; + + if (isReply) { + interactionSection = document.createElement('div'); + interactionSection.classList.add('interaction-section'); + interactionSection.innerHTML = ` + 💬 ${post.replyCount}🔄 ${post.repostCount}❤️ ${post.likeCount} + `; + } + else { + interactionSection = document.createElement('div'); + interactionSection.classList.add('interaction-section'); + interactionSection.innerHTML = ` + + + + `; + } + + card.prepend(authorSection); + card.append(postContent); + card.append(interactionSection); + + if (!isReply) { + card.style.cursor = 'default'; + card.onclick = (_) => null; + } + + return card; +}; + + +async function renderMain(postData) { + const container = document.getElementById('post-container'); + if (!container) return alert("ERROR! CONTAINER NOT FOUND!"); + + console.log(postData); + + // Render main post + const mainPost = renderPost(postData, postData.post); + container.appendChild(mainPost); + + // Render replies + if (postData.replies && postData.replies.length > 0) { + const replyThread = document.createElement('div'); + replyThread.classList.add('reply-thread'); + postData.replies.forEach(reply => { + try { + const replyCard = renderPost(postData, reply.post, true); + replyThread.appendChild(replyCard); + } + catch (err) { + console.error('failed to render', reply, 'with reason\n', err); + } + }); + container.appendChild(replyThread); + } +} + + + +/** + * @param {Electron.IpcRenderer} ipcRenderer + */ +async function init(ipcRenderer) { + const params = new URLSearchParams(window.location.search), + bskyid = params.get('id'); + const r = await ipcRenderer.invoke('get-post-single', bskyid); + + renderMain(r); +} + + +module.exports = init; \ No newline at end of file diff --git a/bluesky/main.js b/bluesky/main.js index 2ebd130..757b8dc 100644 --- a/bluesky/main.js +++ b/bluesky/main.js @@ -127,7 +127,8 @@ async function getUserData(utag, allData = false) { if (allData) { const { data: { feed, cursor } } = await agent.getAuthorFeed({ actor: output.profile.did, limit: 20, includePins: true }), - { data: { feed: likes, cursor: likesCursor } } = await agent.getActorLikes({ actor: did }); + { data: { feed: likes, cursor: likesCursor } } = await agent.getActorLikes({ actor: output.profile.did }) + .catch(err => ({ data: { feed: [], cursor: undefined } })); output.likes = likes; output.likesCursor = likesCursor; @@ -140,7 +141,8 @@ async function getUserData(utag, allData = false) { return output; } catch (err) { - logger.error('failed to fetch user data:', err); + console.error(err); + logger.error(`failed to fetch user data for ${utag}:`); return {}; } } @@ -151,17 +153,27 @@ export const getPosts = async (utag, cursor = undefined, likesCursor = undefined const did = await getDID(utag); if (!did) return { err: 'DID not found!' }; - const likes = await agent.getActorLikes({ actor: did, cursor: likesCursor }), - posts = await agent.getAuthorFeed({ actor: did, limit: 20, includePins: true, cursor }); - return { posts, likes }; + const likes = await agent.getActorLikes({ actor: did, cursor: likesCursor }).catch(_ => ({ data: [] })), + posts = await agent.getAuthorFeed({ actor: did, limit: 30, includePins: true, cursor }); + return { posts: posts.data, likes: likes.data }; } catch (err) { console.error(err); - return { err: 'internal server error!' } + return { err: `internal server error for "${utag}"!` } } } +export const getPost = async (e, bskyid) => { + if (!bskyid) return 404; + + const [, did, collection, rkey] = bskyid.match(/^at:\/\/([^\/]+)\/([^\/]+)\/(.+)$/), + post = await agent.getPost({ repo: did, rkey, collection }); + + return (await agent.getPostThread({ uri: post.uri, depth: 3 })).data.thread; +} + + export const getLikes = async (utag, cursor = undefined) => { try { const did = await getDID(utag); @@ -269,5 +281,7 @@ export async function setupIPC() { ipcMain.handle('new-post', post); ipcMain.handle('upload-file', handleFileOpen); ipcMain.handle('post-action', async (e, action, id, condition) => await handlePostAction(e, action, id, agent, condition)); + + ipcMain.handle('get-post-single', getPost); } diff --git a/main.js b/main.js index 24c9693..0ae9cb8 100644 --- a/main.js +++ b/main.js @@ -51,6 +51,18 @@ const createMainWindow = () => { mainWindow = null // dereference the window object when closed }); + // mainWindow.webContents.on('will-navigate', (e, ustr, inPlace) => { + // const u = isURL(ustr); + // if (u.protocol === 'file:' && u.pathname === '/post') { + // // e.preventDefault(); + // // const bskyid = u.searchParams.get('id'); + + // // TODO: implement loading single post + // // maybe move this logic to the page itself via ipc and just + // // have this redirect to a file? + // } + // }); + mainWindow.webContents.on('did-navigate', (_, url) => { mainWindow.webContents.executeJavaScript('document.title') .then(title => insertHistory(url, title)); diff --git a/package-lock.json b/package-lock.json index cb6fcd3..0fb2283 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,15 +23,15 @@ } }, "node_modules/@atproto/api": { - "version": "0.13.14", - "resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.13.14.tgz", - "integrity": "sha512-CG5UpjI1WwSasSJTGadmr07EwWvl5JV658YZHcwIIg+Psk5sDloQOUJckuo1MP6wke1z6p/BUoPL4lxAATzMzA==", + "version": "0.13.18", + "resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.13.18.tgz", + "integrity": "sha512-rrl5HhzGYWZ7fiC965TPBUOVItq9M4dxMb6qz8IvAVQliSkrJrKc7UD0QWL89QiiXaOBuX8w+4i5r4wrfBGddg==", "license": "MIT", "dependencies": { "@atproto/common-web": "^0.3.1", - "@atproto/lexicon": "^0.4.2", - "@atproto/syntax": "^0.3.0", - "@atproto/xrpc": "^0.6.3", + "@atproto/lexicon": "^0.4.3", + "@atproto/syntax": "^0.3.1", + "@atproto/xrpc": "^0.6.4", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", @@ -51,31 +51,31 @@ } }, "node_modules/@atproto/lexicon": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.2.tgz", - "integrity": "sha512-CXoOkhcdF3XVUnR2oNgCs2ljWfo/8zUjxL5RIhJW/UNLp/FSl+KpF8Jm5fbk8Y/XXVPGRAsv9OYfxyU/14N/pw==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.3.tgz", + "integrity": "sha512-lFVZXe1S1pJP0dcxvJuHP3r/a+EAIBwwU7jUK+r8iLhIja+ml6NmYv8KeFHmIJATh03spEQ9s02duDmFVdCoXg==", "license": "MIT", "dependencies": { "@atproto/common-web": "^0.3.1", - "@atproto/syntax": "^0.3.0", + "@atproto/syntax": "^0.3.1", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "node_modules/@atproto/syntax": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.3.0.tgz", - "integrity": "sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.3.1.tgz", + "integrity": "sha512-fzW0Mg1QUOVCWUD3RgEsDt6d1OZ6DdFmbKcDdbzUfh0t4rhtRAC05KbZYmxuMPWDAiJ4BbbQ5dkAc/mNypMXkw==", "license": "MIT" }, "node_modules/@atproto/xrpc": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.6.3.tgz", - "integrity": "sha512-S3tRvOdA9amPkKLll3rc4vphlDitLrkN5TwWh5Tu/jzk7mnobVVE3akYgICV9XCNHKjWM+IAPxFFI2qi+VW6nQ==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.6.4.tgz", + "integrity": "sha512-9ZAJ8nsXTqC4XFyS0E1Wlg7bAvonhXQNQ3Ocs1L1LIwFLXvsw/4fNpIHXxvXvqTCVeyHLbImOnE9UiO1c/qIYA==", "license": "MIT", "dependencies": { - "@atproto/lexicon": "^0.4.2", + "@atproto/lexicon": "^0.4.3", "zod": "^3.23.8" } }, @@ -121,6 +121,51 @@ "global-agent": "^3.0.0" } }, + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/@electron/node-gyp": { "version": "10.2.0-electron.1", "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", @@ -146,23 +191,10 @@ "node": ">=12.13.0" } }, - "node_modules/@electron/node-gyp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@electron/rebuild": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.0.tgz", - "integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.1.tgz", + "integrity": "sha512-sKGD+xav4Gh25+LcLY0rjIwcCFTw+f/HU1pB48UVbwxXXRGaXEqIH0AaYKN46dgd/7+6kuiDXzoyAEvx1zCsdw==", "dev": true, "license": "MIT", "dependencies": { @@ -188,57 +220,6 @@ "node": ">=12.13.0" } }, - "node_modules/@electron/rebuild/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/rebuild/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/rebuild/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/@emnapi/runtime": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", @@ -654,19 +635,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/move-file": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", @@ -755,9 +723,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.17.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", - "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", + "version": "20.17.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.7.tgz", + "integrity": "sha512-sZXXnpBFMKbao30dUAvzKbdwA2JM1fwUtVEq/kxKuPI5mMwZiRElCpTXb0Biq/LMEVpXDZL5G5V0RPnxKeyaYg==", "dev": true, "license": "MIT", "dependencies": { @@ -798,18 +766,6 @@ "dev": true, "license": "ISC" }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -876,31 +832,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -983,7 +918,26 @@ "readable-stream": "^3.4.0" } }, - "node_modules/bl/node_modules/buffer": { + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", @@ -1007,49 +961,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1090,16 +1001,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/cacache/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -1147,10 +1048,14 @@ } }, "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, "node_modules/clean-stack": { "version": "2.2.0", @@ -1227,28 +1132,34 @@ } }, "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/color-string": { @@ -1271,6 +1182,31 @@ "text-hex": "1.0.x" } }, + "node_modules/colorspace/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/colorspace/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/colorspace/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1291,9 +1227,9 @@ "license": "MIT" }, "node_modules/cron": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/cron/-/cron-3.1.9.tgz", - "integrity": "sha512-eNZu+YhLRHLxNJNqZgYuy8mXhzMV0XXmOSh+Ls2j1yTeQLCQ04ya7oNpujxwl4lEyck1fcVa1aRVZ+T4tAC7SA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cron/-/cron-3.2.1.tgz", + "integrity": "sha512-w2n5l49GMmmkBFEsH9FIDhjZ1n1QgTMOCMGuQtOXs5veNiosZmso6bQGuqOJSYAXXrG84WQFVneNk+Yt0Ua9iw==", "license": "MIT", "dependencies": { "@types/luxon": "~3.4.0", @@ -1301,9 +1237,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -1457,9 +1393,9 @@ "optional": true }, "node_modules/electron": { - "version": "33.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-33.1.0.tgz", - "integrity": "sha512-7KiY6MtRo1fVFLPGyHS7Inh8yZfrbUTy43nNwUgMD2CBk729BgSwOC2WhmcptNJVlzHJpVxSWkiVi2hp9mH/bw==", + "version": "33.2.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-33.2.0.tgz", + "integrity": "sha512-PVw1ICAQDPsnnsmpNFX/b1i/49h67pbSPxuIENd9K9WpGO1tsRaQt+K2bmXqTuoMJsbzIc75Ce8zqtuwBPqawA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1582,24 +1518,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -1672,11 +1590,6 @@ "node": ">=18" } }, - "node_modules/fluent-ffmpeg/node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" - }, "node_modules/fluent-ffmpeg/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -1736,18 +1649,18 @@ "license": "MIT" }, "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=12" } }, "node_modules/fs-minipass": { @@ -1874,20 +1787,6 @@ "node": ">=10.0" } }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -2277,11 +2176,14 @@ "optional": true }, "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -2320,9 +2222,9 @@ } }, "node_modules/logform": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", - "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "license": "MIT", "dependencies": { "@colors/colors": "1.6.0", @@ -2626,18 +2528,6 @@ "node": ">=10" } }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-api-version": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz", @@ -2648,19 +2538,6 @@ "semver": "^7.3.5" } }, - "node_modules/node-api-version/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -2848,15 +2725,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -3133,13 +3001,15 @@ "optional": true }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-compare": { @@ -3206,49 +3076,6 @@ "@img/sharp-win32-x64": "0.33.5" } }, - "node_modules/sharp/node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/sharp/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/sharp/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3505,6 +3332,12 @@ "tar-stream": "^2.1.4" } }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -3521,16 +3354,6 @@ "node": ">=6" } }, - "node_modules/tar/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -3641,13 +3464,13 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" } }, "node_modules/util-deprecate": { @@ -3683,56 +3506,46 @@ } }, "node_modules/winston": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.16.0.tgz", - "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.6.0", + "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "winston-transport": "^4.9.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", - "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "license": "MIT", "dependencies": { - "logform": "^2.6.1", - "readable-stream": "^4.5.2", + "logform": "^2.7.0", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { "node": ">= 12.0.0" } }, - "node_modules/winston-transport/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } + "node_modules/winston/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", diff --git a/src/renderer.cjs b/src/renderer.cjs index 0f4f4f4..56363cf 100644 --- a/src/renderer.cjs +++ b/src/renderer.cjs @@ -1,6 +1,9 @@ const isURL = (ustr) => { - try { return new URL(ustr) } - catch (err) { return null } + try { + const validProtocols = ['http:', 'https:', 'ftp:', 'ftps:', 'sftp:', 'ws:', 'wss:', 'mailto:', 'tel:', 'file:', 'data:', 'irc:', 'geo:', 'rtsp:', 'magnet:'], + url = new URL(ustr); + return validProtocols.includes(url.protocol) ? url : false; + } catch { return false; } } diff --git a/src/user_page_preload.cjs b/src/user_page_preload.cjs index 41b1067..7228338 100644 --- a/src/user_page_preload.cjs +++ b/src/user_page_preload.cjs @@ -4,6 +4,12 @@ const renderPosts = require('../JS/posts.cjs'); const renderReplies = require('../JS/replies.cjs'); const { displayUploadStatus, renderCompose } = require('../JS/compose.cjs'); + +const disableTab = (tabid) => { + const el = document.querySelector(`#${tabid}Btn`); + el.outerHTML = '' +} + async function handleFileDialogue(e) { try { const file = e.target.files[0]; @@ -46,11 +52,15 @@ const appendEOF = (divid) => { window.addEventListener('DOMContentLoaded', () => { + if (window.location.pathname.endsWith('/post.html')) return require('../JS/singlepost.cjs')(ipcRenderer); + renderCompose(ipcRenderer); const query = new URLSearchParams(window.location.search); const utag = query.get('profile') || '@me'; ipcRenderer.on('udata', (e, dataRaw) => { + // REMOVE ALL CURSORS + sessionStorage.clear(); setupMutationObserver(); const data = JSON.parse(dataRaw), @@ -71,7 +81,8 @@ window.addEventListener('DOMContentLoaded', () => { if (data.posts) renderPosts(data.posts, data.likes || [], pObj?.pinnedPost, ipcRenderer); if (data.replies) renderReplies(data.replies); - if (data.likes) renderPosts(data.likes, data.likes, null, ipcRenderer, 'bskylikeid', 'likes'); + if (data.likes?.length) renderPosts(data.likes, data.likes, null, ipcRenderer, 'bskylikeid', 'likes'); + else disableTab('likes'); if (data.media) renderPosts(data.media.data, data.likes, null, ipcRenderer, 'bskymediaid', 'media'); }); @@ -105,7 +116,6 @@ window.addEventListener('DOMContentLoaded', () => { ipcRenderer.on('posts', (e, rawData) => { const data = JSON.parse(rawData); - console.log(data); // reset all videos because the cache was cleared document.querySelectorAll('.post-card video').forEach(video => { @@ -115,10 +125,12 @@ window.addEventListener('DOMContentLoaded', () => { }); if (data.err) return alert(data.err); - if (data.feed) renderPosts(data.posts, data.likes?.map(o => ({ posturi: o.post.uri, likeuri: o.post.viewer?.like })), null, ipcRenderer); + if (data.posts.feed) renderPosts(data.posts.feed, data.likes?.feed, null, ipcRenderer); - if (data.cursor) sessionStorage.setItem('postcursor', data.cursor); + if (data.posts.cursor) sessionStorage.setItem('postcursor', data.posts.cursor); else sessionStorage.removeItem('postcursor'); + + if (data.likes.cursor) sessionStorage.setItem('likescursor', data.likes.cursor); }); ipcRenderer.on('likes', (e, data) => {