nicolium: extend antenna editor
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -260,13 +260,30 @@
|
||||
"alt_text_modal.saving_failed": "Failed to save alt text",
|
||||
"announcements.title": "Announcements",
|
||||
"antennas.create": "Create antenna",
|
||||
"antennas.create.error": "Error creating antenna",
|
||||
"antennas.create.save": "Create antenna",
|
||||
"antennas.create.success": "Antenna created successfully",
|
||||
"antennas.delete": "Delete antenna",
|
||||
"antennas.edit": "Edit antenna",
|
||||
"antennas.edit.destination": "Destination",
|
||||
"antennas.edit.destination.antenna": "Antenna timeline only",
|
||||
"antennas.edit.destination.home": "Insert to home timeline",
|
||||
"antennas.edit.destination.list": "Insert to list",
|
||||
"antennas.edit.error": "Error updating antenna",
|
||||
"antennas.edit.favourite": "Favourite",
|
||||
"antennas.edit.favourite.hint": "The antenna will be marked as favourite (not used by Nicolium yet)",
|
||||
"antennas.edit.ignore_reblogs": "Ignore reblogs",
|
||||
"antennas.edit.ignore_reblogs.hint": "Reblogs will not be included in the antenna",
|
||||
"antennas.edit.mode": "Mode",
|
||||
"antennas.edit.mode.filtering": "Filtering",
|
||||
"antennas.edit.mode.ltl": "Local timeline mode",
|
||||
"antennas.edit.mode.stl": "Social timeline mode",
|
||||
"antennas.edit.save": "Save antenna",
|
||||
"antennas.edit.success": "Antenna updated successfully",
|
||||
"antennas.edit.title": "Antenna title",
|
||||
"antennas.edit.with_media_only": "Media only",
|
||||
"antennas.edit.with_media_only.hint": "Only include posts with media attachments",
|
||||
"antennas.manage_accounts": "Manage antenna accounts",
|
||||
"antennas.new.create": "Add antenna",
|
||||
"antennas.subheading": "Your antennas",
|
||||
"app_create.name_label": "App name",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import List, { ListItem } from '@/components/list';
|
||||
import Button from '@/components/ui/button';
|
||||
import Form from '@/components/ui/form';
|
||||
import FormActions from '@/components/ui/form-actions';
|
||||
@ -8,7 +9,10 @@ import FormGroup from '@/components/ui/form-group';
|
||||
import Input from '@/components/ui/input';
|
||||
import Modal from '@/components/ui/modal';
|
||||
import Spinner from '@/components/ui/spinner';
|
||||
import Toggle from '@/components/ui/toggle';
|
||||
import { SelectDropdown } from '@/features/forms';
|
||||
import { useAntenna, useCreateAntenna, useUpdateAntenna } from '@/queries/accounts/use-antennas';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
import toast from '@/toast';
|
||||
|
||||
import type { BaseModalProps } from '@/features/ui/components/modal-root';
|
||||
@ -16,15 +20,18 @@ import type { BaseModalProps } from '@/features/ui/components/modal-root';
|
||||
type Tab = 'info' | 'accounts' | 'excludedAccounts';
|
||||
|
||||
const messages = defineMessages({
|
||||
success: { id: 'antennas.edit.success', defaultMessage: 'Antenna updated successfully' },
|
||||
error: { id: 'antennas.edit.error', defaultMessage: 'Error updating antenna' },
|
||||
createSuccess: { id: 'antennas.create.success', defaultMessage: 'Antenna created successfully' },
|
||||
editSuccess: { id: 'antennas.edit.success', defaultMessage: 'Antenna updated successfully' },
|
||||
createError: { id: 'antennas.create.error', defaultMessage: 'Error creating antenna' },
|
||||
editError: { id: 'antennas.edit.error', defaultMessage: 'Error updating antenna' },
|
||||
});
|
||||
|
||||
interface IAntennaMembersForm {
|
||||
antennaId?: string;
|
||||
interface IAntennaAccountsForm {
|
||||
antennaId: string;
|
||||
excluded?: boolean;
|
||||
}
|
||||
|
||||
const AntennaMembersForm: React.FC<IAntennaMembersForm> = () => null;
|
||||
const AntennaAccountsForm: React.FC<IAntennaAccountsForm> = () => null;
|
||||
|
||||
interface IEditAntennaForm {
|
||||
antennaId?: string;
|
||||
@ -34,6 +41,7 @@ interface IEditAntennaForm {
|
||||
|
||||
const EditAntennaForm: React.FC<IEditAntennaForm> = ({ antennaId, onTabChange }) => {
|
||||
const intl = useIntl();
|
||||
const { closeModal } = useModalsActions();
|
||||
|
||||
const { data: antenna } = useAntenna(antennaId);
|
||||
const { mutate: updateAntenna, isPending: updateDisabled } = useUpdateAntenna(antennaId!);
|
||||
@ -42,6 +50,13 @@ const EditAntennaForm: React.FC<IEditAntennaForm> = ({ antennaId, onTabChange })
|
||||
const disabled = antennaId ? updateDisabled : createDisabled;
|
||||
|
||||
const [title, setTitle] = useState(antenna ? antenna.title : '');
|
||||
const [ltl, setLtl] = useState(antenna ? antenna.ltl : false);
|
||||
const [stl, setStl] = useState(antenna ? antenna.stl : false);
|
||||
const [insertFeeds, setInsertFeeds] = useState(antenna ? antenna.insert_feeds : false);
|
||||
const [withMediaOnly, setWithMediaOnly] = useState(antenna ? antenna.with_media_only : false);
|
||||
const [ignoreReblog, setIgnoreReblog] = useState(antenna ? antenna.ignore_reblog : false);
|
||||
const [favourite, setFavourite] = useState(antenna ? antenna.favourite : false);
|
||||
const [listId, setListId] = useState(antenna?.list?.id || undefined);
|
||||
|
||||
const handleSubmit: React.FormEventHandler = (e) => {
|
||||
e.preventDefault();
|
||||
@ -50,13 +65,25 @@ const EditAntennaForm: React.FC<IEditAntennaForm> = ({ antennaId, onTabChange })
|
||||
|
||||
const handleUpdate = () => {
|
||||
(antennaId ? updateAntenna : createAntenna)(
|
||||
{ title },
|
||||
{
|
||||
title,
|
||||
stl,
|
||||
ltl,
|
||||
insert_feeds: insertFeeds,
|
||||
with_media_only: withMediaOnly,
|
||||
ignore_reblog: ignoreReblog,
|
||||
favourite,
|
||||
list_id: listId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success(intl.formatMessage(messages.success));
|
||||
toast.success(
|
||||
intl.formatMessage(antennaId ? messages.editSuccess : messages.createSuccess),
|
||||
);
|
||||
closeModal('ANTENNA_EDITOR');
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(intl.formatMessage(messages.error));
|
||||
toast.error(intl.formatMessage(antennaId ? messages.editError : messages.createError));
|
||||
},
|
||||
},
|
||||
);
|
||||
@ -76,6 +103,114 @@ const EditAntennaForm: React.FC<IEditAntennaForm> = ({ antennaId, onTabChange })
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup labelText={<FormattedMessage id='antennas.edit.mode' defaultMessage='Mode' />}>
|
||||
<SelectDropdown
|
||||
items={{
|
||||
stl: intl.formatMessage({
|
||||
id: 'antennas.edit.mode.stl',
|
||||
defaultMessage: 'Social timeline mode',
|
||||
}),
|
||||
ltl: intl.formatMessage({
|
||||
id: 'antennas.edit.mode.ltl',
|
||||
defaultMessage: 'Local timeline mode',
|
||||
}),
|
||||
filtering: intl.formatMessage({
|
||||
id: 'antennas.edit.mode.filtering',
|
||||
defaultMessage: 'Filtering',
|
||||
}),
|
||||
}}
|
||||
defaultValue={stl ? 'stl' : ltl ? 'ltl' : 'filtering'}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setStl(value === 'stl');
|
||||
setLtl(value === 'ltl');
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
labelText={<FormattedMessage id='antennas.edit.destination' defaultMessage='Destination' />}
|
||||
>
|
||||
<SelectDropdown
|
||||
items={{
|
||||
home: intl.formatMessage({
|
||||
id: 'antennas.edit.destination.home',
|
||||
defaultMessage: 'Insert to home timeline',
|
||||
}),
|
||||
list: intl.formatMessage({
|
||||
id: 'antennas.edit.destination.list',
|
||||
defaultMessage: 'Insert to list',
|
||||
}),
|
||||
antenna: intl.formatMessage({
|
||||
id: 'antennas.edit.destination.antenna',
|
||||
defaultMessage: 'Antenna timeline only',
|
||||
}),
|
||||
}}
|
||||
defaultValue={insertFeeds ? 'home' : listId ? 'list' : 'antenna'}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setInsertFeeds(value === 'home');
|
||||
if (value === 'list') {
|
||||
setListId(''); // TODO: add list selection
|
||||
} else {
|
||||
setListId(undefined);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<List>
|
||||
<ListItem
|
||||
label={
|
||||
<FormattedMessage id='antennas.edit.with_media_only' defaultMessage='Media only' />
|
||||
}
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='antennas.edit.with_media_only.hint'
|
||||
defaultMessage='Only include posts with media attachments'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Toggle checked={withMediaOnly} onChange={(e) => setWithMediaOnly(e.target.checked)} />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
label={
|
||||
<FormattedMessage id='antennas.edit.ignore_reblogs' defaultMessage='Ignore reblogs' />
|
||||
}
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='antennas.edit.ignore_reblogs.hint'
|
||||
defaultMessage='Reblogs will not be included in the antenna'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Toggle checked={ignoreReblog} onChange={(e) => setIgnoreReblog(e.target.checked)} />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
label={<FormattedMessage id='antennas.edit.favourite' defaultMessage='Favourite' />}
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='antennas.edit.favourite.hint'
|
||||
defaultMessage='The antenna will be marked as favourite (not used by Nicolium yet)'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Toggle checked={favourite} onChange={(e) => setFavourite(e.target.checked)} />
|
||||
</ListItem>
|
||||
{antennaId && (
|
||||
<>
|
||||
<ListItem
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='antennas.manage_accounts'
|
||||
defaultMessage='Manage antenna accounts'
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
onTabChange('accounts');
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</List>
|
||||
<FormActions>
|
||||
<Button onClick={handleUpdate} disabled={disabled}>
|
||||
{antennaId ? (
|
||||
@ -106,6 +241,25 @@ const AntennaEditorModal: React.FC<BaseModalProps & AntennaEditorModalProps> = (
|
||||
onClose('ANTENNA_EDITOR');
|
||||
};
|
||||
|
||||
const tabContent = useMemo(() => {
|
||||
if (!isFetched) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
switch (tab) {
|
||||
case 'info':
|
||||
return (
|
||||
<EditAntennaForm antennaId={antennaId} setAntennaId={setAntennaId} onTabChange={setTab} />
|
||||
);
|
||||
case 'accounts':
|
||||
return <AntennaAccountsForm antennaId={antennaId!} />;
|
||||
case 'excludedAccounts':
|
||||
return <AntennaAccountsForm antennaId={antennaId!} excluded />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}, [tab, antennaId, isFetched]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
@ -124,15 +278,7 @@ const AntennaEditorModal: React.FC<BaseModalProps & AntennaEditorModalProps> = (
|
||||
}
|
||||
}
|
||||
>
|
||||
{isFetched ? (
|
||||
tab === 'info' ? (
|
||||
<EditAntennaForm antennaId={antennaId} setAntennaId={setAntennaId} onTabChange={setTab} />
|
||||
) : (
|
||||
<AntennaMembersForm antennaId={antennaId} />
|
||||
)
|
||||
) : (
|
||||
<Spinner />
|
||||
)}
|
||||
{tabContent}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user