[READ-ONLY] Mirror of https://github.com/mrgnw/morganwill.com. morganwill.com
0

Configure Feed

Select the types of activity you want to include in your feed.

~simplify link selection via host/params

+77 -108
+3
.rules
··· 1 1 - Use svelte 5 2 2 - Don't use $effect unless I explicitly tell you to 3 + 4 + 5 + Don't write summaries or guides unless I explicitly tell you to
+32 -58
src/routes/+page.server.js
··· 132 132 } 133 133 134 134 /** 135 - * Get links to display based on hostname and URL params 136 - * @param {Link[]} allLinks 135 + * Get titles to display based on hostname and URL params 137 136 * @param {string} hostname 138 - * @param {URLSearchParams} urlParams 139 - * @returns {{ links: Link[], qrMode: boolean }} 137 + * @param {string[] | null} requestedTitles 138 + * @returns {string[]} 140 139 */ 141 - function getFilteredLinks(allLinks, hostname, urlParams) { 142 - const { requestedTitles, qrMode } = parseUrlParams(urlParams); 143 - 144 - // Determine which titles to show 145 - let titlesToShow; 140 + function getTitlesToDisplay(hostname, requestedTitles) { 146 141 if (requestedTitles) { 147 - // URL params determine what's shown 148 - titlesToShow = requestedTitles; 149 - } else { 150 - // Use hostname defaults 151 - titlesToShow = hostDefaults[hostname] || [ 152 - "instagram", 153 - "linkedin", 154 - "bluesky", 155 - "telegram", 156 - ]; 142 + return requestedTitles; 157 143 } 144 + return ( 145 + hostDefaults[hostname] || ["instagram", "linkedin", "bluesky", "telegram"] 146 + ); 147 + } 158 148 159 - // Filter allLinks to only show requested ones 160 - const links = titlesToShow 149 + /** 150 + * Filter and build links with QR codes 151 + * @param {Link[]} allLinks 152 + * @param {string[]} titlesToShow 153 + * @returns {Promise<Link[]>} 154 + */ 155 + async function buildLinksWithQr(allLinks, titlesToShow) { 156 + // Filter to only requested titles 157 + const filteredLinks = titlesToShow 161 158 .map((title) => 162 159 allLinks.find((link) => link.title === title || link.alias === title), 163 160 ) 164 161 .filter(Boolean); 165 162 166 - return { links, qrMode }; 163 + // Generate QR codes only for displayed links 164 + const linksWithQr = await Promise.all( 165 + filteredLinks.map(async (link) => { 166 + const qr = generateAnimatedQRSvg(link.url, 164); 167 + return { ...link, qr }; 168 + }), 169 + ); 170 + 171 + return linksWithQr; 167 172 } 168 173 169 174 /** @type {import('./$types').PageServerLoad} */ ··· 172 177 const hostname = 173 178 request.headers.get("host")?.split(":")[0] ?? url.hostname ?? "localhost"; 174 179 175 - // Parse URL params once for both filtering and overrides 180 + // Parse URL params once 176 181 const { 177 182 requestedTitles, 178 183 overrides: paramOverrides, ··· 193 198 }) 194 199 .filter(Boolean); // Filter out null links (missing values) 195 200 196 - // Generate QR codes for all links 197 - const linksWithQr = await Promise.all( 198 - allLinks.map(async (link) => { 199 - const qr = generateAnimatedQRSvg(link.url, 164); 200 - return { ...link, qr }; 201 - }), 202 - ); 201 + // Determine which titles to display 202 + const titlesToShow = getTitlesToDisplay(hostname, requestedTitles); 203 203 204 - // Determine which links to show based on hostname and params 205 - let links; 206 - if (requestedTitles) { 207 - // URL params determine what's shown 208 - links = requestedTitles 209 - .map((title) => 210 - linksWithQr.find( 211 - (link) => link.title === title || link.alias === title, 212 - ), 213 - ) 214 - .filter(Boolean); 215 - } else { 216 - // Use hostname defaults 217 - const titlesToShow = hostDefaults[hostname] || [ 218 - "instagram", 219 - "linkedin", 220 - "bluesky", 221 - "telegram", 222 - ]; 223 - links = titlesToShow 224 - .map((title) => 225 - linksWithQr.find( 226 - (link) => link.title === title || link.alias === title, 227 - ), 228 - ) 229 - .filter(Boolean); 230 - } 204 + // Build links with QR codes (only for displayed links) 205 + const links = await buildLinksWithQr(allLinks, titlesToShow); 231 206 232 207 return { 233 208 links, 234 209 qrMode, 235 210 hostname, 236 - all_links: linksWithQr, 237 211 }; 238 212 }
+42 -50
src/routes/+page.svelte
··· 1 1 <script> 2 - import { fade } from "svelte/transition"; 3 - 4 - import Projects from "$components/Projects.svelte"; 5 - import LinkIcons from "$components/LinkIcons.svelte"; 2 + import { fade } from "svelte/transition"; 3 + import LinkIcons from "$components/LinkIcons.svelte"; 6 4 7 - let { data } = $props(); 5 + let { data } = $props(); 8 6 </script> 9 7 10 8 <svelte:head> 11 - <title>Morgan</title> 12 - <meta name="viewport" content="width=device-width, initial-scale=1" /> 13 - <meta 14 - name="description" 15 - content="Contact Morgan or view his other work on instagram, LinkedIn, or Github" 16 - /> 9 + <title>Morgan</title> 10 + <meta name="viewport" content="width=device-width, initial-scale=1" /> 11 + <meta 12 + name="description" 13 + content="Contact Morgan or view his other work on instagram, LinkedIn, or Github" 14 + /> 17 15 </svelte:head> 18 16 19 17 <div class="container"> 20 - <LinkIcons links={data.links} defaultTitle="Morgan" qrMode={data.qrMode} /> 18 + <LinkIcons links={data.links} defaultTitle="Morgan" qrMode={data.qrMode} /> 21 19 </div> 22 20 23 - {#if data.hostname === "morganwill.com"} 24 - <div transition:fade={{ duration: 500 }}> 25 - <Projects /> 26 - </div> 27 - {/if} 28 - 29 21 <style> 30 - :root { 31 - --primary: #000000; 32 - --default: rgba(0, 0, 0, 0.8); 33 - --highlight: rgb(30, 131, 255); 34 - --qr: rgb(30, 131, 255); 35 - --bg: #ffffff; 36 - background-color: var(--bg); 37 - } 22 + :root { 23 + --primary: #000000; 24 + --default: rgba(0, 0, 0, 0.8); 25 + --highlight: rgb(30, 131, 255); 26 + --qr: rgb(30, 131, 255); 27 + --bg: #ffffff; 28 + background-color: var(--bg); 29 + } 38 30 39 - @media (prefers-color-scheme: dark) { 40 - :root { 41 - --primary: white; 42 - --highlight: rgb(120, 180, 255); 43 - --default: rgba(255, 255, 255, 0.8); 44 - --qr: white; 45 - --bg: #000000; 46 - } 47 - } 31 + @media (prefers-color-scheme: dark) { 32 + :root { 33 + --primary: white; 34 + --highlight: rgb(120, 180, 255); 35 + --default: rgba(255, 255, 255, 0.8); 36 + --qr: white; 37 + --bg: #000000; 38 + } 39 + } 48 40 49 - :global(html, body) { 50 - height: 100vh; 51 - margin: 0; 52 - padding: 0; 53 - background-color: var(--bg); 54 - } 41 + :global(html, body) { 42 + height: 100vh; 43 + margin: 0; 44 + padding: 0; 45 + background-color: var(--bg); 46 + } 55 47 56 - .container { 57 - text-align: center; 58 - display: flex; 59 - flex-direction: column; 60 - justify-content: center; 61 - align-items: center; 62 - min-height: 100vh; 63 - padding: 2rem; 64 - } 48 + .container { 49 + text-align: center; 50 + display: flex; 51 + flex-direction: column; 52 + justify-content: center; 53 + align-items: center; 54 + min-height: 100vh; 55 + padding: 2rem; 56 + } 65 57 </style>