import { useEffect, useState, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { useParams, Link } from 'react-router-dom'; import DeleteIcon from '@/material-icons/400-24px/delete.svg?react'; import DomainIcon from '@/material-icons/400-24px/dns.svg?react'; //import EditIcon from '@/material-icons/400-24px/edit.svg?react'; //import HashtagIcon from '@/material-icons/400-24px/tag.svg?react'; //import KeywordIcon from '@/material-icons/400-24px/title.svg?react'; import AntennaIcon from '@/material-icons/400-24px/wifi.svg?react'; import { fetchAntenna, fetchAntennaAccounts, fetchAntennaDomains, fetchAntennaExcludeAccounts, fetchAntennaKeywords, fetchAntennaTags, } from 'mastodon/actions/antennas'; import { apiAddDomain, apiGetAccounts, apiRemoveDomain, } from 'mastodon/api/antennas'; import { Button } from 'mastodon/components/button'; import Column from 'mastodon/components/column'; import { ColumnHeader } from 'mastodon/components/column_header'; import type { IconProp , Icon } from 'mastodon/components/icon'; import { IconButton } from 'mastodon/components/icon_button'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; const messages = defineMessages({ deleteMessage: { id: 'confirmations.delete_antenna.message', defaultMessage: 'Are you sure you want to permanently delete this antenna?', }, deleteConfirm: { id: 'confirmations.delete_antenna.confirm', defaultMessage: 'Delete', }, editAccounts: { id: 'antennas.edit_accounts', defaultMessage: 'Edit accounts', }, noOptions: { id: 'antennas.select.no_options_message', defaultMessage: 'Empty lists', }, placeholder: { id: 'antennas.select.placeholder', defaultMessage: 'Select list', }, addDomainLabel: { id: 'antennas.add_domain_placeholder', defaultMessage: 'New domain', }, addKeywordLabel: { id: 'antennas.add_keyword_placeholder', defaultMessage: 'New keyword', }, addTagLabel: { id: 'antennas.add_tag_placeholder', defaultMessage: 'New tag', }, addDomainTitle: { id: 'antennas.add_domain', defaultMessage: 'Add domain' }, addKeywordTitle: { id: 'antennas.add_keyword', defaultMessage: 'Add keyword', }, addTagTitle: { id: 'antennas.add_tag', defaultMessage: 'Add tag' }, accounts: { id: 'antennas.accounts', defaultMessage: '{count} accounts' }, domains: { id: 'antennas.domains', defaultMessage: '{count} domains' }, tags: { id: 'antennas.tags', defaultMessage: '{count} tags' }, keywords: { id: 'antennas.keywords', defaultMessage: '{count} keywords' }, setHome: { id: 'antennas.select.set_home', defaultMessage: 'Set home' }, }); const TextListItem: React.FC<{ icon: string; iconComponent: IconProp; value: string; onRemove: (value: string) => void; }> = ({ icon, iconComponent, value, onRemove }) => { const handleRemove = useCallback(() => { onRemove(value); }, [onRemove, value]); return (
{value}
); }; const TextList: React.FC<{ values: string[]; disabled?: boolean; icon: string; iconComponent: IconProp; label: string; title: string; onAdd: (value: string) => void; onRemove: (value: string) => void; }> = ({ values, disabled, icon, iconComponent, label, title, onAdd, onRemove, }) => { const [value, setValue] = useState(''); const handleValueChange = useCallback( ({ target: { value } }: React.ChangeEvent) => { setValue(value); }, [setValue], ); const handleAdd = useCallback(() => { onAdd(value); setValue(''); }, [onAdd, value]); const handleRemove = useCallback( (removeValue: string) => { onRemove(removeValue); }, [onRemove], ); const handleSubmit = handleAdd; return (
{values.map((val) => ( ))}
); }; const RadioPanel: React.FC<{ items: { title: string; value: string }[]; valueLengths: number[]; alertMessage: React.ReactElement; onChange: (value: string) => void; }> = ({ items, valueLengths, alertMessage, onChange }) => { const [error, setError] = useState(false); const [value, setValue] = useState(''); useEffect(() => { if (valueLengths.length >= 2) { setError(valueLengths.slice(1).some((v) => v > 0)); } else { setError(false); } }, [valueLengths]); useEffect(() => { if (items.length > 0 && !items.some((i) => i.value === value)) { for (let i = 0; i < valueLengths.length; i++) { const length = valueLengths[i] ?? 0; const item = items[i] ?? { value: '' }; if (length > 0) { setValue(item.value); return; } } setValue(items[0]?.value ?? ''); } }, [items]); const handleChange = useCallback( ({ currentTarget }: React.MouseEvent) => { const selected = currentTarget.getAttribute('data-value') ?? ''; if (value !== selected) { onChange(selected); setValue(selected); } }, [setValue], ); return (
{items.map((item) => ( ))}
{error &&
{alertMessage}
}
); }; const MembersLink: React.FC<{ id: string; onCountFetched: (count: number) => void; }> = ({ id, onCountFetched }) => { const [count, setCount] = useState(0); const [avatars, setAvatars] = useState([]); useEffect(() => { void apiGetAccounts(id) .then((data) => { setCount(data.length); onCountFetched(data.length); setAvatars(data.slice(0, 3).map((a) => a.avatar)); return ''; }) .catch(() => { // Nothing }); }, [id, setCount, setAvatars]); return (
{avatars.map((url) => ( ))}
); }; const AntennaSetting: React.FC<{ multiColumn?: boolean; }> = ({ multiColumn }) => { const dispatch = useAppDispatch(); const { id } = useParams<{ id?: string }>(); const intl = useIntl(); //const history = useHistory(); const antenna = useAppSelector((state) => id ? state.antennas.get(id) : undefined, ); const domains = useAppSelector((state) => id ? state.antennas.getIn(['domains', id]) : undefined, ) as string[] | undefined; const [domainList, setDomainList] = useState([] as string[]); const [accountsCount, setAccountsCount] = useState(0); const [rangeMode, setRangeMode] = useState('accounts'); useEffect(() => { if (id) { dispatch(fetchAntenna(id)); dispatch(fetchAntennaKeywords(id)); dispatch(fetchAntennaDomains(id)); dispatch(fetchAntennaTags(id)); dispatch(fetchAntennaAccounts(id)); dispatch(fetchAntennaExcludeAccounts(id)); } }, [dispatch, id]); useEffect(() => { if (id && antenna) { setDomainList(domains ?? []); } }, [id, antenna, domains, setDomainList]); const handleAccountsFetched = useCallback( (count: number) => { setAccountsCount(count); }, [setAccountsCount], ); const handleAddDomain = useCallback( (value: string) => { if (!id) return; void apiAddDomain(id, value).then(() => { setDomainList([...domainList, value]); return value; }); }, [id, domainList, setDomainList], ); const handleRemoveDomain = useCallback( (value: string) => { if (!id) return; void apiRemoveDomain(id, value).then(() => { setDomainList(domainList.filter((v) => v !== value)); return value; }); }, [id, domainList, setDomainList], ); const handleRangeRadioChange = useCallback( (value: string) => { setRangeMode(value); }, [id, antenna, setRangeMode], ); if (!antenna || !id) return
; const rangeRadioItems = [ { value: 'accounts', title: intl.formatMessage(messages.accounts, { count: accountsCount }), }, { value: 'domains', title: intl.formatMessage(messages.domains, { count: domainList.length }), }, ]; const rangeRadioLengths = [0, domainList.length]; return (
} onChange={handleRangeRadioChange} /> {rangeMode === 'accounts' && ( )} {rangeMode === 'domains' && ( )}
); }; // eslint-disable-next-line import/no-default-export export default AntennaSetting;