From e9d68a00c8f8fd56b198afe277a54313307deff3 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Thu, 20 Feb 2025 11:51:17 +0800 Subject: [PATCH] Allow changing header + profile pictures --- src/components/account-info.css | 67 +++++++++++++++-- src/components/account-info.jsx | 129 +++++++++++++++++++++++++++++++- src/locales/en.po | 32 +++++--- 3 files changed, 208 insertions(+), 20 deletions(-) diff --git a/src/components/account-info.css b/src/components/account-info.css index 1c8f34c6..60a0c2dd 100644 --- a/src/components/account-info.css +++ b/src/components/account-info.css @@ -51,7 +51,8 @@ border-radius: var(--posting-stats-size); overflow: hidden; margin: 8px 0; - box-shadow: inset 0 0 0 1px var(--outline-color), + box-shadow: + inset 0 0 0 1px var(--outline-color), inset 0 0 0 1.5px var(--bg-blur-color); background-color: var(--bg-color); background-repeat: no-repeat; @@ -85,7 +86,8 @@ vertical-align: middle; margin: 0 4px 2px; /* border: 1px solid var(--outline-color); */ - box-shadow: inset 0 0 0 1px var(--outline-color), + box-shadow: + inset 0 0 0 1px var(--outline-color), inset 0 0 0 1.5px var(--bg-blur-color); &.posting-stats-legend-item-originals { @@ -246,7 +248,9 @@ display: flex; align-items: center; gap: 8px; - text-shadow: -8px 0 12px -6px var(--bg-color), 8px 0 12px -6px var(--bg-color), + text-shadow: + -8px 0 12px -6px var(--bg-color), + 8px 0 12px -6px var(--bg-color), -8px 0 24px var(--header-color-3, --bg-color), 8px 0 24px var(--header-color-4, --bg-color); animation: fade-in 0.3s both ease-in-out 0.1s; @@ -743,9 +747,9 @@ --shadow-offset: 16px; --shadow-blur: 32px; --shadow-spread: calc(var(--shadow-blur) * -0.75); - box-shadow: calc(var(--shadow-offset) * -1) var(--shadow-offset) - var(--shadow-blur) var(--shadow-spread) - var(--header-color-1, var(--drop-shadow-color)), + box-shadow: + calc(var(--shadow-offset) * -1) var(--shadow-offset) var(--shadow-blur) + var(--shadow-spread) var(--header-color-1, var(--drop-shadow-color)), var(--shadow-offset) var(--shadow-offset) var(--shadow-blur) var(--shadow-spread) var(--header-color-2, var(--drop-shadow-color)); } @@ -805,7 +809,7 @@ } label { - input, + input:not([type='file']), textarea { display: block; width: 100%; @@ -818,6 +822,55 @@ } } + .edit-profile-media-container { + margin-block: 8px; + } + + .edit-profile-media-field { + display: grid; + grid-template-columns: 80px 2em 80px; + gap: 8px; + margin-top: 8px; + align-items: center; + justify-items: center; + + .icon { + opacity: 0.75; + } + + .edit-media { + width: 80px; + height: 80px; + border-radius: 4px; + overflow: hidden; + border: 1px solid var(--outline-color); + /* checkerboard background */ + background-image: + linear-gradient(45deg, var(--img-bg-color) 25%, transparent 25%), + linear-gradient(-45deg, var(--img-bg-color) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, var(--img-bg-color) 75%), + linear-gradient(-45deg, transparent 75%, var(--img-bg-color) 75%); + background-size: 10px 10px; + background-position: + 0 0, + 0 5px, + 5px -5px, + -5px 0px; + + &:hover { + box-shadow: 0 0 0 2px var(--link-light-color); + cursor: pointer; + } + + img { + object-fit: contain; + width: 100%; + height: 100%; + vertical-align: top; + } + } + } + table { width: 100%; diff --git a/src/components/account-info.jsx b/src/components/account-info.jsx index d35e2a77..3a291738 100644 --- a/src/components/account-info.jsx +++ b/src/components/account-info.jsx @@ -2090,11 +2090,21 @@ function PrivateNoteSheet({ ); } +const SUPPORTED_IMAGE_FORMATS = [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/webp', +]; +const SUPPORTED_IMAGE_FORMATS_STR = SUPPORTED_IMAGE_FORMATS.join(','); + function EditProfileSheet({ onClose = () => {} }) { const { t } = useLingui(); const { masto } = api(); const [uiState, setUIState] = useState('loading'); const [account, setAccount] = useState(null); + const [headerPreview, setHeaderPreview] = useState(null); + const [avatarPreview, setAvatarPreview] = useState(null); useEffect(() => { (async () => { @@ -2110,10 +2120,19 @@ function EditProfileSheet({ onClose = () => {} }) { }, []); console.log('EditProfileSheet', account); - const { displayName, source } = account || {}; + const { displayName, source, avatar, header } = account || {}; const { note, fields } = source || {}; const fieldsAttributesRef = useRef(null); + const avatarMediaAttachments = [ + ...(avatar ? [{ type: 'image', url: avatar }] : []), + ...(avatarPreview ? [{ type: 'image', url: avatarPreview }] : []), + ]; + const headerMediaAttachments = [ + ...(header ? [{ type: 'image', url: header }] : []), + ...(headerPreview ? [{ type: 'image', url: headerPreview }] : []), + ]; + return (
{!!onClose && ( @@ -2136,6 +2155,8 @@ function EditProfileSheet({ onClose = () => {} }) { onSubmit={(e) => { e.preventDefault(); const formData = new FormData(e.target); + const header = formData.get('header'); + const avatar = formData.get('avatar'); const displayName = formData.get('display_name'); const note = formData.get('note'); const fieldsAttributesFields = @@ -2163,6 +2184,8 @@ function EditProfileSheet({ onClose = () => {} }) { (async () => { try { const newAccount = await masto.v1.accounts.updateCredentials({ + header, + avatar, displayName, note, fieldsAttributes, @@ -2179,6 +2202,110 @@ function EditProfileSheet({ onClose = () => {} }) { })(); }} > +
+ +
+ {header ? ( +
{ + states.showMediaModal = { + mediaAttachments: headerMediaAttachments, + index: 0, + }; + }} + > + +
+ ) : ( +
+ )} + {headerPreview && ( + <> + +
{ + states.showMediaModal = { + mediaAttachments: headerMediaAttachments, + index: 1, + }; + }} + > + +
+ + )} +
+
+
+ +
+ {avatar ? ( +
{ + states.showMediaModal = { + mediaAttachments: avatarMediaAttachments, + index: 0, + }; + }} + > + +
+ ) : ( +
+ )} + {avatarPreview && ( + <> + +
{ + states.showMediaModal = { + mediaAttachments: avatarMediaAttachments, + index: 1, + }; + }} + > + +
+ + )} +
+