your personal website on atproto - mirror blento.app

small fixes

Florian a53434f2 c3cdb964

+101 -74
+22
docs/Beta.md
··· 1 + # Todo for beta 2 + 3 + - opengraph stuff 4 + 5 + - title, description 6 + - fix opengraph image stuff 7 + 8 + - site.standard 9 + 10 + - move subpages to own lexicon 11 + - move description to markdownDescription and set description as text only 12 + - implement verification 13 + 14 + - fix recent blentos only showing the last ~5 15 + 16 + - card with big call to action button 17 + 18 + - link card: save favicon and og image as blobs 19 + 20 + - video card 21 + 22 + -
+1 -69
src/lib/cards/ImageCard/CreateImageCardModal.svelte
··· 1 1 <script lang="ts"> 2 2 import { Button, Input, Label, Modal, Subheading } from '@foxui/core'; 3 3 import type { CreationModalComponentProps } from '../types'; 4 + import { compressImage } from '$lib/helper'; 4 5 5 6 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props(); 6 7 ··· 15 16 16 17 item.cardData.blob = compressedFile; 17 18 item.cardData.objectUrl = URL.createObjectURL(compressedFile); 18 - } 19 - 20 - export function compressImage(file: File, maxSize: number = 600 * 1024): Promise<Blob> { 21 - return new Promise((resolve, reject) => { 22 - const img = new Image(); 23 - const reader = new FileReader(); 24 - 25 - reader.onload = (e) => { 26 - if (!e.target?.result) { 27 - return reject(new Error('Failed to read file.')); 28 - } 29 - img.src = e.target.result as string; 30 - }; 31 - 32 - reader.onerror = (err) => reject(err); 33 - reader.readAsDataURL(file); 34 - 35 - img.onload = () => { 36 - let width = img.width; 37 - let height = img.height; 38 - const maxDimension = 2048; 39 - 40 - if (width > maxDimension || height > maxDimension) { 41 - if (width > height) { 42 - height = Math.round((maxDimension / width) * height); 43 - width = maxDimension; 44 - } else { 45 - width = Math.round((maxDimension / height) * width); 46 - height = maxDimension; 47 - } 48 - } 49 - 50 - // Create a canvas to draw the image 51 - const canvas = document.createElement('canvas'); 52 - canvas.width = width; 53 - canvas.height = height; 54 - const ctx = canvas.getContext('2d'); 55 - if (!ctx) return reject(new Error('Failed to get canvas context.')); 56 - ctx.drawImage(img, 0, 0, width, height); 57 - 58 - // Function to try compressing at a given quality 59 - let quality = 0.8; 60 - function attemptCompression() { 61 - canvas.toBlob( 62 - (blob) => { 63 - if (!blob) { 64 - return reject(new Error('Compression failed.')); 65 - } 66 - // If the blob is under our size limit, or quality is too low, resolve it 67 - if (blob.size <= maxSize || quality < 0.3) { 68 - console.log('Compression successful. Blob size:', blob.size); 69 - console.log('Quality:', quality); 70 - resolve(blob); 71 - } else { 72 - // Otherwise, reduce the quality and try again 73 - quality -= 0.1; 74 - attemptCompression(); 75 - } 76 - }, 77 - 'image/jpeg', 78 - quality 79 - ); 80 - } 81 - 82 - attemptCompression(); 83 - }; 84 - 85 - img.onerror = (err) => reject(err); 86 - }); 87 19 } 88 20 89 21 let inputRef = $state<HTMLInputElement | null>(null);
+3 -3
src/lib/components/ImageDropper.svelte
··· 1 1 <script lang="ts"> 2 2 import { Portal } from 'bits-ui'; 3 3 4 - let isDragOver = $state(false); 5 - 6 4 let { 7 - processImageFile 5 + processImageFile, 6 + isDragOver = $bindable() 8 7 }: { 9 8 processImageFile: (file: File) => Promise<void>; 9 + isDragOver: boolean; 10 10 } = $props(); 11 11 12 12 function handleDragOver(event: DragEvent) {
+75 -1
src/lib/helper.ts
··· 38 38 return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y; 39 39 }; 40 40 41 - export function fixCollisions(items: Item[], movedItem: Item, mobile: boolean = false, skipCompact: boolean = false) { 41 + export function fixCollisions( 42 + items: Item[], 43 + movedItem: Item, 44 + mobile: boolean = false, 45 + skipCompact: boolean = false 46 + ) { 42 47 const clampX = (item: Item) => { 43 48 if (mobile) item.mobileX = clamp(item.mobileX, 0, COLUMNS - item.mobileW); 44 49 else item.x = clamp(item.x, 0, COLUMNS - item.w); ··· 326 331 } 327 332 } 328 333 } 334 + 335 + export function compressImage(file: File, maxSize: number = 900 * 1024): Promise<Blob> { 336 + return new Promise((resolve, reject) => { 337 + const img = new Image(); 338 + const reader = new FileReader(); 339 + 340 + reader.onload = (e) => { 341 + if (!e.target?.result) { 342 + return reject(new Error('Failed to read file.')); 343 + } 344 + img.src = e.target.result as string; 345 + }; 346 + 347 + reader.onerror = (err) => reject(err); 348 + reader.readAsDataURL(file); 349 + 350 + img.onload = () => { 351 + let width = img.width; 352 + let height = img.height; 353 + const maxDimension = 2048; 354 + 355 + if (width > maxDimension || height > maxDimension) { 356 + if (width > height) { 357 + height = Math.round((maxDimension / width) * height); 358 + width = maxDimension; 359 + } else { 360 + width = Math.round((maxDimension / height) * width); 361 + height = maxDimension; 362 + } 363 + } 364 + 365 + // Create a canvas to draw the image 366 + const canvas = document.createElement('canvas'); 367 + canvas.width = width; 368 + canvas.height = height; 369 + const ctx = canvas.getContext('2d'); 370 + if (!ctx) return reject(new Error('Failed to get canvas context.')); 371 + ctx.drawImage(img, 0, 0, width, height); 372 + 373 + // Function to try compressing at a given quality 374 + let quality = 0.8; 375 + function attemptCompression() { 376 + canvas.toBlob( 377 + (blob) => { 378 + if (!blob) { 379 + return reject(new Error('Compression failed.')); 380 + } 381 + // If the blob is under our size limit, or quality is too low, resolve it 382 + if (blob.size <= maxSize || quality < 0.3) { 383 + console.log('Compression successful. Blob size:', blob.size); 384 + console.log('Quality:', quality); 385 + resolve(blob); 386 + } else { 387 + // Otherwise, reduce the quality and try again 388 + quality -= 0.1; 389 + attemptCompression(); 390 + } 391 + }, 392 + 'image/jpeg', 393 + quality 394 + ); 395 + } 396 + 397 + attemptCompression(); 398 + }; 399 + 400 + img.onerror = (err) => reject(err); 401 + }); 402 + }
-1
src/lib/website/EditableWebsite.svelte
··· 10 10 Sidebar, 11 11 Popover, 12 12 Input, 13 - Label 14 13 } from '@foxui/core'; 15 14 import { BlueskyLogin } from '@foxui/social'; 16 15