your personal website on atproto - mirror blento.app

fixes

+118 -12
+14 -1
docs/Beta.md
··· 23 23 24 24 - when adding images try to add them in a size that best fits aspect ratio 25 25 26 - - onboarding 26 + - onboarding? 27 + 28 + - switch sidebar to a quick list of available cards with search function 29 + 30 + - test 31 + - selfhosting 32 + 33 + - guestbook card 34 + 35 + - analytics? 36 + 37 + - refresh recently updated blentos (move to top of list, update profiles every 24 hours) 38 + 39 + - server side oauth?
+2 -1
src/lib/atproto/settings.ts
··· 1 1 import { dev } from '$app/environment'; 2 + import { env } from '$env/dynamic/public'; 2 3 3 - export const SITE = 'https://blento.app'; 4 + export const SITE = env.PUBLIC_DOMAIN; 4 5 5 6 type Permissions = { 6 7 collections: readonly string[];
+102 -10
src/lib/cards/TimerCard/TimerCard.svelte
··· 62 62 eventDiff !== null ? Math.floor((eventDiff % (1000 * 60)) / 1000) : 0 63 63 ); 64 64 65 - let isEventComplete = $derived(cardData.mode === 'event' && eventDiff === 0); 65 + // Check if event is in the past (elapsed mode) 66 + let isEventPast = $derived.by(() => { 67 + if (cardData.mode !== 'event' || !cardData.targetDate) return false; 68 + const target = new Date(cardData.targetDate); 69 + return now.getTime() > target.getTime(); 70 + }); 71 + 72 + // Elapsed time since past event 73 + let elapsedDiff = $derived.by(() => { 74 + if (!isEventPast || !cardData.targetDate) return null; 75 + const target = new Date(cardData.targetDate); 76 + return now.getTime() - target.getTime(); 77 + }); 78 + 79 + let elapsedYears = $derived( 80 + elapsedDiff !== null ? Math.floor(elapsedDiff / (1000 * 60 * 60 * 24 * 365)) : 0 81 + ); 82 + let elapsedDays = $derived( 83 + elapsedDiff !== null 84 + ? Math.floor((elapsedDiff % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24)) 85 + : 0 86 + ); 87 + let elapsedHours = $derived( 88 + elapsedDiff !== null ? Math.floor((elapsedDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) : 0 89 + ); 90 + let elapsedMinutes = $derived( 91 + elapsedDiff !== null ? Math.floor((elapsedDiff % (1000 * 60 * 60)) / (1000 * 60)) : 0 92 + ); 93 + let elapsedSeconds = $derived( 94 + elapsedDiff !== null ? Math.floor((elapsedDiff % (1000 * 60)) / 1000) : 0 95 + ); 66 96 67 97 // Get timezone display name 68 98 let timezoneDisplay = $derived.by(() => { ··· 113 143 114 144 <!-- Event Countdown Mode --> 115 145 {:else if cardData.mode === 'event'} 116 - {#if eventDiff !== null && !isEventComplete} 146 + {#if isEventPast && elapsedDiff !== null} 147 + <!-- Elapsed time since past event --> 148 + <NumberFlowGroup> 149 + <div 150 + class="text-base-900 dark:text-base-100 accent:text-base-900 flex items-baseline gap-4 text-center @sm:gap-6 @md:gap-8" 151 + style="font-variant-numeric: tabular-nums;" 152 + > 153 + {#if elapsedYears > 0} 154 + <div class="flex flex-col items-center"> 155 + <NumberFlow 156 + value={elapsedYears} 157 + trend={1} 158 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 159 + /> 160 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs" 161 + >{elapsedYears === 1 ? 'year' : 'years'}</span 162 + > 163 + </div> 164 + {/if} 165 + {#if elapsedYears > 0 || elapsedDays > 0} 166 + <div class="flex flex-col items-center"> 167 + <NumberFlow 168 + value={elapsedDays} 169 + trend={1} 170 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 171 + /> 172 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs" 173 + >{elapsedDays === 1 ? 'day' : 'days'}</span 174 + > 175 + </div> 176 + {/if} 177 + <div class="flex flex-col items-center"> 178 + <NumberFlow 179 + value={elapsedHours} 180 + trend={1} 181 + format={{ minimumIntegerDigits: 2 }} 182 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 183 + /> 184 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs">hrs</span> 185 + </div> 186 + <div class="flex flex-col items-center"> 187 + <NumberFlow 188 + value={elapsedMinutes} 189 + trend={1} 190 + format={{ minimumIntegerDigits: 2 }} 191 + digits={{ 1: { max: 5 } }} 192 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 193 + /> 194 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs">min</span> 195 + </div> 196 + <div class="flex flex-col items-center"> 197 + <NumberFlow 198 + value={elapsedSeconds} 199 + trend={1} 200 + format={{ minimumIntegerDigits: 2 }} 201 + digits={{ 1: { max: 5 } }} 202 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 203 + /> 204 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs">sec</span> 205 + </div> 206 + </div> 207 + </NumberFlowGroup> 208 + {:else if eventDiff !== null} 209 + <!-- Countdown to future event --> 117 210 <NumberFlowGroup> 118 211 <div 119 212 class="text-base-900 dark:text-base-100 accent:text-base-900 flex items-baseline gap-4 text-center @sm:gap-6 @md:gap-8" ··· 121 214 > 122 215 {#if eventDays > 0} 123 216 <div class="flex flex-col items-center"> 124 - <NumberFlow value={eventDays} trend={-1} class="text-4xl font-bold" /> 125 - <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs">days</span 217 + <NumberFlow 218 + value={eventDays} 219 + trend={-1} 220 + class="text-3xl font-bold @xs:text-4xl @sm:text-5xl @md:text-6xl @lg:text-7xl" 221 + /> 222 + <span class="text-base-500 dark:text-base-400 accent:text-accent-950 text-xs" 223 + >{eventDays === 1 ? 'day' : 'days'}</span 126 224 > 127 225 </div> 128 226 {/if} ··· 157 255 </div> 158 256 </div> 159 257 </NumberFlowGroup> 160 - {:else if isEventComplete} 161 - <div 162 - class="text-accent-600 dark:text-accent-400 accent:text-accent-900 text-xl font-bold @xs:text-2xl @sm:text-3xl @md:text-4xl" 163 - > 164 - Event Started! 165 - </div> 166 258 {:else} 167 259 <div class="text-base-500 text-sm">Set a target date in settings</div> 168 260 {/if}