mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 17:19:40 +02:00
- Add uload project with apps/web structure
- Reorganize from flat to monorepo structure
- Remove PocketBase binary and local data
- Update to pnpm and @uload/web namespace
- Add picture project to monorepo
- Remove embedded git repository
- Unify all package names to @{project}/{app} schema:
- @maerchenzauber/* (was @storyteller/*)
- @manacore/* (was manacore-*, manacore)
- @manadeck/* (was web, backend, manadeck)
- @memoro/* (was memoro-web, landing, memoro)
- @picture/* (already unified)
- @uload/web
- Add convenient dev scripts for all apps:
- pnpm dev:{project}:web
- pnpm dev:{project}:landing
- pnpm dev:{project}:mobile
- pnpm dev:{project}:backend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
/**
|
|
* Image utility functions for handling Supabase Storage transformations
|
|
*/
|
|
|
|
export type ThumbnailSize = 'tiny' | 'small' | 'medium' | 'full';
|
|
|
|
/**
|
|
* Get the appropriate thumbnail URL based on the view mode or size requirement
|
|
*
|
|
* Supabase Storage Transformations: https://supabase.com/docs/guides/storage/serving/image-transformations
|
|
* Format: {storage-url}/render/image/authenticated/{bucket}/{path}?width={w}&height={h}
|
|
*/
|
|
export function getThumbnailUrl(
|
|
publicUrl: string | null,
|
|
size: ThumbnailSize = 'medium'
|
|
): string | null {
|
|
if (!publicUrl) return null;
|
|
|
|
// If it's already a full URL with transformations, return as is
|
|
if (publicUrl.includes('?width=') || publicUrl.includes('&width=')) {
|
|
return publicUrl;
|
|
}
|
|
|
|
// Determine dimensions based on size
|
|
const dimensions: Record<ThumbnailSize, number> = {
|
|
tiny: 100, // For grid5 view
|
|
small: 200, // For grid3 view
|
|
medium: 400, // For single view
|
|
full: 0, // No transformation, use original
|
|
};
|
|
|
|
const targetSize = dimensions[size];
|
|
|
|
// If full resolution requested, return original URL
|
|
if (targetSize === 0) {
|
|
return publicUrl;
|
|
}
|
|
|
|
// Parse the Supabase Storage URL
|
|
// Expected format: https://{project}.supabase.co/storage/v1/object/public/{bucket}/{path}
|
|
const url = new URL(publicUrl);
|
|
|
|
// Add transformation parameters
|
|
url.searchParams.set('width', targetSize.toString());
|
|
url.searchParams.set('height', targetSize.toString());
|
|
url.searchParams.set('resize', 'cover'); // Crop to fill the dimensions
|
|
url.searchParams.set('quality', '80'); // Good balance between quality and file size
|
|
|
|
return url.toString();
|
|
}
|
|
|
|
/**
|
|
* Get thumbnail size based on view mode
|
|
*/
|
|
export function getSizeForViewMode(viewMode: 'single' | 'grid3' | 'grid5'): ThumbnailSize {
|
|
switch (viewMode) {
|
|
case 'grid5':
|
|
return 'tiny';
|
|
case 'grid3':
|
|
return 'small';
|
|
case 'single':
|
|
return 'medium';
|
|
default:
|
|
return 'medium';
|
|
}
|
|
}
|