mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
[Glitch] Move account search into hook
Port 7e27ba990e to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import { useCallback, useState, useEffect, useRef } from 'react';
|
||||
import { useCallback, useState, useEffect } from 'react';
|
||||
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||
import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react';
|
||||
import { fetchRelationships } from 'flavours/glitch/actions/accounts';
|
||||
@@ -14,14 +12,12 @@ import { showAlertForError } from 'flavours/glitch/actions/alerts';
|
||||
import { importFetchedAccounts } from 'flavours/glitch/actions/importer';
|
||||
import { fetchList } from 'flavours/glitch/actions/lists';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { apiRequest } from 'flavours/glitch/api';
|
||||
import { apiFollowAccount } from 'flavours/glitch/api/accounts';
|
||||
import {
|
||||
apiGetAccounts,
|
||||
apiAddAccountToList,
|
||||
apiRemoveAccountFromList,
|
||||
} from 'flavours/glitch/api/lists';
|
||||
import type { ApiAccountJSON } from 'flavours/glitch/api_types/accounts';
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import { Button } from 'flavours/glitch/components/button';
|
||||
import { Column } from 'flavours/glitch/components/column';
|
||||
@@ -35,6 +31,8 @@ import { VerifiedBadge } from 'flavours/glitch/components/verified_badge';
|
||||
import { me } from 'flavours/glitch/initial_state';
|
||||
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||
|
||||
import { useSearchAccounts } from './use_search_accounts';
|
||||
|
||||
export const messages = defineMessages({
|
||||
manageMembers: {
|
||||
id: 'column.list_members',
|
||||
@@ -163,10 +161,23 @@ const ListMembers: React.FC<{
|
||||
|
||||
const [searching, setSearching] = useState(false);
|
||||
const [accountIds, setAccountIds] = useState<string[]>([]);
|
||||
const [searchAccountIds, setSearchAccountIds] = useState<string[]>([]);
|
||||
const [loading, setLoading] = useState(!!id);
|
||||
const [mode, setMode] = useState<Mode>('remove');
|
||||
|
||||
const {
|
||||
accountIds: searchAccountIds = [],
|
||||
isLoading: loadingSearchResults,
|
||||
searchAccounts: handleSearch,
|
||||
} = useSearchAccounts({
|
||||
onSettled: (value) => {
|
||||
if (value.trim().length === 0) {
|
||||
setSearching(false);
|
||||
} else {
|
||||
setSearching(true);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
dispatch(fetchList(id));
|
||||
@@ -206,46 +217,6 @@ const ListMembers: React.FC<{
|
||||
[accountIds, setAccountIds],
|
||||
);
|
||||
|
||||
const searchRequestRef = useRef<AbortController | null>(null);
|
||||
|
||||
const handleSearch = useDebouncedCallback(
|
||||
(value: string) => {
|
||||
if (searchRequestRef.current) {
|
||||
searchRequestRef.current.abort();
|
||||
}
|
||||
|
||||
if (value.trim().length === 0) {
|
||||
setSearching(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
searchRequestRef.current = new AbortController();
|
||||
|
||||
void apiRequest<ApiAccountJSON[]>('GET', 'v1/accounts/search', {
|
||||
signal: searchRequestRef.current.signal,
|
||||
params: {
|
||||
q: value,
|
||||
resolve: true,
|
||||
},
|
||||
})
|
||||
.then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
setSearchAccountIds(data.map((a) => a.id));
|
||||
setLoading(false);
|
||||
setSearching(true);
|
||||
return '';
|
||||
})
|
||||
.catch(() => {
|
||||
setSearching(true);
|
||||
setLoading(false);
|
||||
});
|
||||
},
|
||||
500,
|
||||
{ leading: true, trailing: true },
|
||||
);
|
||||
|
||||
let displayedAccountIds: string[];
|
||||
|
||||
if (mode === 'add' && searching) {
|
||||
@@ -279,7 +250,7 @@ const ListMembers: React.FC<{
|
||||
scrollKey='list_members'
|
||||
trackScroll={!multiColumn}
|
||||
bindToDocument={!multiColumn}
|
||||
isLoading={loading}
|
||||
isLoading={loading || loadingSearchResults}
|
||||
showLoading={loading && displayedAccountIds.length === 0}
|
||||
hasMore={false}
|
||||
footer={
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { importFetchedAccounts } from 'flavours/glitch/actions/importer';
|
||||
import { apiRequest } from 'flavours/glitch/api';
|
||||
import type { ApiAccountJSON } from 'flavours/glitch/api_types/accounts';
|
||||
import { useAppDispatch } from 'flavours/glitch/store';
|
||||
|
||||
export function useSearchAccounts({
|
||||
onSettled,
|
||||
}: {
|
||||
onSettled?: (value: string) => void;
|
||||
} = {}) {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [accountIds, setAccountIds] = useState<string[]>();
|
||||
const [loadingState, setLoadingState] = useState<
|
||||
'idle' | 'loading' | 'error'
|
||||
>('idle');
|
||||
|
||||
const searchRequestRef = useRef<AbortController | null>(null);
|
||||
|
||||
const searchAccounts = useDebouncedCallback(
|
||||
(value: string) => {
|
||||
if (searchRequestRef.current) {
|
||||
searchRequestRef.current.abort();
|
||||
}
|
||||
|
||||
if (value.trim().length === 0) {
|
||||
onSettled?.('');
|
||||
return;
|
||||
}
|
||||
|
||||
setLoadingState('loading');
|
||||
|
||||
searchRequestRef.current = new AbortController();
|
||||
|
||||
void apiRequest<ApiAccountJSON[]>('GET', 'v1/accounts/search', {
|
||||
signal: searchRequestRef.current.signal,
|
||||
params: {
|
||||
q: value,
|
||||
resolve: true,
|
||||
},
|
||||
})
|
||||
.then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
setAccountIds(data.map((a) => a.id));
|
||||
setLoadingState('idle');
|
||||
onSettled?.(value);
|
||||
})
|
||||
.catch(() => {
|
||||
setLoadingState('error');
|
||||
onSettled?.(value);
|
||||
});
|
||||
},
|
||||
500,
|
||||
{ leading: true, trailing: true },
|
||||
);
|
||||
|
||||
return {
|
||||
searchAccounts,
|
||||
accountIds,
|
||||
isLoading: loadingState === 'loading',
|
||||
isError: loadingState === 'error',
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user