This commit is contained in:
Thomas Demirdjian
2025-10-03 14:09:47 +02:00
parent 1907449dee
commit bfca92f9e0
10 changed files with 265 additions and 305 deletions
+30 -209
View File
@@ -1,7 +1,7 @@
import { useEffect, useMemo, useState } from "react";
import { useGlobal } from "reactn";
import { usersRef, projectsRef } from "../config/firebase";
import useDataFromRef from "./useDataFromRef";
import { useState } from "react";
import useAlgoliaSearch from "react-native-minuit/src/hooks/useAlgoliaSearch";
import { AlgoliaUserConfig, AlgoliaProjectConfig } from "../data/keys";
import { useUserData } from "../providers/UserDataProvider";
const batchSizes = {
users: 5,
@@ -11,221 +11,42 @@ const batchSizes = {
const useSearch = () => {
const [selected, setSelected] = useState(null);
const [search, setSearch] = useState("");
const queryText = useMemo(() => search.trim(), [search]);
const queryLower = useMemo(
() => (search || "").toLowerCase().trim(),
[search],
);
const [currentUID] = useGlobal("currentUID");
const [autoLoads, setAutoLoads] = useState(0);
const { currentUID } = useUserData();
const usersQueryRef = useMemo(() => {
try {
const lower = queryLower;
if (lower) {
return usersRef
.orderBy("userNameLower")
.startAt(lower)
.endAt(lower + "\uf8ff");
}
return usersRef.orderBy("userNameLower");
} catch (_error) {
return null;
}
}, [queryLower]);
const projectsQueryRefLower = useMemo(() => {
try {
const lower = queryText ? queryText.toLowerCase() : "";
if (lower) {
return projectsRef
.orderBy("titleLower")
.startAt(lower)
.endAt(lower + "\uf8ff");
}
return null;
} catch (_error) {
return null;
}
}, [queryText]);
const projectsQueryRefCase = useMemo(() => {
try {
const raw = queryText || "";
if (raw) {
return projectsRef
.orderBy("title")
.startAt(raw)
.endAt(raw + "\uf8ff");
}
return null;
} catch (_error) {
return null;
}
}, [queryText]);
const {
data: userResults = [],
loading: usersLoading,
loadMore: loadMoreUsers,
} = useDataFromRef({
ref: usersQueryRef,
simpleRef: false,
listener: false,
condition: !!usersQueryRef,
refreshArray: [queryLower],
usePagination: true,
batchSize: batchSizes.users,
const { hits: users, loading: userLoading } = useAlgoliaSearch({
query: search,
algoliaObject: AlgoliaUserConfig,
batch: batchSizes.users,
searchParams: {
filters: `NOT objectID:${currentUID}`,
},
});
const filteredUsers = useMemo(() => {
const arr = Array.isArray(userResults) ? userResults : [];
const matchingUsers = queryLower
? arr.filter((user) => {
const nameLower = (
user?.userNameLower ||
user?.userName ||
""
).toLowerCase();
return nameLower.includes(queryLower);
})
: arr;
const seen = new Set();
const unique = [];
for (const user of matchingUsers) {
const id = user?.id;
if (!id || seen.has(id)) continue;
if (id === currentUID || user?.userID === currentUID) continue;
seen.add(id);
unique.push(user);
}
return unique;
}, [userResults, queryLower, currentUID]);
const {
data: projectResultsLower = [],
loading: projectsLoadingLower,
loadMore: loadMoreProjectsLower,
} = useDataFromRef({
ref: projectsQueryRefLower,
simpleRef: false,
listener: false,
condition: !!projectsQueryRefLower,
refreshArray: [queryText],
usePagination: true,
batchSize: batchSizes.projects,
const { hits: playbacks, loading: playbackLoading } = useAlgoliaSearch({
query: search,
algoliaObject: AlgoliaProjectConfig,
batch: batchSizes.projects,
searchParams: {
filters: `hasPlayback:true AND hasSong:true`,
},
});
const {
data: projectResultsCase = [],
loading: projectsLoadingCase,
loadMore: loadMoreProjectsCase,
} = useDataFromRef({
ref: projectsQueryRefCase,
simpleRef: false,
listener: false,
condition: !!projectsQueryRefCase,
refreshArray: [queryText],
usePagination: true,
batchSize: batchSizes.projects,
const { hits: musics, loading: musicLoading } = useAlgoliaSearch({
query: search,
algoliaObject: AlgoliaProjectConfig,
batch: batchSizes.projects,
searchParams: {
filters: `hasPlayback:false AND hasSong:true`,
},
});
const {
data: projectResultsDefault = [],
loading: projectsLoadingDefault,
loadMore: loadMoreProjectsDefault,
} = useDataFromRef({
ref: !queryText ? projectsRef.orderBy("updatedAt", "desc") : null,
simpleRef: false,
listener: false,
condition: !queryText,
refreshArray: [queryText],
usePagination: true,
batchSize: batchSizes.projects,
});
const projectsLoading = queryText
? projectsLoadingLower || projectsLoadingCase
: projectsLoadingDefault;
const loadMoreProjects = () => {
if (queryText) {
loadMoreProjectsLower?.();
loadMoreProjectsCase?.();
} else {
loadMoreProjectsDefault?.();
}
};
const filteredProjects = useMemo(() => {
const lowerMatches = Array.isArray(projectResultsLower)
? projectResultsLower
: [];
const caseMatches = Array.isArray(projectResultsCase)
? projectResultsCase
: [];
const defaultProjects = Array.isArray(projectResultsDefault)
? projectResultsDefault
: [];
const arr = queryText ? [...lowerMatches, ...caseMatches] : defaultProjects;
const seen = new Set();
const unique = [];
for (const project of arr) {
const id = project?.id;
if (!id || seen.has(id)) continue;
seen.add(id);
unique.push(project);
}
return unique;
}, [
queryText,
projectResultsLower,
projectResultsCase,
projectResultsDefault,
]);
useEffect(() => {
setAutoLoads(0);
}, [queryText]);
useEffect(() => {
if (
filteredUsers.length < batchSizes.users &&
usersQueryRef &&
!usersLoading
) {
if (autoLoads < 3) {
setAutoLoads((previous) => previous + 1);
loadMoreUsers?.();
}
}
}, [
filteredUsers.length,
usersLoading,
usersQueryRef,
autoLoads,
loadMoreUsers,
]);
const toggleSelected = (item) => {
setSelected((prev) => (prev === item ? null : item));
};
return {
search,
setSearch,
queryText,
queryLower,
selected,
setSelected,
toggleSelected,
filteredUsers,
usersLoading,
loadMoreUsers,
filteredProjects,
projectsLoading,
loadMoreProjects,
users,
musics,
playbacks,
loading: userLoading || musicLoading || playbackLoading,
};
};