memoize images

This commit is contained in:
2025-10-03 15:24:42 +02:00
parent ce9571ec7f
commit 2b6bf7e433
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from "react"; import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { import {
FlatList, FlatList,
Image, Image,
@@ -66,30 +66,36 @@ const ProjectDropDown = ({
}) })
: normalizedProjects; : normalizedProjects;
const toggleDropdown = () => { const toggleDropdown = useCallback(() => {
if (isDisabled) { if (isDisabled) {
return; return;
} }
setIsOpen((prev) => !prev); setIsOpen((prev) => !prev);
}; }, [isDisabled]);
const closeDropdown = () => setIsOpen(false); const closeDropdown = useCallback(() => setIsOpen(false), []);
const handleSelect = (project) => { const handleSelect = useCallback(
(project) => {
if (!project?.id) return; if (!project?.id) return;
onSelectProject?.(project); onSelectProject?.(project);
closeDropdown(); closeDropdown();
}; },
[closeDropdown, onSelectProject],
);
const handleModify = (project, topPosition) => { const handleModify = useCallback(
(project, topPosition) => {
if (!project?.id) return; if (!project?.id) return;
onModifyProject?.(project, topPosition); onModifyProject?.(project, topPosition);
}; },
[onModifyProject],
);
const handleCreate = () => { const handleCreate = useCallback(() => {
onCreateProject?.(); onCreateProject?.();
closeDropdown(); closeDropdown();
}; }, [closeDropdown, onCreateProject]);
const dropdownWidth = useMemo( const dropdownWidth = useMemo(
() => triggerLayout?.width || 0, () => triggerLayout?.width || 0,
@@ -124,24 +130,15 @@ const ProjectDropDown = ({
/> />
</BlurView> </BlurView>
{isOpen && (
<BlurView <BlurView
intensity={BUTTON_BLUR_INTENSITY} intensity={BUTTON_BLUR_INTENSITY}
tint="dark" tint="dark"
style={{ pointerEvents={isOpen ? "auto" : "none"}
position: "absolute", style={[
top: 0, styles.dropdownOverlay,
left: 0, { width: dropdownWidth || "100%" },
borderRadius: 16, !isOpen && styles.dropdownOverlayHidden,
paddingHorizontal: 8, ]}
paddingVertical: 8,
gap: 9,
maxHeight: 400,
zIndex: 4,
elevation: 4,
width: dropdownWidth || "100%",
overflow: "hidden",
}}
> >
<ProjectRow <ProjectRow
isTitle={true} isTitle={true}
@@ -178,7 +175,6 @@ const ProjectDropDown = ({
/> />
</View> </View>
</BlurView> </BlurView>
)}
</View> </View>
</View> </View>
); );
@@ -227,6 +223,10 @@ const ProjectRow = ({
project?.coverUrl || project?.coverUrl ||
project?.coverUri || project?.coverUri ||
(typeof project?.cover === "string" ? project.cover : project?.cover?.uri); (typeof project?.cover === "string" ? project.cover : project?.cover?.uri);
const imageSource = useMemo(
() => (coverUri ? { uri: coverUri } : img.placeholder),
[coverUri],
);
const title = const title =
project?.title || (isEmptyProject ? "Nouvelle musique" : "Sans titre"); project?.title || (isEmptyProject ? "Nouvelle musique" : "Sans titre");
const formattedDate = !isEmptyProject const formattedDate = !isEmptyProject
@@ -245,10 +245,7 @@ const ProjectRow = ({
onLayout={(event) => setLayout(event.nativeEvent.layout)} onLayout={(event) => setLayout(event.nativeEvent.layout)}
style={styles.projectRowPressable} style={styles.projectRowPressable}
> >
<Image <Image source={imageSource} style={styles.projectImage} />
source={coverUri ? { uri: coverUri } : img.placeholder}
style={styles.projectImage}
/>
<BlurView tint="dark" style={styles.projectInfo}> <BlurView tint="dark" style={styles.projectInfo}>
<View style={styles.projectTexts}> <View style={styles.projectTexts}>
<Text style={styles.projectTitle} numberOfLines={1}> <Text style={styles.projectTitle} numberOfLines={1}>
@@ -306,6 +303,22 @@ const styles = StyleSheet.create({
position: "relative", position: "relative",
zIndex: 3, zIndex: 3,
}, },
dropdownOverlay: {
position: "absolute",
top: 0,
left: 0,
borderRadius: 16,
paddingHorizontal: 8,
paddingVertical: 8,
gap: 9,
maxHeight: 400,
zIndex: 4,
elevation: 4,
overflow: "hidden",
},
dropdownOverlayHidden: {
opacity: 0,
},
dropdownOverlayContent: { dropdownOverlayContent: {
maxHeight: 260, maxHeight: 260,
width: "100%", width: "100%",