From 9a96a7aad8ce99cb355b090fd961f5b5e0c4f358 Mon Sep 17 00:00:00 2001 From: silberengel Date: Tue, 5 Aug 2025 17:46:08 +0200 Subject: [PATCH] fixed gaps in landing page feed. now always 10x column number. --- package-lock.json | 180 +++++++++--------- .../publications/PublicationFeed.svelte | 90 +++++++-- 2 files changed, 168 insertions(+), 102 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed96156..003bf33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2783,19 +2783,39 @@ } }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "devOptional": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/cliui": { @@ -3711,6 +3731,16 @@ } } }, + "node_modules/eslint-plugin-svelte/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -5953,17 +5983,27 @@ } }, "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "devOptional": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">= 14.18.0" + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/require-directory": { @@ -6471,6 +6511,36 @@ "typescript": ">=5.0.0" } }, + "node_modules/svelte-check/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/svelte-check/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/svelte-eslint-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-1.3.1.tgz", @@ -6671,54 +6741,6 @@ "node": ">=14.0.0" } }, - "node_modules/tailwindcss/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tailwindcss/node_modules/postcss-load-config": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", @@ -6767,30 +6789,6 @@ "node": ">=4" } }, - "node_modules/tailwindcss/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -7376,13 +7374,15 @@ } }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 6" + "node": ">= 14.6" } }, "node_modules/yargs": { diff --git a/src/lib/components/publications/PublicationFeed.svelte b/src/lib/components/publications/PublicationFeed.svelte index 48e4eba..1e6939c 100644 --- a/src/lib/components/publications/PublicationFeed.svelte +++ b/src/lib/components/publications/PublicationFeed.svelte @@ -27,6 +27,7 @@ let loading: boolean = $state(true); let hasInitialized = $state(false); let fallbackTimeout: ReturnType | null = null; + let gridContainer: HTMLElement; // Relay management let allRelays: string[] = $state([]); @@ -35,6 +36,35 @@ // Event management let allIndexEvents: NDKEvent[] = $state([]); + // Calculate the number of columns based on window width + let columnCount = $state(1); + let publicationsToDisplay = $state(10); + + // Update column count and publications when window resizes + $effect(() => { + if (typeof window !== 'undefined') { + const width = window.innerWidth; + let newColumnCount = 1; + if (width >= 1280) newColumnCount = 4; // xl:grid-cols-4 + else if (width >= 1024) newColumnCount = 3; // lg:grid-cols-3 + else if (width >= 768) newColumnCount = 2; // md:grid-cols-2 + + if (columnCount !== newColumnCount) { + columnCount = newColumnCount; + publicationsToDisplay = newColumnCount * 10; + + // Update the view immediately when column count changes + if (allIndexEvents.length > 0) { + const source = props.searchQuery?.trim() + ? filterEventsBySearch(allIndexEvents) + : allIndexEvents; + eventsInView = source.slice(0, publicationsToDisplay); + endOfFeed = eventsInView.length >= source.length; + } + } + } + }); + // Initialize relays and fetch events async function initializeAndFetch() { if (!ndk) { @@ -121,8 +151,8 @@ `[PublicationFeed] Using cached index events (${cachedEvents.length} events)`, ); allIndexEvents = cachedEvents; - eventsInView = allIndexEvents.slice(0, 30); - endOfFeed = allIndexEvents.length <= 30; + eventsInView = allIndexEvents.slice(0, publicationsToDisplay); + endOfFeed = allIndexEvents.length <= publicationsToDisplay; loading = false; return; } @@ -210,8 +240,8 @@ allIndexEvents.sort((a, b) => b.created_at! - a.created_at!); // Update the view immediately with new events - eventsInView = allIndexEvents.slice(0, 30); - endOfFeed = allIndexEvents.length <= 30; + eventsInView = allIndexEvents.slice(0, publicationsToDisplay); + endOfFeed = allIndexEvents.length <= publicationsToDisplay; console.debug(`[PublicationFeed] Updated view with ${newEvents.length} new events from ${relay}, total: ${allIndexEvents.length}`); } @@ -236,8 +266,8 @@ indexEventCache.set(allRelays, allIndexEvents); // Final update to ensure we have the latest view - eventsInView = allIndexEvents.slice(0, 30); - endOfFeed = allIndexEvents.length <= 30; + eventsInView = allIndexEvents.slice(0, publicationsToDisplay); + endOfFeed = allIndexEvents.length <= publicationsToDisplay; loading = false; } @@ -326,11 +356,11 @@ console.debug("[PublicationFeed] Search query changed:", query); if (query && query.trim()) { const filtered = filterEventsBySearch(allIndexEvents); - eventsInView = filtered.slice(0, 30); - endOfFeed = filtered.length <= 30; + eventsInView = filtered.slice(0, publicationsToDisplay); + endOfFeed = filtered.length <= publicationsToDisplay; } else { - eventsInView = allIndexEvents.slice(0, 30); - endOfFeed = allIndexEvents.length <= 30; + eventsInView = allIndexEvents.slice(0, publicationsToDisplay); + endOfFeed = allIndexEvents.length <= publicationsToDisplay; } }, 300); @@ -354,7 +384,7 @@ let source = props.searchQuery.trim() ? filterEventsBySearch(allIndexEvents) : allIndexEvents; - eventsInView = source.slice(0, current + 30); + eventsInView = source.slice(0, current + publicationsToDisplay); endOfFeed = eventsInView.length >= source.length; loadingMore = false; } @@ -388,14 +418,50 @@ cleanup(); }); - onMount(async () => { + onMount(() => { console.debug('[PublicationFeed] onMount called'); // The effect will handle fetching when relays become available + + // Add window resize listener for responsive updates + const handleResize = () => { + if (typeof window !== 'undefined') { + const width = window.innerWidth; + let newColumnCount = 1; + if (width >= 1280) newColumnCount = 4; // xl:grid-cols-4 + else if (width >= 1024) newColumnCount = 3; // lg:grid-cols-3 + else if (width >= 768) newColumnCount = 2; // md:grid-cols-2 + + if (columnCount !== newColumnCount) { + columnCount = newColumnCount; + publicationsToDisplay = newColumnCount * 10; + + // Update the view immediately when column count changes + if (allIndexEvents.length > 0) { + const source = props.searchQuery?.trim() + ? filterEventsBySearch(allIndexEvents) + : allIndexEvents; + eventsInView = source.slice(0, publicationsToDisplay); + endOfFeed = eventsInView.length >= source.length; + } + } + } + }; + + window.addEventListener('resize', handleResize); + + // Initial calculation + handleResize(); + + // Cleanup function + return () => { + window.removeEventListener('resize', handleResize); + }; });
{#if loading && eventsInView.length === 0}