mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] Allow deleting avatar + header via settings panel (#3970)
This commit is contained in:
@ -26,10 +26,11 @@ import type {
|
|||||||
import type { Theme } from "../../types/theme";
|
import type { Theme } from "../../types/theme";
|
||||||
import { User } from "../../types/user";
|
import { User } from "../../types/user";
|
||||||
import { DefaultInteractionPolicies, UpdateDefaultInteractionPolicies } from "../../types/interaction";
|
import { DefaultInteractionPolicies, UpdateDefaultInteractionPolicies } from "../../types/interaction";
|
||||||
|
import { Account } from "../../types/account";
|
||||||
|
|
||||||
const extended = gtsApi.injectEndpoints({
|
const extended = gtsApi.injectEndpoints({
|
||||||
endpoints: (build) => ({
|
endpoints: (build) => ({
|
||||||
updateCredentials: build.mutation({
|
updateCredentials: build.mutation<Account, any>({
|
||||||
query: (formData) => ({
|
query: (formData) => ({
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
url: `/api/v1/accounts/update_credentials`,
|
url: `/api/v1/accounts/update_credentials`,
|
||||||
@ -40,6 +41,22 @@ const extended = gtsApi.injectEndpoints({
|
|||||||
...replaceCacheOnMutation("verifyCredentials")
|
...replaceCacheOnMutation("verifyCredentials")
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
deleteHeader: build.mutation<Account, void>({
|
||||||
|
query: (_) => ({
|
||||||
|
method: "DELETE",
|
||||||
|
url: `/api/v1/profile/header`,
|
||||||
|
}),
|
||||||
|
...replaceCacheOnMutation("verifyCredentials")
|
||||||
|
}),
|
||||||
|
|
||||||
|
deleteAvatar: build.mutation<Account, void>({
|
||||||
|
query: (_) => ({
|
||||||
|
method: "DELETE",
|
||||||
|
url: `/api/v1/profile/avatar`,
|
||||||
|
}),
|
||||||
|
...replaceCacheOnMutation("verifyCredentials")
|
||||||
|
}),
|
||||||
|
|
||||||
user: build.query<User, void>({
|
user: build.query<User, void>({
|
||||||
query: () => ({url: `/api/v1/user`})
|
query: () => ({url: `/api/v1/user`})
|
||||||
}),
|
}),
|
||||||
@ -122,6 +139,8 @@ const extended = gtsApi.injectEndpoints({
|
|||||||
|
|
||||||
export const {
|
export const {
|
||||||
useUpdateCredentialsMutation,
|
useUpdateCredentialsMutation,
|
||||||
|
useDeleteHeaderMutation,
|
||||||
|
useDeleteAvatarMutation,
|
||||||
useUserQuery,
|
useUserQuery,
|
||||||
usePasswordChangeMutation,
|
usePasswordChangeMutation,
|
||||||
useEmailChangeMutation,
|
useEmailChangeMutation,
|
||||||
|
@ -447,6 +447,12 @@ section.with-sidebar > form {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
.delete-header-button,
|
||||||
|
.delete-avatar-button {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useMemo } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useTextInput,
|
useTextInput,
|
||||||
@ -41,7 +41,7 @@ import FormWithData from "../../lib/form/form-with-data";
|
|||||||
import FakeProfile from "../../components/profile";
|
import FakeProfile from "../../components/profile";
|
||||||
import MutationButton from "../../components/form/mutation-button";
|
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 { useUpdateCredentialsMutation } from "../../lib/query/user";
|
||||||
import { useVerifyCredentialsQuery } from "../../lib/query/login";
|
import { useVerifyCredentialsQuery } from "../../lib/query/login";
|
||||||
import { useInstanceV1Query } from "../../lib/query/gts-api";
|
import { useInstanceV1Query } from "../../lib/query/gts-api";
|
||||||
@ -116,17 +116,23 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) {
|
|||||||
theme: useTextInput("theme", { source: profile }),
|
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(), {
|
const [submitForm, result] = useFormSubmit(form, useUpdateCredentialsMutation(), {
|
||||||
changedOnly: true,
|
changedOnly: true,
|
||||||
onFinish: () => {
|
onFinish: (res) => {
|
||||||
form.avatar.reset();
|
if ('data' in res) {
|
||||||
form.header.reset();
|
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 (
|
return (
|
||||||
<form className="user-profile" onSubmit={submitForm}>
|
<form className="user-profile" onSubmit={submitForm}>
|
||||||
<h1>Profile</h1>
|
<h1>Profile</h1>
|
||||||
@ -152,7 +158,21 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) {
|
|||||||
label="Image description; only settable if not using default header"
|
label="Image description; only settable if not using default header"
|
||||||
placeholder="A green field with pink flowers."
|
placeholder="A green field with pink flowers."
|
||||||
autoCapitalize="sentences"
|
autoCapitalize="sentences"
|
||||||
disabled={noHeaderSet && !form.header.value}
|
disabled={noHeader && !form.header.value}
|
||||||
|
/>
|
||||||
|
<MutationButton
|
||||||
|
className="delete-header-button"
|
||||||
|
label="Delete header"
|
||||||
|
disabled={noHeader}
|
||||||
|
result={deleteHeaderRes}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
deleteHeader().then(res => {
|
||||||
|
if ('data' in res) {
|
||||||
|
setNoHeader(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
@ -168,7 +188,21 @@ function UserProfileForm({ data: profile }: UserProfileFormProps) {
|
|||||||
label="Image description; only settable if not using default avatar"
|
label="Image description; only settable if not using default avatar"
|
||||||
placeholder="A cute drawing of a smiling sloth."
|
placeholder="A cute drawing of a smiling sloth."
|
||||||
autoCapitalize="sentences"
|
autoCapitalize="sentences"
|
||||||
disabled={noAvatarSet && !form.avatar.value}
|
disabled={noAvatar && !form.avatar.value}
|
||||||
|
/>
|
||||||
|
<MutationButton
|
||||||
|
className="delete-avatar-button"
|
||||||
|
label="Delete avatar"
|
||||||
|
disabled={noAvatar}
|
||||||
|
result={deleteAvatarRes}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
deleteAvatar().then(res => {
|
||||||
|
if ('data' in res) {
|
||||||
|
setNoAvatar(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user