summaryrefslogtreecommitdiff
path: root/web/source
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2024-07-08 15:47:03 +0200
committerLibravatar GitHub <noreply@github.com>2024-07-08 15:47:03 +0200
commitd70f4e166dd9ce2f11a6ac2d7a2e500515657041 (patch)
tree256f2a4423742a41adceb00dbec0cd56c568e908 /web/source
parent[chore]: Bump github.com/minio/minio-go/v7 from 7.0.72 to 7.0.73 (#3083) (diff)
downloadgotosocial-d70f4e166dd9ce2f11a6ac2d7a2e500515657041.tar.xz
[feature/frontend] Allow setting alt-text for avatar + header (#3086)
Diffstat (limited to 'web/source')
-rw-r--r--web/source/css/profile.css29
-rw-r--r--web/source/settings/components/profile.tsx8
-rw-r--r--web/source/settings/style.css23
-rw-r--r--web/source/settings/views/user/profile.tsx44
4 files changed, 71 insertions, 33 deletions
diff --git a/web/source/css/profile.css b/web/source/css/profile.css
index a966d768a..3f7f43d0d 100644
--- a/web/source/css/profile.css
+++ b/web/source/css/profile.css
@@ -82,18 +82,37 @@
margin-top: calc(-1 * $overlap);
gap: 0 1rem;
- .avatar {
+ .avatar-image-wrapper {
grid-area: avatar;
- height: $avatar-size;
- width: $avatar-size;
+
border: 0.2rem solid $avatar-border;
border-radius: $br;
- overflow: hidden; /* prevents image extending beyond rounded borders */
+
+ /*
+ Wrapper always same
+ size + proportions no
+ matter image inside.
+ */
+ height: $avatar-size;
+ width: $avatar-size;
- img {
+ .avatar {
+ /*
+ Fit 100% of the wrapper.
+ */
height: 100%;
width: 100%;
+
+ /*
+ Normalize non-square images.
+ */
object-fit: cover;
+
+ /*
+ Prevent image extending
+ beyond rounded borders.
+ */
+ border-radius: $br-inner;
}
}
diff --git a/web/source/settings/components/profile.tsx b/web/source/settings/components/profile.tsx
index 4a5157378..24cb3c4c2 100644
--- a/web/source/settings/components/profile.tsx
+++ b/web/source/settings/components/profile.tsx
@@ -27,9 +27,11 @@ export default function FakeProfile({ avatar, header, display_name, username, ro
<img src={header} alt={header ? `header image for ${username}` : "None set"} />
</div>
<div className="basic-info" aria-hidden="true">
- <a className="avatar" href={avatar}>
- <img src={avatar} alt={avatar ? `avatar image for ${username}` : "None set"} />
- </a>
+ <div className="avatar-image-wrapper">
+ <a href={avatar}>
+ <img className="avatar" src={avatar} alt={avatar ? `avatar image for ${username}` : "None set"} />
+ </a>
+ </div>
<dl className="namerole">
<dt className="sr-only">Display name</dt>
<dd className="displayname text-cutoff">{display_name.trim().length > 0 ? display_name : username}</dd>
diff --git a/web/source/settings/style.css b/web/source/settings/style.css
index cdae6b972..f9c098ace 100644
--- a/web/source/settings/style.css
+++ b/web/source/settings/style.css
@@ -400,12 +400,13 @@ section.with-sidebar > form {
width: 24rem;
}
}
-
- .file-input-with-image-description {
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- }
+}
+
+.file-input-with-image-description {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+ gap: 0.5rem;
}
/*
@@ -422,11 +423,13 @@ section.with-sidebar > form {
}
.user-profile {
+ .profile {
+ max-width: 42rem;
+ }
+
.overview {
- display: grid;
- max-width: 60rem;
- grid-template-columns: 70% 30%;
- grid-template-rows: auto;
+ display: flex;
+ flex-direction: column;
gap: 1rem;
.files {
diff --git a/web/source/settings/views/user/profile.tsx b/web/source/settings/views/user/profile.tsx
index 17827ce9e..f4088b353 100644
--- a/web/source/settings/views/user/profile.tsx
+++ b/web/source/settings/views/user/profile.tsx
@@ -93,7 +93,9 @@ function UserProfileForm({ data: profile }) {
const form = {
avatar: useFileInput("avatar", { withPreview: true }),
+ avatarDescription: useTextInput("avatar_description", { source: profile }),
header: useFileInput("header", { withPreview: true }),
+ headerDescription: useTextInput("header_description", { source: profile }),
displayName: useTextInput("display_name", { source: profile }),
note: useTextInput("note", { source: profile, valueSelector: (p) => p.source?.note }),
bot: useBoolInput("bot", { source: profile }),
@@ -131,21 +133,33 @@ function UserProfileForm({ data: profile }) {
username={profile.username}
role={profile.role}
/>
- <div className="files">
- <div>
- <FileInput
- label="Header"
- field={form.header}
- accept="image/*"
- />
- </div>
- <div>
- <FileInput
- label="Avatar"
- field={form.avatar}
- accept="image/*"
- />
- </div>
+
+ <div className="file-input-with-image-description">
+ <FileInput
+ label="Header"
+ field={form.header}
+ accept="image/png, image/jpeg, image/webp, image/gif"
+ />
+ <TextInput
+ field={form.headerDescription}
+ label="Header image description"
+ placeholder="A green field with pink flowers."
+ autoCapitalize="sentences"
+ />
+ </div>
+
+ <div className="file-input-with-image-description">
+ <FileInput
+ label="Avatar (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"
+ placeholder="A cute drawing of a smiling sloth."
+ autoCapitalize="sentences"
+ />
</div>
<div className="theme">