search
This commit is contained in:
+30
-209
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user