/* * Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors. * SPDX-License-Identifier: GPL-2.0-or-later */ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { toast } from "react-hot-toast"; import { XMarkIcon } from "@heroicons/react/24/solid"; import type { FieldProps } from "formik"; import type { FieldArrayRenderProps } from "formik"; import { Field, FieldArray, FormikErrors, FormikValues } from "formik"; import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; import Select from "react-select"; import { Dialog } from "@headlessui/react"; import { IrcAuthMechanismTypeOptions, OptionBasicTyped } from "@domain/constants"; import { ircKeys } from "@screens/settings/Irc"; import { APIClient } from "@api/APIClient"; import { NumberFieldWide, PasswordFieldWide, SwitchGroupWide, TextFieldWide } from "@components/inputs"; import { SlideOver } from "@components/panels"; import Toast from "@components/notifications/Toast"; import * as common from "@components/inputs/common"; import { classNames } from "@utils"; interface ChannelsFieldArrayProps { channels: IrcChannel[]; } const ChannelsFieldArray = ({ channels }: ChannelsFieldArrayProps) => (
{({ remove, push }: FieldArrayRenderProps) => (
{channels && channels.length > 0 ? ( channels.map((channel: IrcChannel, index) => { const isDisabled = channel.name === "#ptp-announce-dev"; return (
{({ field, meta }: FieldProps) => ( )} {({ field, meta }: FieldProps) => ( )}
); }) ) : ( No channels! )}
)}
); interface IrcNetworkAddFormValues { name: string; enabled: boolean; server : string; port: number; tls: boolean; pass: string; nick: string; auth: IrcAuth; channels: IrcChannel[]; } interface AddFormProps { isOpen: boolean; toggle: () => void; } export function IrcNetworkAddForm({ isOpen, toggle }: AddFormProps) { const queryClient = useQueryClient(); const mutation = useMutation({ mutationFn: (network: IrcNetwork) => APIClient.irc.createNetwork(network), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ircKeys.lists() }); toast.custom((t) => ); toggle(); }, onError: () => { toast.custom((t) => ); } }); const onSubmit = (data: unknown) => mutation.mutate(data as IrcNetwork); const initialValues: IrcNetworkAddFormValues = { name: "", enabled: true, server: "", port: 6667, tls: false, pass: "", nick: "", auth: { mechanism: "SASL_PLAIN", account: "" }, channels: [] }; return ( {(values) => (
ADD NETWORKS VIA INDEXERS! ONLY USE THIS IF YOU DELETED NETWORKS
Channels

Channels to join.

)}
); } const validateNetwork = (values: FormikValues) => { const errors = {} as FormikErrors; if (!values.name) { errors.name = "Required"; } if (!values.server) { errors.server = "Required"; } if (!values.port) { errors.port = "Required"; } if (!values.nick) { errors.nick = "Required"; } return errors; }; interface IrcNetworkUpdateFormValues { id: number; name: string; enabled: boolean; server: string; port: number; tls: boolean; pass: string; nick: string; auth?: IrcAuth; invite_command: string; use_bouncer: boolean; bouncer_addr: string; bot_mode: boolean; channels: Array; } interface IrcNetworkUpdateFormProps { isOpen: boolean; toggle: () => void; network: IrcNetwork; } export function IrcNetworkUpdateForm({ isOpen, toggle, network }: IrcNetworkUpdateFormProps) { const queryClient = useQueryClient(); const updateMutation = useMutation({ mutationFn: (network: IrcNetwork) => APIClient.irc.updateNetwork(network), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ircKeys.lists() }); toast.custom((t) => ); toggle(); } }); const onSubmit = (data: unknown) => updateMutation.mutate(data as IrcNetwork); const deleteMutation = useMutation({ mutationFn: (id: number) => APIClient.irc.deleteNetwork(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ircKeys.lists() }); toast.custom((t) => ); toggle(); } }); const deleteAction = () => deleteMutation.mutate(network.id); const initialValues: IrcNetworkUpdateFormValues = { id: network.id, name: network.name, enabled: network.enabled, server: network.server, port: network.port, tls: network.tls, nick: network.nick, pass: network.pass, auth: network.auth, invite_command: network.invite_command, use_bouncer: network.use_bouncer, bouncer_addr: network.bouncer_addr, bot_mode: network.bot_mode, channels: network.channels }; return ( {(values) => (
{values.use_bouncer && ( )}
Identification

Identify with SASL or NickServ. Most networks support SASL but some don't.

name="auth.mechanism" label="Mechanism" options={IrcAuthMechanismTypeOptions} />
Channels

Channels are added when you setup IRC indexers. Do not edit unless you know what you are doing.

)}
); } interface SelectFieldProps { name: string; label: string; options: OptionBasicTyped[] } function SelectField({ name, label, options }: SelectFieldProps) { return (
{({ field, form: { setFieldValue, resetForm } }: FieldProps) => (