clear lot of tickets
This commit is contained in:
+170
-3
@@ -1,6 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import useAlgoliaSearch from "react-native-minuit/src/hooks/useAlgoliaSearch";
|
||||
import { AlgoliaUserConfig, AlgoliaProjectConfig } from "../data/keys";
|
||||
import { projectsRef } from "../config/firebase";
|
||||
import { useUserData } from "../providers/UserDataProvider";
|
||||
|
||||
const batchSizes = {
|
||||
@@ -8,9 +9,119 @@ const batchSizes = {
|
||||
projects: 6,
|
||||
};
|
||||
|
||||
const isValidUri = (value) =>
|
||||
typeof value === "string" && value.trim().length > 0;
|
||||
|
||||
const hasCoverAsset = (project) => {
|
||||
if (!project) return false;
|
||||
if (isValidUri(project?.coverUrl)) {
|
||||
return true;
|
||||
}
|
||||
const cover = project?.cover;
|
||||
if (!cover || typeof cover !== "object") {
|
||||
return false;
|
||||
}
|
||||
const coverCandidates = [
|
||||
cover?.result,
|
||||
cover?.finalUrl,
|
||||
cover?.generatedBackground,
|
||||
];
|
||||
if (Array.isArray(cover?.options)) {
|
||||
coverCandidates.push(
|
||||
...cover.options.flatMap((option) => [
|
||||
option?.finalUrl,
|
||||
option?.generatedUrl,
|
||||
]),
|
||||
);
|
||||
}
|
||||
return coverCandidates.some(isValidUri);
|
||||
};
|
||||
|
||||
const hasThumbnailAsset = (project) =>
|
||||
isValidUri(project?.thumbnailUrl) || isValidUri(project?.songThumbnailUrl);
|
||||
|
||||
const mergeProjectAssets = (
|
||||
project,
|
||||
firestoreData,
|
||||
{ mergeCover = false, mergeThumbnails = false } = {},
|
||||
) => {
|
||||
if (!firestoreData || typeof firestoreData !== "object") {
|
||||
return project;
|
||||
}
|
||||
const mergedProject = { ...project };
|
||||
|
||||
if (mergeCover) {
|
||||
if (!isValidUri(mergedProject.coverUrl) && isValidUri(firestoreData.coverUrl)) {
|
||||
mergedProject.coverUrl = firestoreData.coverUrl;
|
||||
}
|
||||
const firestoreCover =
|
||||
firestoreData.cover && typeof firestoreData.cover === "object"
|
||||
? firestoreData.cover
|
||||
: null;
|
||||
if (firestoreCover) {
|
||||
mergedProject.cover = {
|
||||
...(typeof mergedProject.cover === "object" ? mergedProject.cover : {}),
|
||||
...firestoreCover,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (mergeThumbnails) {
|
||||
if (!isValidUri(mergedProject.thumbnailUrl) && isValidUri(firestoreData.thumbnailUrl)) {
|
||||
mergedProject.thumbnailUrl = firestoreData.thumbnailUrl;
|
||||
}
|
||||
if (
|
||||
!isValidUri(mergedProject.songThumbnailUrl) &&
|
||||
isValidUri(firestoreData.songThumbnailUrl)
|
||||
) {
|
||||
mergedProject.songThumbnailUrl = firestoreData.songThumbnailUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return mergedProject;
|
||||
};
|
||||
|
||||
const hydrateProjects = async (
|
||||
projects = [],
|
||||
{ ensureCover = false, ensureThumbnails = false } = {},
|
||||
) => {
|
||||
if (!Array.isArray(projects) || projects.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
projects.map(async (project) => {
|
||||
const needsCover = ensureCover && !hasCoverAsset(project);
|
||||
const needsThumbnail = ensureThumbnails && !hasThumbnailAsset(project);
|
||||
|
||||
if ((!needsCover && !needsThumbnail) || !project?.id) {
|
||||
return project;
|
||||
}
|
||||
|
||||
try {
|
||||
const snapshot = await projectsRef.doc(project.id).get();
|
||||
if (!snapshot.exists) {
|
||||
return project;
|
||||
}
|
||||
const firestoreData = snapshot.data() || {};
|
||||
return mergeProjectAssets(project, firestoreData, {
|
||||
mergeCover: needsCover,
|
||||
mergeThumbnails: needsThumbnail,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("useSearch.hydrateProjects error", error?.message || error);
|
||||
return project;
|
||||
}
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const useSearch = () => {
|
||||
const [selected, setSelected] = useState(null);
|
||||
const [search, setSearch] = useState("");
|
||||
const [hydratedMusics, setHydratedMusics] = useState(null);
|
||||
const [hydratedPlaybacks, setHydratedPlaybacks] = useState(null);
|
||||
|
||||
const { currentUID } = useUserData();
|
||||
|
||||
const { hits: users, loading: userLoading } = useAlgoliaSearch({
|
||||
@@ -38,14 +149,70 @@ const useSearch = () => {
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
let isCancelled = false;
|
||||
const nextMusics = Array.isArray(musics) ? musics : [];
|
||||
const requiresHydration =
|
||||
nextMusics.length > 0 &&
|
||||
nextMusics.some((project) => !hasCoverAsset(project));
|
||||
|
||||
if (!requiresHydration) {
|
||||
setHydratedMusics(null);
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}
|
||||
|
||||
setHydratedMusics(null);
|
||||
(async () => {
|
||||
const hydrated = await hydrateProjects(nextMusics, { ensureCover: true });
|
||||
if (!isCancelled) {
|
||||
setHydratedMusics(hydrated);
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}, [musics]);
|
||||
|
||||
useEffect(() => {
|
||||
let isCancelled = false;
|
||||
const nextPlaybacks = Array.isArray(playbacks) ? playbacks : [];
|
||||
const requiresHydration =
|
||||
nextPlaybacks.length > 0 &&
|
||||
nextPlaybacks.some((project) => !hasThumbnailAsset(project));
|
||||
|
||||
if (!requiresHydration) {
|
||||
setHydratedPlaybacks(null);
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}
|
||||
|
||||
setHydratedPlaybacks(null);
|
||||
(async () => {
|
||||
const hydrated = await hydrateProjects(nextPlaybacks, {
|
||||
ensureThumbnails: true,
|
||||
});
|
||||
if (!isCancelled) {
|
||||
setHydratedPlaybacks(hydrated);
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}, [playbacks]);
|
||||
|
||||
return {
|
||||
search,
|
||||
setSearch,
|
||||
selected,
|
||||
setSelected,
|
||||
users,
|
||||
musics,
|
||||
playbacks,
|
||||
musics: hydratedMusics ?? musics,
|
||||
playbacks: hydratedPlaybacks ?? playbacks,
|
||||
loading: userLoading || musicLoading || playbackLoading,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user