Proje: Okul B2B App · Hub: Okul B2B App — Conventions
ContentMediaPicker — Optimistic Upload Pattern
components/school-content/ContentMediaPicker.tsx — İçerik görsellerini yönetir.
İki Farklı Medya State
interface NewMediaItem {
_uid: string; // Client-side ID
localUri: string; // Cihaz local URI
tempUrl: string | null; // Geçici yükleme URL (null = yükleniyor)
isUploading: boolean;
}
interface ExistingMediaItem {
id: number; // API media ID
url: string; // CDN URL
sort: number;
isDeleting?: boolean; // Siliniyor işareti
}Yükleme Stratejisi
Edit mode: Seçilen görsel anında MediaService.uploadMedia() ile yüklenir. Başarılı upload sonrası existingMedia’ya taşınır.
Create mode: Görseller newMediaItems’da bekler. Kaydet butonuna basıldığında content oluşturulur sonra görseller yüklenir.
Ref ile Closure Sorunu Çözme
const newMediaRef = React.useRef(newMediaItems);
React.useEffect(() => { newMediaRef.current = newMediaItems; }, [newMediaItems]);Async upload callback’lerinde stale closure sorununu önlemek için useRef ile güncel state takibi yapılır.
maxCount Kontrolü
totalCount = existingMedia.length + newMediaItems.length toplamı maxCount’u aşarsa yeni seçim engellenir.
Related
- icerik-form-modal-pattern — form context’i
- medya-yukleme-akisi — MediaService.uploadMedia detayı