fix(media): use Appwrite /view endpoint instead of /preview for Cloud compatibility

This commit is contained in:
AI Bot 2026-11-07 15:42:19 -05:00
parent 45ecec69aa
commit 9a134b12ab
20 changed files with 29 additions and 35 deletions

View File

@ -11,7 +11,7 @@ export interface ImageOptimizationOptions {
format?: 'webp' | 'avif' | 'jpg' | 'png';
}
const DEFAULT_PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
const DEFAULT_PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
export function getOptimizedImageUrl(
url?: string | null,
@ -42,26 +42,20 @@ export function getOptimizedImageUrl(
const format = options.format || 'webp';
try {
// 1. Appwrite Storage URL Optimization
// 1. Appwrite Storage URL Optimization (use /view for Appwrite Cloud Free Plan compatibility)
if (trimmed.includes('/storage/buckets/') && (trimmed.includes('/files/') || trimmed.includes('/view') || trimmed.includes('/preview'))) {
let optimized = trimmed;
// Convert /view to /preview for Appwrite image transformation engine
if (optimized.includes('/view')) {
optimized = optimized.replace('/view', '/preview');
} else if (!optimized.includes('/preview') && optimized.includes('/files/')) {
// e.g. /files/fileId -> /files/fileId/preview
if (optimized.includes('/preview')) {
optimized = optimized.replace('/preview', '/view');
} else if (!optimized.includes('/view') && optimized.includes('/files/')) {
const regex = /(\/files\/[^\/\?]+)(.*)/;
optimized = optimized.replace(regex, '$1/preview$2');
optimized = optimized.replace(regex, '$1/view$2');
}
const urlObj = new URL(optimized, 'https://appwrite.almeira.com.co');
const urlObj = new URL(optimized, 'https://nyc.cloud.appwrite.io');
if (!urlObj.searchParams.has('project')) {
urlObj.searchParams.set('project', DEFAULT_PROJECT_ID);
}
urlObj.searchParams.set('width', width.toString());
urlObj.searchParams.set('height', height.toString());
urlObj.searchParams.set('quality', quality.toString());
urlObj.searchParams.set('output', format);
return urlObj.toString();
}

View File

@ -177,7 +177,7 @@ export async function generateMetadata(
const client = await createAdminClient();
const mediaRes = await client.databases.getDocument(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', post.imagen_destacada_id);
if (mediaRes) {
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaRes.bucket_id}/files/${mediaRes.file_id}/preview?project=${PROJECT_ID}&width=1200&height=630&quality=90`;
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaRes.bucket_id}/files/${mediaRes.file_id}/view?project=${PROJECT_ID}&width=1200&height=630&quality=90`;
}
} catch(e) {}
}
@ -231,7 +231,7 @@ export default async function NoticiaDetail({ params }: { params: Promise<{ slug
const client = await createAdminClient();
const mediaRes = await client.databases.getDocument(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', post.imagen_destacada_id);
if (mediaRes) {
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaRes.bucket_id}/files/${mediaRes.file_id}/preview?project=${PROJECT_ID}&width=640&height=${imgHeight}&quality=90`;
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaRes.bucket_id}/files/${mediaRes.file_id}/view?project=${PROJECT_ID}&width=640&height=${imgHeight}&quality=90`;
}
} catch(e) {}
}

View File

@ -12,7 +12,7 @@ function getAppwriteImageUrl(fileId: string, bucketId?: string, width = 400, hei
if (isVideo) {
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/view?project=${projectId}`;
}
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/preview?project=${projectId}&width=${width}&height=${height}&quality=80`;
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/view?project=${projectId}&width=${width}&height=${height}&quality=80`;
}
export const runtime = 'nodejs';

View File

@ -397,7 +397,7 @@ function detectExplicitPublicationType(inputText: string): 'noticia' | 'evento'
let ogImageUrl = undefined;
if (storageFileId) {
ogImageUrl = `${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${APPWRITE_ALMEIRA_CONFIG.mediaBucketId}/files/${storageFileId}/preview?project=${APPWRITE_ALMEIRA_CONFIG.projectId}&width=640&height=${imgHeight}&gravity=${gravity}&quality=85`;
ogImageUrl = `${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${APPWRITE_ALMEIRA_CONFIG.mediaBucketId}/files/${storageFileId}/view?project=${APPWRITE_ALMEIRA_CONFIG.projectId}&width=640&height=${imgHeight}&gravity=${gravity}&quality=85`;
}
// Determinar fecha de vencimiento

View File

@ -140,7 +140,7 @@ export default async function ClasificadosPage() {
const mediaObj = post.resolved_media || (typeof post.imagen_destacada_id === 'object' ? post.imagen_destacada_id : null) as MediaItem | null;
if (mediaObj) {
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/preview?project=${PROJECT_ID}&width=640&height=640&quality=80`;
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/view?project=${PROJECT_ID}&width=640&height=640&quality=80`;
}
return (

View File

@ -73,7 +73,7 @@ export default async function EntityPage() {
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
let logoUrl = entity?.logotipo || '';
if (logoUrl && !logoUrl.startsWith('http') && !logoUrl.startsWith('/')) {
logoUrl = `${ENDPOINT}/storage/buckets/media/files/${logoUrl}/view?project=${PROJECT_ID}`;
logoUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${logoUrl}/view?project=${PROJECT_ID}`;
}
return <EntityLogoField initialUrl={logoUrl} />;
})()}

View File

@ -140,7 +140,7 @@ export default async function EventosPage() {
const mediaObj = post.resolved_media || (typeof post.imagen_destacada_id === 'object' ? post.imagen_destacada_id : null) as MediaItem | null;
if (mediaObj) {
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/preview?project=${PROJECT_ID}&width=640&height=640&quality=80`;
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/view?project=${PROJECT_ID}&width=640&height=640&quality=80`;
}
return (

View File

@ -16,7 +16,7 @@ export async function generateMetadata(): Promise<Metadata> {
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
let logoUrl = entity?.logotipo || null;
if (logoUrl && !logoUrl.startsWith('http') && !logoUrl.startsWith('/')) {
logoUrl = `${ENDPOINT}/storage/buckets/media/files/${logoUrl}/view?project=${PROJECT_ID}`;
logoUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${logoUrl}/view?project=${PROJECT_ID}`;
}
return {

View File

@ -9,7 +9,7 @@ export default async function LoginPage() {
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
let logoUrl = entity?.logotipo || null;
if (logoUrl && !logoUrl.startsWith('http') && !logoUrl.startsWith('/')) {
logoUrl = `${ENDPOINT}/storage/buckets/media/files/${logoUrl}/view?project=${PROJECT_ID}`;
logoUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${logoUrl}/view?project=${PROJECT_ID}`;
}
return (

View File

@ -224,7 +224,7 @@ export default async function Home(props: { searchParams: Promise<{ [key: string
const mediaObj = post.resolved_media || (typeof post.imagen_destacada_id === 'object' ? post.imagen_destacada_id : null) as MediaItem | null;
if (mediaObj) {
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/preview?project=${PROJECT_ID}&width=640&height=${imgHeight}&quality=85`;
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaObj.bucket_id}/files/${mediaObj.file_id}/view?project=${PROJECT_ID}&width=640&height=${imgHeight}&quality=85`;
}
return (

View File

@ -52,7 +52,7 @@ function ClientCarouselGroup({ eslogan, ads, rotationSeconds }: { eslogan: strin
if (typeof activeAd.imagen_destacada_id === 'object' && activeAd.imagen_destacada_id.bucket_id) {
imgUrl = `${ENDPOINT}/storage/buckets/${activeAd.imagen_destacada_id.bucket_id}/files/${activeAd.imagen_destacada_id.file_id}/view?project=${PROJECT_ID}`;
} else if (typeof activeAd.imagen_destacada_id === 'string') {
imgUrl = `${ENDPOINT}/storage/buckets/media/files/${activeAd.imagen_destacada_id}/view?project=${PROJECT_ID}`;
imgUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${activeAd.imagen_destacada_id}/view?project=${PROJECT_ID}`;
}
}

View File

@ -15,7 +15,7 @@ export const Navbar = ({ entity }: { entity?: any }) => {
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
let logoUrl = entity?.logotipo || null;
if (logoUrl && !logoUrl.startsWith('http') && !logoUrl.startsWith('/')) {
logoUrl = `${ENDPOINT}/storage/buckets/media/files/${logoUrl}/view?project=${PROJECT_ID}`;
logoUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${logoUrl}/view?project=${PROJECT_ID}`;
}
useEffect(() => {

View File

@ -55,7 +55,7 @@ export default async function NewsTicker() {
const media = typeof post.imagen_destacada_id === 'object' ? post.imagen_destacada_id : mediaMap.get(post.imagen_destacada_id);
let imagenUrl = post.og_image_url || null;
if (media) {
imagenUrl = `${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${media.bucket_id}/files/${media.file_id}/preview?project=${APPWRITE_ALMEIRA_CONFIG.projectId}`;
imagenUrl = `${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${media.bucket_id}/files/${media.file_id}/view?project=${APPWRITE_ALMEIRA_CONFIG.projectId}`;
}
tickerItems.push({

View File

@ -33,10 +33,10 @@ export default function TopBanner({ initialBanners, rotationSeconds }: { initial
if (activeBanner.imagen_destacada_id) {
if (typeof activeBanner.imagen_destacada_id === 'object' && activeBanner.imagen_destacada_id.bucket_id) {
imgUrl = `${ENDPOINT}/storage/buckets/${activeBanner.imagen_destacada_id.bucket_id}/files/${activeBanner.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
imgUrl = `${ENDPOINT}/storage/buckets/${activeBanner.imagen_destacada_id.bucket_id}/files/${activeBanner.imagen_destacada_id.file_id}/view?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
} else if (typeof activeBanner.imagen_destacada_id === 'string') {
// Fallback to 'media' bucket if we only have the ID
imgUrl = `${ENDPOINT}/storage/buckets/media/files/${activeBanner.imagen_destacada_id}/preview?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
imgUrl = `${ENDPOINT}/storage/buckets/media_bucket/files/${activeBanner.imagen_destacada_id}/view?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
}
}

View File

@ -13,7 +13,7 @@ export function getAppwriteImageUrl(fileId: string, bucketId?: string, width = 4
if (isVideo) {
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/view?project=${projectId}`;
}
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/preview?project=${projectId}&width=${width}&height=${height}&quality=80`;
return `${endpoint}/storage/buckets/${finalBucketId}/files/${fileId}/view?project=${projectId}&width=${width}&height=${height}&quality=80`;
}
interface MediaGridSelectorProps {

View File

@ -60,7 +60,7 @@ export const MediaPickerMini = ({ value, onChange, label }: MediaPickerMiniProps
}, [searchTerm, isOpen]);
const getImageUrl = (fileId: string) => {
return `${endpoint}/storage/buckets/media/files/${fileId}/view?project=${projectId}&width=200&height=200&gravity=center`;
return `${endpoint}/storage/buckets/media_bucket/files/${fileId}/view?project=${projectId}&width=200&height=200&gravity=center`;
};
const filteredItems = mediaItems;
@ -91,7 +91,7 @@ export const MediaPickerMini = ({ value, onChange, label }: MediaPickerMiniProps
{value ? (
<>
<img
src={`${endpoint}/storage/buckets/media/files/${value}/view?project=${projectId}`}
src={`${endpoint}/storage/buckets/media_bucket/files/${value}/view?project=${projectId}`}
alt="Selected"
className="w-full h-full object-cover"
/>

View File

@ -168,7 +168,7 @@ export const StreamOverlays = () => {
const bucketId = mediaObj.bucket_id || APPWRITE_ALMEIRA_CONFIG.mediaBucketId;
return (
<img
src={`${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${bucketId}/files/${mediaObj.file_id}/preview?project=${APPWRITE_ALMEIRA_CONFIG.projectId}&width=400&height=250&quality=80`}
src={`${APPWRITE_ALMEIRA_CONFIG.endpoint}/storage/buckets/${bucketId}/files/${mediaObj.file_id}/view?project=${APPWRITE_ALMEIRA_CONFIG.projectId}&width=400&height=250&quality=80`}
className="w-full h-full object-cover"
alt={activeItem.titulo}
/>

View File

@ -38,7 +38,7 @@ function resolveImageUrl(
const { bucket_id, file_id } = post.imagen_destacada_id;
const isSquare = post.tipo === 'evento' || post.tipo === 'aviso';
const height = isSquare ? 640 : 360;
return `${endpoint}/storage/buckets/${bucket_id}/files/${file_id}/preview?project=${projectId}&width=640&height=${height}&quality=80`;
return `${endpoint}/storage/buckets/${bucket_id}/files/${file_id}/view?project=${projectId}&width=640&height=${height}&quality=80`;
}
// If it's a string, we can't generate a valid URL because it's a document ID, not a file ID.

View File

@ -186,7 +186,7 @@ function MediaThumbnail({ fileId }: { fileId: string }) {
const endpoint = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://nyc.cloud.appwrite.io/v1';
const projectId = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
const url = `${endpoint}/storage/buckets/media/files/${fileId}/preview?project=${projectId}&width=400&height=250&quality=80`;
const url = `${endpoint}/storage/buckets/media_bucket/files/${fileId}/view?project=${projectId}&width=400&height=250&quality=80`;
return (
<div className="mt-3 rounded-xl overflow-hidden border border-slate-800 bg-slate-900 aspect-video relative group animate-fade-in shadow-lg">

View File

@ -10,7 +10,7 @@ export interface UserPreferences {
*/
export async function getUserPreferences(): Promise<UserPreferences> {
try {
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '6aef63d9002c07371b40';
const { cookies } = await import('next/headers');
const cookieStore = await cookies();
const sessionCookie = cookieStore.get(`a_session_${PROJECT_ID.toLowerCase()}`);