148 lines
4.2 KiB
TypeScript
148 lines
4.2 KiB
TypeScript
import { createFormControl, createFormGroup } from "solid-forms";
|
|
import { Match, Show, Switch } from "solid-js";
|
|
|
|
import { Trans, useLingui } from "@lingui-solid/solid/macro";
|
|
import type { API } from "stoat.js";
|
|
|
|
import { useClient } from "@revolt/client";
|
|
import { CONFIGURATION } from "@revolt/common";
|
|
import { useModals } from "@revolt/modal";
|
|
import { Button, CircularProgress, Column, Form2, Row, Text } from "@revolt/ui";
|
|
|
|
import { ChannelSettingsProps } from "../ChannelSettings";
|
|
|
|
/**
|
|
* Channel overview
|
|
*/
|
|
export default function ChannelOverview(props: ChannelSettingsProps) {
|
|
const { t } = useLingui();
|
|
const client = useClient();
|
|
const { openModal } = useModals();
|
|
|
|
/* eslint-disable solid/reactivity */
|
|
// we want to take the initial value only
|
|
const editGroup = createFormGroup({
|
|
name: createFormControl(props.channel.name),
|
|
description: createFormControl(props.channel.description || ""),
|
|
icon: createFormControl<string | File[] | null>(
|
|
props.channel.animatedIconURL,
|
|
),
|
|
});
|
|
/* eslint-enable solid/reactivity */
|
|
|
|
function onReset() {
|
|
editGroup.controls.name.setValue(props.channel.name);
|
|
editGroup.controls.description.setValue(props.channel.description || "");
|
|
editGroup.controls.icon.setValue(props.channel.animatedIconURL ?? null);
|
|
}
|
|
|
|
async function onSubmit() {
|
|
const changes: API.DataEditChannel = {
|
|
remove: [],
|
|
};
|
|
|
|
if (editGroup.controls.name.isDirty) {
|
|
changes.name = editGroup.controls.name.value.trim();
|
|
}
|
|
|
|
if (editGroup.controls.description.isDirty) {
|
|
const description = editGroup.controls.description.value.trim();
|
|
|
|
if (description) {
|
|
changes.description = description;
|
|
} else {
|
|
changes.remove!.push("Description");
|
|
}
|
|
}
|
|
|
|
if (editGroup.controls.icon.isDirty) {
|
|
if (!editGroup.controls.icon.value) {
|
|
changes.remove!.push("Icon");
|
|
} else if (Array.isArray(editGroup.controls.icon.value)) {
|
|
const body = new FormData();
|
|
body.append("file", editGroup.controls.icon.value[0]);
|
|
|
|
const [key, value] = client().authenticationHeader;
|
|
const data: { id: string } = await fetch(
|
|
`${CONFIGURATION.DEFAULT_MEDIA_URL}/icons`,
|
|
{
|
|
method: "POST",
|
|
body,
|
|
headers: {
|
|
[key]: value,
|
|
},
|
|
},
|
|
).then((res) => res.json());
|
|
|
|
changes.icon = data.id;
|
|
}
|
|
}
|
|
|
|
await props.channel.edit(changes);
|
|
}
|
|
|
|
const submit = Form2.useSubmitHandler(editGroup, onSubmit, onReset);
|
|
|
|
return (
|
|
<Column gap="xl">
|
|
<form onSubmit={submit}>
|
|
<Column>
|
|
<Text class="label">
|
|
<Trans>Channel Info</Trans>
|
|
</Text>
|
|
<Form2.FileInput control={editGroup.controls.icon} accept="image/*" />
|
|
<Form2.TextField
|
|
name="name"
|
|
control={editGroup.controls.name}
|
|
label={t`Channel Name`}
|
|
/>
|
|
<Form2.TextField
|
|
autosize
|
|
min-rows={2}
|
|
name="description"
|
|
control={editGroup.controls.description}
|
|
label={t`Channel Description`}
|
|
placeholder={t`This channel is about...`}
|
|
/>
|
|
<Row>
|
|
<Form2.Reset group={editGroup} onReset={onReset} />
|
|
<Form2.Submit group={editGroup} requireDirty>
|
|
<Trans>Save</Trans>
|
|
</Form2.Submit>
|
|
<Show when={editGroup.isPending}>
|
|
<CircularProgress />
|
|
</Show>
|
|
</Row>
|
|
</Column>
|
|
</form>
|
|
<Column>
|
|
<Text class="label">
|
|
<Trans>Mark as Mature</Trans>
|
|
</Text>
|
|
<Text>
|
|
<Trans>
|
|
Users will be asked to confirm their age before opening this
|
|
channel.
|
|
</Trans>
|
|
</Text>
|
|
<div>
|
|
<Button
|
|
onPress={() =>
|
|
openModal({
|
|
type: "channel_toggle_mature",
|
|
channel: props.channel,
|
|
})
|
|
}
|
|
>
|
|
<Switch fallback={<Trans>Mark as Mature</Trans>}>
|
|
<Match when={props.channel.mature}>
|
|
<Trans>Unmark as Mature</Trans>
|
|
</Match>
|
|
</Switch>
|
|
</Button>
|
|
</div>
|
|
</Column>
|
|
</Column>
|
|
);
|
|
}
|