From 4a0a2444e112d5d124d15fabace948165f0d444f Mon Sep 17 00:00:00 2001 From: Yeghro <130201060+Yeghro@users.noreply.github.com> Date: Sat, 25 Jan 2025 20:21:48 -0800 Subject: [PATCH 1/4] managed to ensure all items included nested are parsed and available for display --- script.js | 162 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 114 insertions(+), 48 deletions(-) diff --git a/script.js b/script.js index e261c84..8ed8081 100644 --- a/script.js +++ b/script.js @@ -371,35 +371,8 @@ searchInput.addEventListener('input', (e) => { Object.entries(window.parsedResources).forEach(([sectionName, sectionContent]) => { sectionContent.forEach(item => { if (item.type === 'resources') { - // Search through resource lists - Array.from(item.element.children).forEach(li => { - const resourceName = li.querySelector('a')?.textContent || ''; - const resourceLink = li.querySelector('a')?.href || ''; - const resourceDescription = li.textContent.split('- ')[1]?.trim() || ''; - - const searchableText = [resourceName, resourceDescription, resourceLink] - .join(' ') - .toLowerCase(); - - if (searchableText.includes(searchTerm)) { - const card = createResourceCard({ - name: resourceName, - link: resourceLink, - description: resourceDescription, - stars: li.querySelector('img[alt="stars"]') - ? parseInt(li.querySelector('img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 - : 0 - }); - - // Add section label to card - const sectionLabel = document.createElement('div'); - sectionLabel.className = 'category-label'; - sectionLabel.textContent = sectionName; - card.insertBefore(sectionLabel, card.firstChild); - - container.appendChild(card); - } - }); + // Process both top-level and nested items for search + searchResourceList(item.element, container, searchTerm, sectionName); } else if (item.type === 'content') { // Search through regular content const contentText = item.element.textContent.toLowerCase(); @@ -430,6 +403,47 @@ searchInput.addEventListener('input', (e) => { } }); +// New helper function to search through resource lists recursively +function searchResourceList(ulElement, container, searchTerm, sectionName) { + Array.from(ulElement.children).forEach(li => { + // Search in the main item if it has a link + if (li.querySelector(':scope > a')) { + const resourceName = li.querySelector(':scope > a')?.textContent || ''; + const resourceLink = li.querySelector(':scope > a')?.href || ''; + const resourceDescription = li.childNodes[0].textContent.split('- ')[1]?.trim() || ''; + + const searchableText = [resourceName, resourceDescription, resourceLink] + .join(' ') + .toLowerCase(); + + if (searchableText.includes(searchTerm)) { + const card = createResourceCard({ + name: resourceName, + link: resourceLink, + description: resourceDescription, + stars: li.querySelector(':scope > img[alt="stars"]') + ? parseInt(li.querySelector(':scope > img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 + : 0 + }); + + // Add section label to card + const sectionLabel = document.createElement('div'); + sectionLabel.className = 'category-label'; + sectionLabel.textContent = sectionName; + card.insertBefore(sectionLabel, card.firstChild); + + container.appendChild(card); + } + } + + // Search in nested items if they exist + const nestedUl = li.querySelector(':scope > ul'); + if (nestedUl) { + searchResourceList(nestedUl, container, searchTerm, sectionName); + } + }); +} + // Add active class handling for navigation document.querySelectorAll('.nav-links a').forEach(link => { link.addEventListener('click', () => { @@ -579,11 +593,10 @@ function parseResources(content) { // Function to parse a single resource line function parseResourceLine(line) { - // Updated regex patterns to better handle various markdown formats + // Same regex patterns as before const nameRegex = /\[(.*?)\]/; const linkRegex = /\((.*?)\)/; const starsRegex = /!\[stars\].*?stars\/(.*?)\/.*?style=social/; - // Updated description regex to handle descriptions after stars badge const descriptionRegex = /style=social\) - (.*?)(?=(?:\[|\n|$))|(?:\) - )(.*?)(?=(?:\[|\n|$))/; try { @@ -591,7 +604,6 @@ function parseResourceLine(line) { const link = linkRegex.exec(line)?.[1]; const stars = starsRegex.exec(line)?.[1]; - // More robust description extraction const descMatch = descriptionRegex.exec(line); const description = (descMatch?.[1] || descMatch?.[2] || '').trim(); @@ -599,7 +611,7 @@ function parseResourceLine(line) { return { name, link, - stars: stars || 0, + stars: stars ? parseInt(stars) : 0, description: description || '', raw: line.trim() }; @@ -619,18 +631,59 @@ function createResourceCard(resource) { card.setAttribute('itemscope', ''); card.setAttribute('itemtype', 'https://schema.org/SoftwareApplication'); - // Extract domain for favicon + // Extract domain and build multiple fallback favicon URLs let faviconUrl = ''; try { const url = new URL(resource.link); - faviconUrl = `https://www.google.com/s2/favicons?domain=${url.hostname}&sz=64`; + const domain = url.hostname; + + // Try multiple favicon sources + const faviconSources = [ + `https://www.google.com/s2/favicons?domain=${domain}&sz=64`, + `https://${domain}/favicon.ico`, + `https://${domain}/favicon.png`, + `https://${domain}/apple-touch-icon.png`, + `https://${domain}/apple-touch-icon-precomposed.png` + ]; + + // Create image element with fallback chain + const img = document.createElement('img'); + img.className = 'resource-favicon'; + img.alt = ''; + + // Set first source as initial + img.src = faviconSources[0]; + + // Add error handling to try next source + let sourceIndex = 0; + img.onerror = () => { + sourceIndex++; + if (sourceIndex < faviconSources.length) { + img.src = faviconSources[sourceIndex]; + } else { + // If all sources fail, use a default icon + img.src = 'data:image/svg+xml,' + encodeURIComponent(` + + + + ${resource.name.charAt(0).toUpperCase()} + + + `); + img.onerror = null; // Remove error handler once default is shown + } + }; + + faviconUrl = img.outerHTML; } catch (e) { console.warn('Invalid URL:', resource.link); + // Use default icon for invalid URLs + faviconUrl = `
${resource.name.charAt(0).toUpperCase()}
`; } card.innerHTML = `
- ${faviconUrl ? `` : ''} + ${faviconUrl}

{ if (item.type === 'content') { - // Regular markdown content const contentDiv = document.createElement('div'); contentDiv.className = 'markdown-content'; contentDiv.innerHTML = item.element.outerHTML; container.appendChild(contentDiv); } else if (item.type === 'resources') { - // Resource list - Array.from(item.element.children).forEach(li => { - const card = createResourceCard({ - name: li.querySelector('a')?.textContent || '', - link: li.querySelector('a')?.href || '', - description: li.textContent.split('- ')[1]?.trim() || '', - stars: li.querySelector('img[alt="stars"]') - ? parseInt(li.querySelector('img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 - : 0 - }); - container.appendChild(card); + // Process both top-level and nested items + processResourceList(item.element, container); + } + }); +} + +// New helper function to process resource lists recursively +function processResourceList(ulElement, container) { + Array.from(ulElement.children).forEach(li => { + // Process the main item if it has a link + if (li.querySelector(':scope > a')) { + const card = createResourceCard({ + name: li.querySelector(':scope > a')?.textContent || '', + link: li.querySelector(':scope > a')?.href || '', + description: li.childNodes[0].textContent.split('- ')[1]?.trim() || '', + stars: li.querySelector(':scope > img[alt="stars"]') + ? parseInt(li.querySelector(':scope > img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 + : 0 }); + container.appendChild(card); + } + + // Process nested items if they exist + const nestedUl = li.querySelector(':scope > ul'); + if (nestedUl) { + processResourceList(nestedUl, container); } }); } From f3289d713a9803a96b04646d9f48355a311cf997 Mon Sep 17 00:00:00 2001 From: Yeghro <130201060+Yeghro@users.noreply.github.com> Date: Sat, 25 Jan 2025 20:48:02 -0800 Subject: [PATCH 2/4] added yeghro unfollow tool to the tools list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c9b3153..5ffa2ac 100644 --- a/README.md +++ b/README.md @@ -473,6 +473,7 @@ Websites with lists of relays and their performance/health: - [tostr](https://github.com/slaninas/tostr)![stars](https://img.shields.io/github/stars/slaninas/tostr.svg?style=social) - a twitter to nostr bot - [Undelete my Nostr](https://yonle.github.io/undelete-my-nostr)![stars](https://img.shields.io/github/stars/Yonle/undelete-my-nostr.svg?style=social) - Simple tool for restoring deleted nostr account. - [Zapper](https://zapper.nostrapps.org) - Nostr micro-app for zapping +- [YEGHRO unFollow Tool](https://unfollow.yeghro.com) - A tool that allows you to unfollow inactive users on nostr. ## NIP-05 identity services From d36f1e17e734bafca932231c64d6418aa6ca821a Mon Sep 17 00:00:00 2001 From: Yeghro <130201060+Yeghro@users.noreply.github.com> Date: Sat, 25 Jan 2025 21:31:06 -0800 Subject: [PATCH 3/4] missing descritptions fixed --- script.js | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/script.js b/script.js index 8ed8081..0261ee2 100644 --- a/script.js +++ b/script.js @@ -932,37 +932,24 @@ function displaySection(sectionName, sections) { // Display section content sections[sectionName].forEach(item => { if (item.type === 'content') { + // Regular markdown content const contentDiv = document.createElement('div'); contentDiv.className = 'markdown-content'; contentDiv.innerHTML = item.element.outerHTML; container.appendChild(contentDiv); } else if (item.type === 'resources') { - // Process both top-level and nested items - processResourceList(item.element, container); - } - }); -} - -// New helper function to process resource lists recursively -function processResourceList(ulElement, container) { - Array.from(ulElement.children).forEach(li => { - // Process the main item if it has a link - if (li.querySelector(':scope > a')) { - const card = createResourceCard({ - name: li.querySelector(':scope > a')?.textContent || '', - link: li.querySelector(':scope > a')?.href || '', - description: li.childNodes[0].textContent.split('- ')[1]?.trim() || '', - stars: li.querySelector(':scope > img[alt="stars"]') - ? parseInt(li.querySelector(':scope > img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 - : 0 + // Resource list + Array.from(item.element.children).forEach(li => { + const card = createResourceCard({ + name: li.querySelector('a')?.textContent || '', + link: li.querySelector('a')?.href || '', + description: li.textContent.split('- ')[1]?.trim() || '', + stars: li.querySelector('img[alt="stars"]') + ? parseInt(li.querySelector('img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 + : 0 + }); + container.appendChild(card); }); - container.appendChild(card); - } - - // Process nested items if they exist - const nestedUl = li.querySelector(':scope > ul'); - if (nestedUl) { - processResourceList(nestedUl, container); } }); } From e590560a8633d0b123dca71490ed2e0b4c792700 Mon Sep 17 00:00:00 2001 From: Yeghro <130201060+Yeghro@users.noreply.github.com> Date: Sat, 25 Jan 2025 21:50:39 -0800 Subject: [PATCH 4/4] search result improvements --- script.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/script.js b/script.js index 0261ee2..b93c4d2 100644 --- a/script.js +++ b/script.js @@ -410,9 +410,13 @@ function searchResourceList(ulElement, container, searchTerm, sectionName) { if (li.querySelector(':scope > a')) { const resourceName = li.querySelector(':scope > a')?.textContent || ''; const resourceLink = li.querySelector(':scope > a')?.href || ''; - const resourceDescription = li.childNodes[0].textContent.split('- ')[1]?.trim() || ''; + const description = li.textContent + .replace(resourceName, '') // Remove the resource name + .replace(/^\s*-\s*/, '') // Remove leading dash + .replace(/\s*\[!\[.*?\]\(.*?\)\]\(.*?\)\s*/, '') // Remove GitHub stars badge if present + .trim(); - const searchableText = [resourceName, resourceDescription, resourceLink] + const searchableText = [resourceName, description, resourceLink] .join(' ') .toLowerCase(); @@ -420,7 +424,7 @@ function searchResourceList(ulElement, container, searchTerm, sectionName) { const card = createResourceCard({ name: resourceName, link: resourceLink, - description: resourceDescription, + description: description, stars: li.querySelector(':scope > img[alt="stars"]') ? parseInt(li.querySelector(':scope > img[alt="stars"]').src.match(/stars\/(\d+)/)?.[1]) || 0 : 0