diff --git a/CHANGELOG.md b/CHANGELOG.md index bd8165c..e4cd703 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,15 @@ e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/). - Melhor performance em navegação ### Modificado +- Otimização global de imagens + - Conversão automática para WebP + - Redimensionamento otimizado por contexto + - Parâmetros de qualidade personalizados + - Função utilitária centralizada + - Implementação em todas as rotas + - Otimização contextual por uso + - Pré-carregamento otimizado + - Otimização de imagens de capa - Uso da primeira página como capa - Tamanho reduzido para thumbnails @@ -69,7 +78,7 @@ e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/). - Melhor tratamento de estados de loading e erro - Implementação de componente ImageWithLoading - Sistema de cache de imagens -- Otimização de URLs de imagem +- Otimizaç��o de URLs de imagem - Refatoração de componentes para melhor reuso - Separação de lógica de carregamento de imagens diff --git a/src/lib/imageUtils.ts b/src/lib/imageUtils.ts new file mode 100644 index 0000000..89bca49 --- /dev/null +++ b/src/lib/imageUtils.ts @@ -0,0 +1,30 @@ +interface ImageOptions { + width?: number; + height?: number; + quality?: number; +} + +export function getOptimizedImageUrl(url: string, options: ImageOptions = {}): string { + const { + width = 800, + height = undefined, + quality = 80 + } = options; + + // Se for URL do Supabase Storage + if (url.includes('storage.googleapis.com')) { + const params = new URLSearchParams({ + width: width.toString(), + quality: quality.toString(), + format: 'webp' + }); + + if (height) { + params.append('height', height.toString()); + } + + return `${url}?${params.toString()}`; + } + + return url; +} \ No newline at end of file diff --git a/src/pages/student-dashboard/StoryPage.tsx b/src/pages/student-dashboard/StoryPage.tsx index 704bddf..de05ebc 100644 --- a/src/pages/student-dashboard/StoryPage.tsx +++ b/src/pages/student-dashboard/StoryPage.tsx @@ -6,6 +6,7 @@ import { AudioRecorder } from '../../components/story/AudioRecorder'; import type { Story } from '../../types/database'; import { StoryMetrics } from '../../components/story/StoryMetrics'; import type { MetricsData } from '../../components/story/StoryMetrics'; +import { getOptimizedImageUrl } from '../../lib/imageUtils'; interface StoryRecording { id: string; @@ -304,7 +305,10 @@ export function StoryPage() { const nextImageUrl = story?.content?.pages?.[currentPage + 1]?.image; if (nextImageUrl) { const nextImage = new Image(); - nextImage.src = nextImageUrl; + nextImage.src = getOptimizedImageUrl(nextImageUrl, { + width: 1200, + quality: 85 + }); } }, [currentPage, story]); @@ -398,7 +402,10 @@ export function StoryPage() { {/* Imagem da página atual */} {story?.content?.pages?.[currentPage]?.image && ( diff --git a/src/pages/student-dashboard/StudentDashboardPage.tsx b/src/pages/student-dashboard/StudentDashboardPage.tsx index c7fc7ec..da05e8b 100644 --- a/src/pages/student-dashboard/StudentDashboardPage.tsx +++ b/src/pages/student-dashboard/StudentDashboardPage.tsx @@ -3,6 +3,7 @@ import { Plus, BookOpen, Clock, TrendingUp, Award } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { supabase } from '../../lib/supabase'; import type { Story, Student } from '../../types/database'; +import { getOptimizedImageUrl } from '../../lib/imageUtils'; interface DashboardMetrics { totalStories: number; @@ -252,7 +253,10 @@ export function StudentDashboardPage() { {story.cover && (
{story.title} navigate(`/aluno/historias/${story.id}`)} > - {story.content?.pages?.[0]?.image && ( + {story.cover && (