mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-06-24 05:36:39 -05:00
152 lines
4.2 KiB
TypeScript
152 lines
4.2 KiB
TypeScript
import * as React from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Divider } from "~/components/Divider";
|
|
import { SendouButton } from "~/components/elements/Button";
|
|
import { SendouPopover } from "~/components/elements/Popover";
|
|
import { FormMessage } from "~/components/FormMessage";
|
|
import { Label } from "~/components/Label";
|
|
import { Config } from "~/config";
|
|
import { useUser } from "~/features/auth/core/user";
|
|
import { SendouForm } from "~/form/SendouForm";
|
|
import {
|
|
disableBuildAbilitySortingSchema,
|
|
disallowScrimPickupsFromUntrustedSchema,
|
|
spoilerFreeModeSchema,
|
|
} from "../settings-schemas";
|
|
|
|
export function PreferencesTab() {
|
|
const user = useUser();
|
|
if (!user) return null;
|
|
|
|
return (
|
|
<div className="stack md">
|
|
<PushNotificationsEnabler />
|
|
<Divider className="my-2" />
|
|
<div className="stack md">
|
|
<SendouForm
|
|
schema={disableBuildAbilitySortingSchema}
|
|
defaultValues={{
|
|
newValue: user.preferences.disableBuildAbilitySorting ?? false,
|
|
}}
|
|
autoSubmit
|
|
revalidateRoot
|
|
fullWidth
|
|
>
|
|
{({ FormField }) => <FormField name="newValue" />}
|
|
</SendouForm>
|
|
<SendouForm
|
|
schema={disallowScrimPickupsFromUntrustedSchema}
|
|
defaultValues={{
|
|
newValue:
|
|
user.preferences.disallowScrimPickupsFromUntrusted ?? false,
|
|
}}
|
|
autoSubmit
|
|
revalidateRoot
|
|
fullWidth
|
|
>
|
|
{({ FormField }) => <FormField name="newValue" />}
|
|
</SendouForm>
|
|
<SendouForm
|
|
schema={spoilerFreeModeSchema}
|
|
defaultValues={{
|
|
newValue: user.preferences.spoilerFreeMode ?? false,
|
|
}}
|
|
autoSubmit
|
|
revalidateRoot
|
|
fullWidth
|
|
>
|
|
{({ FormField }) => <FormField name="newValue" />}
|
|
</SendouForm>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PushNotificationsEnabler() {
|
|
const { t } = useTranslation(["common"]);
|
|
const [notificationsPermsGranted, setNotificationsPermsGranted] =
|
|
React.useState<NotificationPermission | "not-supported">("default");
|
|
|
|
React.useEffect(() => {
|
|
if (!("serviceWorker" in navigator)) {
|
|
setNotificationsPermsGranted("not-supported");
|
|
return;
|
|
}
|
|
|
|
if (!("PushManager" in window)) {
|
|
setNotificationsPermsGranted("not-supported");
|
|
return;
|
|
}
|
|
|
|
setNotificationsPermsGranted(Notification.permission);
|
|
}, []);
|
|
|
|
function askPermission() {
|
|
Notification.requestPermission().then((permission) => {
|
|
setNotificationsPermsGranted(permission);
|
|
if (permission === "granted") {
|
|
initServiceWorker();
|
|
}
|
|
});
|
|
}
|
|
|
|
async function initServiceWorker() {
|
|
const swRegistration = await navigator.serviceWorker.register("sw-2.js");
|
|
const subscription = await swRegistration.pushManager.getSubscription();
|
|
if (subscription) {
|
|
sendSubscriptionToServer(subscription);
|
|
} else {
|
|
const subscription = await swRegistration.pushManager.subscribe({
|
|
userVisibleOnly: true,
|
|
applicationServerKey: Config.vapid.publicKey,
|
|
});
|
|
sendSubscriptionToServer(subscription);
|
|
}
|
|
}
|
|
|
|
function sendSubscriptionToServer(subscription: PushSubscription) {
|
|
fetch("/notifications/subscribe", {
|
|
method: "post",
|
|
body: JSON.stringify(subscription),
|
|
headers: { "content-type": "application/json" },
|
|
});
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<Label>{t("common:settings.notifications.title")}</Label>
|
|
{notificationsPermsGranted === "granted" ? (
|
|
<SendouPopover
|
|
trigger={
|
|
<SendouButton size="small" variant="minimal">
|
|
{t("common:actions.disable")}
|
|
</SendouButton>
|
|
}
|
|
>
|
|
{t("common:settings.notifications.disableInfo")}
|
|
</SendouPopover>
|
|
) : notificationsPermsGranted === "not-supported" ||
|
|
notificationsPermsGranted === "denied" ? (
|
|
<SendouPopover
|
|
trigger={
|
|
<SendouButton size="small" variant="minimal">
|
|
{t("common:actions.enable")}
|
|
</SendouButton>
|
|
}
|
|
>
|
|
{notificationsPermsGranted === "not-supported"
|
|
? t("common:settings.notifications.browserNotSupported")
|
|
: t("common:settings.notifications.permissionDenied")}
|
|
</SendouPopover>
|
|
) : (
|
|
<SendouButton size="small" variant="minimal" onPress={askPermission}>
|
|
{t("common:actions.enable")}
|
|
</SendouButton>
|
|
)}
|
|
<FormMessage type="info">
|
|
{t("common:settings.notifications.description")}
|
|
</FormMessage>
|
|
</div>
|
|
);
|
|
}
|