/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { classNameFactory } from "@api/Styles";
import {
closeModal, ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, openModal
} from "@utils/modal";
import { LazyComponent } from "@utils/react";
import { Button, React, RelationshipStore, Select, Text, TextInput, useCallback, useMemo, useReducer, useState } from "@webpack/common";
import { cacheUsers, getNotes, usersCache as usersCache$1 } from "../data";
import NotesDataRow from "./NotesDataRow";
const cl = classNameFactory("vc-notes-searcher-modal-");
const enum SearchStatus {
ALL,
FRIENDS,
BLOCKED,
}
const filterUser = (query: string, userId: string, userNotes: string) => {
if (query === "" || userId.includes(query)) return true;
query = query.toLowerCase();
const user = usersCache$1.get(userId);
return user && (
user.globalName?.toLowerCase().includes(query) || user.username.toLowerCase().includes(query)
) || userNotes.toLowerCase().includes(query);
};
// looks like a shit but I don't know better way to do it
// P.S. using `getNotes()` as deps for useMemo won't work due to object init outside of component
let RefreshNotesDataEx: () => void | undefined;
export const refreshNotesData = () => {
if (!RefreshNotesDataEx) return;
RefreshNotesDataEx();
};
export function NotesDataModal({ modalProps, close }: {
modalProps: ModalProps;
close(): void;
}) {
const [searchValue, setSearchValue] = useState({ query: "", status: SearchStatus.ALL });
const onSearch = (query: string) => setSearchValue(prev => ({ ...prev, query }));
const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
const [usersNotesData, refreshNotesData] = useReducer(() => {
return Object.entries(getNotes())
.map<[string, string]>(([userId, { note }]) => [userId, note])
.filter((([_, note]) => note && note !== ""));
},
Object.entries(getNotes())
.map<[string, string]>(([userId, { note }]) => [userId, note])
.filter((([_, note]) => note && note !== ""))
);
RefreshNotesDataEx = refreshNotesData;
const filteredNotes = useMemo(() => {
const { query, status } = searchValue;
if (query === "" && status === SearchStatus.ALL) {
return usersNotesData;
}
return usersNotesData
.filter(([userId, userNotes]) => {
switch (status) {
case SearchStatus.FRIENDS:
return RelationshipStore.isFriend(userId) && filterUser(query, userId, userNotes);
case SearchStatus.BLOCKED:
return RelationshipStore.isBlocked(userId) && filterUser(query, userId, userNotes);
default:
return filterUser(query, userId, userNotes);
}
});
}, [usersNotesData, searchValue]);
const [visibleNotesNum, setVisibleNotesNum] = useState(10);
const loadMore = useCallback(() => {
setVisibleNotesNum(prevNum => prevNum + 10);
}, []);
const visibleNotes = filteredNotes.slice(0, visibleNotesNum);
const canLoadMore = visibleNotesNum < filteredNotes.length;
return (