diff --git a/web/source/settings/lib/query/user/index.ts b/web/source/settings/lib/query/user/index.ts index 0df926eb3..80aeea2a4 100644 --- a/web/source/settings/lib/query/user/index.ts +++ b/web/source/settings/lib/query/user/index.ts @@ -26,10 +26,11 @@ import type { import type { Theme } from "../../types/theme"; import { User } from "../../types/user"; import { DefaultInteractionPolicies, UpdateDefaultInteractionPolicies } from "../../types/interaction"; +import { Account } from "../../types/account"; const extended = gtsApi.injectEndpoints({ endpoints: (build) => ({ - updateCredentials: build.mutation({ + updateCredentials: build.mutation({ query: (formData) => ({ method: "PATCH", url: `/api/v1/accounts/update_credentials`, @@ -39,6 +40,22 @@ const extended = gtsApi.injectEndpoints({ }), ...replaceCacheOnMutation("verifyCredentials") }), + + deleteHeader: build.mutation({ + query: (_) => ({ + method: "DELETE", + url: `/api/v1/profile/header`, + }), + ...replaceCacheOnMutation("verifyCredentials") + }), + + deleteAvatar: build.mutation({ + query: (_) => ({ + method: "DELETE", + url: `/api/v1/profile/avatar`, + }), + ...replaceCacheOnMutation("verifyCredentials") + }), user: build.query({ query: () => ({url: `/api/v1/user`}) @@ -122,6 +139,8 @@ const extended = gtsApi.injectEndpoints({ export const { useUpdateCredentialsMutation, + useDeleteHeaderMutation, + useDeleteAvatarMutation, useUserQuery, usePasswordChangeMutation, useEmailChangeMutation, diff --git a/web/source/settings/style.css b/web/source/settings/style.css index c05072043..2afb44c42 100644 --- a/web/source/settings/style.css +++ b/web/source/settings/style.css @@ -447,6 +447,12 @@ section.with-sidebar > form { flex-direction: column; justify-content: space-around; gap: 0.5rem; + + .delete-header-button, + .delete-avatar-button { + margin-top: 0.5rem; + font-size: 1rem; + } } /* diff --git a/web/source/settings/views/user/profile.tsx b/web/source/settings/views/user/profile.tsx index 9ea948337..d6fcbf56d 100644 --- a/web/source/settings/views/user/profile.tsx +++ b/web/source/settings/views/user/profile.tsx @@ -17,7 +17,7 @@ along with this program. If not, see . */ -import React, { useMemo } from "react"; +import React, { useMemo, useState } from "react"; import { useTextInput, @@ -41,7 +41,7 @@ import FormWithData from "../../lib/form/form-with-data"; import FakeProfile from "../../components/profile"; import MutationButton from "../../components/form/mutation-button"; -import { useAccountThemesQuery } from "../../lib/query/user"; +import { useAccountThemesQuery, useDeleteAvatarMutation, useDeleteHeaderMutation } from "../../lib/query/user"; import { useUpdateCredentialsMutation } from "../../lib/query/user"; import { useVerifyCredentialsQuery } from "../../lib/query/login"; import { useInstanceV1Query } from "../../lib/query/gts-api"; @@ -116,17 +116,23 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) { theme: useTextInput("theme", { source: profile }), }; + const [ noHeader, setNoHeader ] = useState(!profile.header_media_id); + const [ deleteHeader, deleteHeaderRes ] = useDeleteHeaderMutation(); + const [ noAvatar, setNoAvatar ] = useState(!profile.avatar_media_id); + const [ deleteAvatar, deleteAvatarRes ] = useDeleteAvatarMutation(); + const [submitForm, result] = useFormSubmit(form, useUpdateCredentialsMutation(), { changedOnly: true, - onFinish: () => { - form.avatar.reset(); - form.header.reset(); + onFinish: (res) => { + if ('data' in res) { + form.avatar.reset(); + form.header.reset(); + setNoAvatar(!res.data.avatar_media_id); + setNoHeader(!res.data.header_media_id); + } } }); - const noAvatarSet = !profile.avatar_media_id; - const noHeaderSet = !profile.header_media_id; - return (

Profile

@@ -152,7 +158,21 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) { label="Image description; only settable if not using default header" placeholder="A green field with pink flowers." autoCapitalize="sentences" - disabled={noHeaderSet && !form.header.value} + disabled={noHeader && !form.header.value} + /> + { + e.preventDefault(); + deleteHeader().then(res => { + if ('data' in res) { + setNoHeader(true); + } + }); + }} /> @@ -168,7 +188,21 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) { label="Image description; only settable if not using default avatar" placeholder="A cute drawing of a smiling sloth." autoCapitalize="sentences" - disabled={noAvatarSet && !form.avatar.value} + disabled={noAvatar && !form.avatar.value} + /> + { + e.preventDefault(); + deleteAvatar().then(res => { + if ('data' in res) { + setNoAvatar(true); + } + }); + }} />