[feature] Add image descriptions for default avatar + header; don't allow editing default desc (#3473)

This commit is contained in:
tobi
2024-10-21 14:04:50 +02:00
committed by GitHub
parent e9299e1174
commit 8a93300ac4
22 changed files with 198 additions and 25 deletions

View File

@@ -19,6 +19,7 @@
import React from "react";
import Loading from "./loading";
import { Error as ErrorC } from "./error";
import { useVerifyCredentialsQuery, useLogoutMutation } from "../lib/query/oauth";
import { useInstanceV1Query } from "../lib/query/gts-api";
@@ -29,16 +30,20 @@ export default function UserLogoutCard() {
if (isLoading) {
return <Loading />;
} else {
return (
<div className="account-card">
<img className="avatar" src={profile.avatar} alt="" />
<h3 className="text-cutoff">{profile.display_name?.length > 0 ? profile.display_name : profile.acct}</h3>
<span className="text-cutoff">@{profile.username}@{instance?.account_domain}</span>
<a onClick={logoutQuery} href="#" aria-label="Log out" title="Log out" className="logout">
<i className="fa fa-fw fa-sign-out" aria-hidden="true" />
</a>
</div>
);
}
if (!profile) {
return <ErrorC error={new Error("account was undefined")} />;
}
return (
<div className="account-card">
<img className="avatar" src={profile.avatar} alt="" />
<h3 className="text-cutoff">{profile.display_name?.length > 0 ? profile.display_name : profile.acct}</h3>
<span className="text-cutoff">@{profile.username}@{instance?.account_domain}</span>
<a onClick={logoutQuery} href="#" aria-label="Log out" title="Log out" className="logout">
<i className="fa fa-fw fa-sign-out" aria-hidden="true" />
</a>
</div>
);
}

View File

@@ -26,6 +26,7 @@ import {
authorize as oauthAuthorize,
} from "../../../redux/oauth";
import { RootState } from '../../../redux/store';
import { Account } from '../../types/account';
export interface OauthTokenRequestBody {
client_id: string;
@@ -58,7 +59,7 @@ const SETTINGS_URL = (getSettingsURL());
// https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#performing-multiple-requests-with-a-single-query
const extended = gtsApi.injectEndpoints({
endpoints: (build) => ({
verifyCredentials: build.query<any, void>({
verifyCredentials: build.query<Account, void>({
providesTags: (_res, error) =>
error == undefined ? ["Auth"] : [],
async queryFn(_arg, api, _extraOpts, fetchWithBQ) {

View File

@@ -53,8 +53,12 @@ export interface Account {
url: string,
avatar: string,
avatar_static: string,
avatar_description?: string,
avatar_media_id?: string,
header: string,
header_static: string,
header_description?: string,
header_media_id?: string,
followers_count: number,
following_count: number,
statuses_count: number,
@@ -68,7 +72,7 @@ export interface Account {
}
export interface AccountSource {
fields: any[];
fields: any;
follow_requests_count: number;
language: string;
note: string;

View File

@@ -441,6 +441,11 @@ section.with-sidebar > form {
.profile {
max-width: 42rem;
}
.file-input-with-image-description {
max-width: 100%;
width: 100%;
}
.overview {
display: flex;

View File

@@ -20,7 +20,7 @@
import React from "react";
import { useVerifyCredentialsQuery } from "../../../lib/query/oauth";
import Loading from "../../../components/loading";
import { Error } from "../../../components/error";
import { Error as ErrorC } from "../../../components/error";
import BasicSettings from "./basic-settings";
import InteractionPolicySettings from "./interaction-policy-settings";
@@ -38,7 +38,11 @@ export default function PostSettings() {
}
if (isError) {
return <Error error={error} />;
return <ErrorC error={error} />;
}
if (!account) {
return <ErrorC error={new Error("account was undefined")} />;
}
return (

View File

@@ -45,6 +45,7 @@ import { useAccountThemesQuery } from "../../lib/query/user";
import { useUpdateCredentialsMutation } from "../../lib/query/user";
import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
import { useInstanceV1Query } from "../../lib/query/gts-api";
import { Account } from "../../lib/types/account";
export default function UserProfile() {
return (
@@ -55,7 +56,11 @@ export default function UserProfile() {
);
}
function UserProfileForm({ data: profile }) {
interface UserProfileFormProps {
data: Account;
}
function UserProfileForm({ data: profile }: UserProfileFormProps) {
/*
User profile update form keys
- bool bot
@@ -132,6 +137,9 @@ function UserProfileForm({ data: profile }) {
}
});
const noAvatarSet = !profile.avatar_media_id;
const noHeaderSet = !profile.header_media_id;
return (
<form className="user-profile" onSubmit={submitForm}>
<h1>Profile</h1>
@@ -145,33 +153,37 @@ function UserProfileForm({ data: profile }) {
role={profile.role}
/>
<div className="file-input-with-image-description">
<fieldset className="file-input-with-image-description">
<legend>Header</legend>
<FileInput
label="Header"
label="Upload file"
field={form.header}
accept="image/png, image/jpeg, image/webp, image/gif"
/>
<TextInput
field={form.headerDescription}
label="Header image description"
label="Image description; only settable if not using default header"
placeholder="A green field with pink flowers."
autoCapitalize="sentences"
disabled={noHeaderSet && !form.header.value}
/>
</div>
</fieldset>
<div className="file-input-with-image-description">
<fieldset className="file-input-with-image-description">
<legend>Avatar</legend>
<FileInput
label="Avatar (1:1 images look best)"
label="Upload file (1:1 images look best)"
field={form.avatar}
accept="image/png, image/jpeg, image/webp, image/gif"
/>
<TextInput
field={form.avatarDescription}
label="Avatar image description"
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}
/>
</div>
</fieldset>
<div className="theme">
<div>