import { createFormControl, createFormGroup } from "solid-forms"; import { Show, createMemo, createSignal } from "solid-js"; import { Trans, useLingui } from "@lingui-solid/solid/macro"; import { Server } from "stoat.js"; import { cva } from "styled-system/css"; import { styled } from "styled-system/jsx"; import { decodeTime } from "ulid"; import { useClient } from "@revolt/client"; import { Markdown } from "@revolt/markdown"; import { Avatar, Column, Dialog, DialogProps, Form2, Ripple, Text, TextField, Time, } from "@revolt/ui"; import { useModals } from ".."; import { Modals } from "../types"; /** * Modal to join a server */ export function AddBotModal(props: DialogProps & Modals & { type: "add_bot" }) { const { t } = useLingui(); const client = useClient(); const { showError } = useModals(); const [filter, setFilter] = createSignal(""); const filterLowercase = createMemo(() => filter().toLowerCase()); const availableGroups = createMemo(() => { const instance = client(); return [ ...instance.servers .filter((server) => server.havePermission("ManageServer")) // this won't always work, but we might as well try: .filter((server) => !server.getMember(props.invite.id)), ...instance.channels .filter((channel) => channel.type === "Group") .filter((channel) => !channel.recipientIds.has(props.invite.id)), ] .filter((group) => group.name.toLowerCase().includes(filterLowercase())) .toSorted((a, b) => a.name.localeCompare(b.name)) .map((item) => ({ item, value: item.id })); }); const group = createFormGroup({ id: createFormControl([] as string[], { required: true, }), }); async function onSubmit() { try { const entry = availableGroups().find( (entry) => entry.value === group.controls.id.value[0], )!; if (entry.item instanceof Server) { await props.invite.addToServer(entry.item); } else { await props.invite.addToGroup(entry.item); } props.onClose(); } catch (error) { showError(error); } } const submit = Form2.useSubmitHandler(group, onSubmit); return ( Cancel }, { text: Add, onClick: () => { onSubmit(); // doesn't go through submitHandler! // much like other modals don't either return false; }, isDisabled: !Form2.canSubmit(group), }, ]} isDisabled={group.isPending} >
{props.invite.username} Registered since{" "}
Description provided by {props.invite.username}
setFilter(e.currentTarget.value)} /> {(item, selected) => ( {" "} {item.name} )} Bots are not verified by Stoat. The bot will not be granted any permissions.
); } const description = cva({ base: { position: "relative", maxHeight: "120px", padding: "var(--gap-md)", borderRadius: "var(--borderRadius-lg)", color: "var(--md-sys-color-on-secondary-container)", background: "var(--md-sys-color-secondary-container)", }, }); const ProvidedBy = styled("div", { base: { bottom: 0, position: "sticky", background: "var(--md-sys-color-secondary-container)", }, }); const CoverText = styled("div", { base: { position: "relative", "& *": { top: 0, width: "100%", position: "absolute", height: "var(--gap-md)", background: "var(--md-sys-color-secondary-container)", }, }, }); const Item = styled("div", { base: { height: "40px", display: "flex", position: "relative", alignItems: "center", gap: "var(--gap-md)", padding: "var(--gap-md)", borderRadius: "var(--borderRadius-sm)", }, variants: { selected: { true: { color: "var(--md-sys-color-on-primary)", background: "var(--md-sys-color-primary)", }, }, }, });