data endpoint for entity 90008 (aka. a website)
0
fork

Configure Feed

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

feat: add last updated date to status, instead of not displaying them, fix aligning of stuff

dusk b7d61fa0 fdbc62ce

+67 -53
+4 -13
src/components/note.svelte
··· 25 25 </script> 26 26 <script lang="ts"> 27 27 import Token from "./token.svelte"; 28 + import {renderDate, renderRelativeDate} from '$lib/dateFmt'; 28 29 29 30 interface Props { 30 31 note: NoteData; ··· 39 40 onlyContent = false, 40 41 showOutgoing = true 41 42 }: Props = $props(); 42 - 43 - const renderDate = (timestamp: number) => { 44 - return (new Date(timestamp)).toLocaleString("en-GB", { 45 - year: "2-digit", 46 - month: "2-digit", 47 - day: "2-digit", 48 - hour: "2-digit", 49 - minute: "2-digit", 50 - }) 51 - } 52 43 53 44 const getOutgoingLink = (name: string, link: string) => { 54 45 if (name === "bsky") { ··· 65 56 } 66 57 </script> 67 58 68 - <div class="text-wrap break-words max-w-[70ch] leading-tight"> 69 - {#if !onlyContent}<Token v={renderDate(note.published)} small={!isHighlighted}/>{/if} <Token v={note.content} str/> 59 + <p class="m-0 max-w-[70ch] text-wrap break-words leading-tight align-middle"> 60 + {#if !onlyContent}<Token title={renderDate(note.published)} v={renderRelativeDate(note.published)} small={!isHighlighted}/>{/if} <Token v={note.content} str/> 70 61 {#if note.hasMedia}<Token v="-contains media-" keywd small/>{/if} 71 62 {#if note.hasQuote}<Token v="-contains quote-" keywd small/>{/if} 72 63 {#if showOutgoing} ··· 75 66 <span class="text-sm"><Token v="(" punct/><a class="hover:motion-safe:animate-squiggle hover:underline" style="color: {color};{getTextShadowStyle(color)}" href={getOutgoingLink(name, link)}>{name}</a><Token v=")" punct/></span> 76 67 {/each} 77 68 {/if} 78 - </div> 69 + </p>
+3 -1
src/components/token.svelte
··· 8 8 str?: boolean; 9 9 small?: boolean; 10 10 v: string; 11 + title?: string; 11 12 } 12 13 13 14 let { ··· 16 17 funct = false, 17 18 str = false, 18 19 small = false, 20 + title, 19 21 v 20 22 }: Props = $props(); 21 23 ··· 27 29 : "" 28 30 </script> 29 31 30 - <span class="align-middle token {ty} {small ? "text-sm" : ""}">{v}</span> 32 + <span {title} class="token {ty} {small ? "text-sm" : ""}">{v}</span>
+25
src/lib/dateFmt.ts
··· 1 + export const renderRelativeDate = (timestamp: number) => { 2 + const elapsed = timestamp - (new Date()).getTime() 3 + const units: Record<string, number> = { 4 + year : 24 * 60 * 60 * 1000 * 365, 5 + month : 24 * 60 * 60 * 1000 * 365/12, 6 + day : 24 * 60 * 60 * 1000, 7 + hour : 60 * 60 * 1000, 8 + minute: 60 * 1000, 9 + second: 1000 10 + } 11 + const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }) 12 + for (var unit in units) 13 + if (Math.abs(elapsed) > units[unit] || unit == 'second') 14 + return rtf.format(Math.round(elapsed / units[unit]), unit as Intl.RelativeTimeFormatUnit) 15 + return "" 16 + } 17 + export const renderDate = (timestamp: number) => { 18 + return (new Date(timestamp)).toLocaleString("en-GB", { 19 + year: "2-digit", 20 + month: "2-digit", 21 + day: "2-digit", 22 + hour: "2-digit", 23 + minute: "2-digit", 24 + }) 25 + }
+8 -2
src/lib/lastfm.ts
··· 2 2 3 3 const GET_RECENT_TRACKS_ENDPOINT = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=yusdacra&api_key=da1911d405b5b37383e200b8f36ee9ec&format=json&limit=1" 4 4 5 - type LastTrack = {name: string, artist: string, image: string | null, link: string} 5 + type LastTrack = { 6 + name: string, 7 + artist: string, 8 + image: string | null, 9 + link: string, 10 + when: number, 11 + } 6 12 const lastTrack = writable<LastTrack | null>(null) 7 13 8 14 export const lastFmUpdateNowPlaying = async () => { ··· 17 23 artist: track.artist['#text'], 18 24 image: track.image[2]['#text'] ?? null, 19 25 link: track.url, 26 + when: Date.now(), 20 27 } 21 28 lastTrack.set(data) 22 29 } catch(why) { 23 30 console.log("could not fetch last fm: ", why) 24 - lastTrack.set(null) 25 31 } 26 32 } 27 33
+8 -2
src/lib/steam.ts
··· 5 5 const STEAM_ID = "76561198106829949" 6 6 const GET_PLAYER_SUMMARY_ENDPOINT = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=${STEAM_ID}&format=json` 7 7 8 - type LastGame = {name: string, link: string, icon: string, pfp: string} 8 + type LastGame = { 9 + name: string, 10 + link: string, 11 + icon: string, 12 + pfp: string, 13 + when: number, 14 + } 9 15 10 16 const steamgriddbClient = writable<SGDB | null>(null) 11 17 const lastGame = writable<LastGame | null>(null) ··· 28 34 link: `https://store.steampowered.com/app/${profile.gameid}`, 29 35 icon: icons[0].thumb.toString(), 30 36 pfp: profile.avatarmedium, 37 + when: Date.now(), 31 38 } 32 39 lastGame.set(game) 33 40 } catch(why) { 34 41 console.log("could not fetch steam: ", why) 35 - lastGame.set(null) 36 42 } 37 43 } 38 44
+19 -35
src/routes/+page.svelte
··· 3 3 import Note from '../components/note.svelte'; 4 4 import Window from '../components/window.svelte'; 5 5 import LatestStuff from './lateststuff.md'; 6 + import {renderDate, renderRelativeDate} from '$lib/dateFmt'; 6 7 7 8 interface Props { 8 9 data: any; 9 10 } 10 11 11 12 let { data }: Props = $props(); 12 - 13 - const renderDate = (timestamp: number) => { 14 - return (new Date(timestamp)).toLocaleString("en-GB", { 15 - year: "2-digit", 16 - month: "2-digit", 17 - day: "2-digit", 18 - hour: "2-digit", 19 - minute: "2-digit", 20 - }) 21 - } 22 - const renderRelativeDate = (timestamp: number) => { 23 - const elapsed = timestamp - (new Date()).getTime() 24 - const units: Record<string, number> = { 25 - year : 24 * 60 * 60 * 1000 * 365, 26 - month : 24 * 60 * 60 * 1000 * 365/12, 27 - day : 24 * 60 * 60 * 1000, 28 - hour : 60 * 60 * 1000, 29 - minute: 60 * 1000, 30 - second: 1000 31 - } 32 - const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }) 33 - for (var unit in units) 34 - if (Math.abs(elapsed) > units[unit] || unit == 'second') 35 - return rtf.format(Math.round(elapsed / units[unit]), unit as Intl.RelativeTimeFormatUnit) 36 - } 37 13 </script> 38 14 39 15 <div class="flex flex-col md:flex-row gap-y-2 lg:gap-y-0 md:h-full h-card"> ··· 182 158 </div> 183 159 {/if} 184 160 {#if data.lastTrack} 185 - <div class="flex flex-row m-1.5 border-4 border-double bg-ralsei-black"> 161 + <div class="flex flex-row gap-0.5 m-1.5 border-4 border-double bg-ralsei-black"> 186 162 <!-- svelte-ignore a11y_missing_attribute --> 187 163 {#if data.lastTrack.image} 188 164 <img 189 - class="border-4 w-16 h-16" 165 + class="border-4 w-[4.5rem] h-[4.5rem]" 190 166 style="border-style: none double none none;" 191 - width="64" 192 - height="64" 193 167 src={data.lastTrack.image} 194 168 /> 195 169 {:else} 196 170 <img 197 - class="border-4 w-16 h-16 p-2" 171 + class="border-4 w-[4.5rem] h-[4.5rem] p-2" 198 172 style="border-style: none double none none; image-rendering: pixelated;" 199 173 src="/icons/cd_audio.webp" 200 174 /> 201 175 {/if} 202 - <div class="flex flex-col max-w-[40ch] p-2 overflow-hidden"> 176 + <div class="flex flex-col max-w-[40ch] p-2"> 203 177 <p 204 - class="text-shadow-green text-ralsei-green-light text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 178 + class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 205 179 > 206 180 <span class="text-sm text-shadow-white text-ralsei-white">listening to</span> 207 181 <a ··· 216 190 <span class="text-shadow-white text-ralsei-white">by</span> 217 191 <span title={data.lastTrack.artist}>{data.lastTrack.artist}</span> 218 192 </p> 193 + <p 194 + class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 195 + > 196 + …{renderRelativeDate(data.lastTrack.when)} 197 + </p> 219 198 </div> 220 199 </div> 221 200 {/if} ··· 223 202 <div class="flex flex-row m-1.5 border-4 border-double bg-ralsei-black"> 224 203 <!-- svelte-ignore a11y_missing_attribute --> 225 204 <img 226 - class="border-4 w-16 h-16" 205 + class="border-4 w-[4.5rem] h-[4.5rem]" 227 206 style="border-style: none double none none;" 228 207 width="64" 229 208 height="64" 230 209 src={data.lastGame.icon} 231 210 /> 232 - <div class="flex flex-col max-w-[40ch] p-2 gap-1 overflow-hidden"> 211 + <div class="flex flex-col max-w-[40ch] p-2 gap-0.5 overflow-hidden"> 233 212 <p 234 - class="text-shadow-green text-ralsei-green-light text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 213 + class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 235 214 > 236 215 <span class="text-sm text-shadow-white text-ralsei-white">playing</span> 237 216 <a title={data.lastGame.name} class="hover:underline" href={data.lastGame.link} 238 217 >{data.lastGame.name}</a 239 218 > 219 + </p> 220 + <p 221 + class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[30ch]" 222 + > 223 + …{renderRelativeDate(data.lastGame.when)} 240 224 </p> 241 225 <!-- svelte-ignore a11y_missing_attribute --> 242 226 <a