your personal website on atproto - mirror blento.app
26
fork

Configure Feed

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

fix bluesky post card, improve resize handler

Florian 52338c09 593f3bc1

+84 -34
+2 -2
src/lib/EditableWebsite.svelte
··· 346 346 }} 347 347 onsetsize={(newW: number, newH: number) => { 348 348 if (isMobile) { 349 - item.mobileW = newW * 2; 350 - item.mobileH = newH * 2; 349 + item.mobileW = newW; 350 + item.mobileH = newH; 351 351 } else { 352 352 item.w = newW; 353 353 item.h = newH;
+4 -1
src/lib/cards/BaseCard/BaseCard.svelte
··· 17 17 item: Item; 18 18 controls?: Snippet<[]>; 19 19 isEditing?: boolean; 20 + showOutline?: boolean 20 21 } & WithElementRef<HTMLAttributes<HTMLDivElement>>; 21 22 22 23 let { ··· 25 26 ref = $bindable(null), 26 27 isEditing = false, 27 28 controls, 29 + showOutline, 28 30 ...rest 29 31 }: BaseCardProps = $props(); 30 32 ··· 39 41 class={[ 40 42 'card group focus-within:outline-accent-500 @container/card absolute z-0 rounded-2xl outline-offset-2 transition-all duration-200 focus-within:outline-2', 41 43 color ? (colors[color] ?? colors.accent) : colors.base, 42 - color !== 'accent' && item.color !== 'base' && item.color !== 'transparent' ? color : '' 44 + color !== 'accent' && item.color !== 'base' && item.color !== 'transparent' ? color : '', 45 + showOutline ? 'outline-2' : '' 43 46 ]} 44 47 style={` 45 48 --mx: ${item.mobileX};
+52 -28
src/lib/cards/BaseCard/BaseEditingCard.svelte
··· 58 58 59 59 const cardDef = $derived(CardDefinitionsByType[item.cardType]); 60 60 61 - const minW = $derived(cardDef.minW ?? 1); 62 - const minH = $derived(cardDef.minH ?? 1); 61 + const minW = $derived(cardDef.minW ?? (isMobile() ? 4 : 2)); 62 + const minH = $derived(cardDef.minH ?? (isMobile() ? 2 : 2)); 63 63 64 64 const maxW = $derived(cardDef.maxW ?? COLUMNS); 65 - const maxH = $derived(cardDef.maxH ?? COLUMNS); 65 + const maxH = $derived(cardDef.maxH ?? 6); 66 66 67 67 // Resize handle state 68 68 let isResizing = $state(false); ··· 78 78 resizeStartX = e.clientX; 79 79 resizeStartY = e.clientY; 80 80 // For mobile view, sizes are doubled so we need to account for that 81 - resizeStartW = isMobile() ? (item.mobileW ?? item.w) / 2 : item.w; 82 - resizeStartH = isMobile() ? (item.mobileH ?? item.h) / 2 : item.h; 81 + resizeStartW = isMobile() ? (item.mobileW ?? item.w) : item.w; 82 + resizeStartH = isMobile() ? (item.mobileH ?? item.h) : item.h; 83 83 84 84 document.addEventListener('pointermove', handleResizeMove); 85 85 document.addEventListener('pointerup', handleResizeEnd); ··· 99 99 const deltaX = e.clientX - resizeStartX; 100 100 const deltaY = e.clientY - resizeStartY; 101 101 102 + const refRect = ref.getBoundingClientRect(); 103 + 104 + console.log(Math.round(deltaX / cellSize)); 102 105 // Convert pixel delta to grid units (2 grid units = 1 visual cell) 103 106 const gridDeltaW = Math.round(deltaX / cellSize); 104 107 const gridDeltaH = Math.round(deltaY / cellSize); 105 108 106 - // Calculate new size (snap to even numbers since visual units are 2 grid units) 107 109 let newW = resizeStartW + gridDeltaW; 108 110 let newH = resizeStartH + gridDeltaH; 109 111 110 - // Snap to increments of 2 111 - newW = Math.round(newW / 2) * 2; 112 - newH = newH; 112 + console.log(item.mobileW, newW); 113 + if (isMobile()) { 114 + newW = Math.round(newW / 4) * 4; 115 + } else { 116 + newW = Math.round(newW / 2) * 2; 117 + } 118 + console.log(item.mobileW, newW); 113 119 114 120 // Clamp to min/max 115 121 newW = Math.max(minW, Math.min(maxW, newW)); 116 122 newH = Math.max(minH, Math.min(maxH, newH)); 117 123 118 124 // Only call onsetsize if size changed 119 - const currentW = isMobile() ? (item.mobileW ?? item.w) / 2 : item.w; 120 - const currentH = isMobile() ? (item.mobileH ?? item.h) / 2 : item.h; 125 + const currentW = isMobile() ? (item.mobileW ?? item.w) : item.w; 126 + const currentH = isMobile() ? (item.mobileH ?? item.h) : item.h; 121 127 122 128 if (newW !== currentW || newH !== currentH) { 123 129 onsetsize?.(newW, newH); ··· 131 137 } 132 138 </script> 133 139 134 - <BaseCard {item} {...rest} isEditing={true} bind:ref> 140 + <BaseCard {item} {...rest} isEditing={true} bind:ref showOutline={isResizing}> 135 141 {@render children?.()} 136 142 137 143 {#snippet controls()} ··· 243 249 </div> 244 250 </div> 245 251 246 - <!-- Resize handle at bottom right corner --> 247 - <!-- svelte-ignore a11y_no_static_element_interactions --> 248 - <div 249 - class={[ 250 - 'absolute -bottom-2 -right-2 z-50 cursor-se-resize rounded-full p-1 group-focus-within:flex group-hover:flex', 251 - isResizing ? 'flex' : 'hidden' 252 - ]} 253 - onpointerdown={handleResizeStart} 254 - > 255 - <div class="bg-base-100 dark:bg-base-800 border-base-300 dark:border-base-600 flex size-5 items-center justify-center rounded-full border shadow-md"> 252 + {#if cardDef.canResize !== false} 253 + <!-- Resize handle at bottom right corner --> 254 + <!-- svelte-ignore a11y_no_static_element_interactions --> 255 + <div 256 + class={[ 257 + 'absolute inset-0 z-50 cursor-se-resize items-end justify-end overflow-hidden rounded-2xl group-focus-within:flex group-hover:flex', 258 + isResizing ? 'flex' : 'hidden' 259 + ]} 260 + onpointerdown={handleResizeStart} 261 + > 256 262 <svg 257 263 xmlns="http://www.w3.org/2000/svg" 258 - viewBox="0 0 16 16" 259 - fill="currentColor" 260 - class="text-base-500 size-3" 264 + viewBox="0 0 24 24" 265 + fill="none" 266 + stroke="currentColor" 267 + stroke-width="2" 268 + stroke-linecap="round" 269 + stroke-linejoin="round" 270 + class="text-base-500 size-4" 261 271 > 262 - <path d="M5.5 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm0-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm4 4a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm0-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm0-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z" /> 272 + <circle cx="12" cy="5" r="1" /><circle cx="19" cy="5" r="1" /><circle 273 + cx="5" 274 + cy="5" 275 + r="1" 276 + /> 277 + <circle cx="12" cy="12" r="1" /><circle cx="19" cy="12" r="1" /><circle 278 + cx="5" 279 + cy="12" 280 + r="1" 281 + /> 282 + <circle cx="12" cy="19" r="1" /><circle cx="19" cy="19" r="1" /><circle 283 + cx="5" 284 + cy="19" 285 + r="1" 286 + /> 263 287 </svg> 288 + <span class="sr-only">Resize card</span> 264 289 </div> 265 - <span class="sr-only">Resize card</span> 266 - </div> 290 + {/if} 267 291 {/if} 268 292 {/snippet} 269 293 </BaseCard>
+22 -2
src/lib/cards/BlueskyPostCard/BlueskyPostCard.svelte
··· 1 1 <script lang="ts"> 2 2 import { getAdditionalUserData } from '$lib/helper'; 3 3 import type { Item } from '$lib/types'; 4 + import { onMount } from 'svelte'; 4 5 import { BlueskyPost } from '../../components/bluesky-post'; 6 + import { getDidContext, getHandleContext } from '$lib/website/context'; 7 + import { CardDefinitionsByType } from '..'; 5 8 6 9 let { item }: { item: Item } = $props(); 7 10 8 11 const data = getAdditionalUserData(); 9 12 // svelte-ignore state_referenced_locally 10 - const feed = (data[item.cardType] as any).feed; 13 + let feed = $state((data[item.cardType] as any)?.feed); 14 + 15 + let did = getDidContext(); 16 + let handle = getHandleContext(); 17 + 18 + onMount(async () => { 19 + if (!feed) { 20 + feed = ((await CardDefinitionsByType[item.cardType]?.loadData?.([], { 21 + did, 22 + handle, 23 + platform: undefined 24 + })) as any).feed 25 + 26 + console.log(feed); 27 + 28 + data[item.cardType] = feed; 29 + } 30 + }); 11 31 </script> 12 32 13 33 <div class="flex h-full flex-col justify-center-safe overflow-y-scroll p-4"> 14 - {#if feed?.[0].post} 34 + {#if feed?.[0]?.post} 15 35 <BlueskyPost showLogo feedViewPost={feed?.[0].post}></BlueskyPost> 16 36 <div class="h-4 w-full"></div> 17 37 {:else}
+2 -1
src/lib/cards/SectionCard/index.ts
··· 22 22 23 23 sidebarButtonText: 'Section Headline', 24 24 defaultColor: 'transparent', 25 - maxH: 1 25 + maxH: 1, 26 + canResize: false 26 27 } as CardDefinition & { type: 'section' };
+2
src/lib/cards/types.ts
··· 52 52 53 53 minH?: number; 54 54 maxH?: number; 55 + 56 + canResize?: boolean; 55 57 };