Very, very simple Edit Profile sheet.

This commit is contained in:
Lim Chee Aun 2024-03-24 20:49:02 +08:00
parent 9c8aff6d32
commit 1a2914362f
2 changed files with 183 additions and 0 deletions

View file

@ -781,3 +781,33 @@
} }
} }
} }
#edit-profile-container {
p {
margin-block: 8px;
}
label {
input,
textarea {
display: block;
width: 100%;
}
textarea {
resize: vertical;
min-height: 5em;
max-height: 50vh;
}
}
footer {
display: flex;
justify-content: space-between;
padding: 8px 0;
* {
vertical-align: middle;
}
}
}

View file

@ -341,6 +341,17 @@ function AccountInfo({
[standalone, id, statusesCount], [standalone, id, statusesCount],
); );
const onProfileUpdate = useCallback(
(newAccount) => {
if (newAccount.id === id) {
console.log('Updated account info', newAccount);
setInfo(newAccount);
states.accounts[`${newAccount.id}@${instance}`] = newAccount;
}
},
[id, instance],
);
return ( return (
<div <div
tabIndex="-1" tabIndex="-1"
@ -793,8 +804,10 @@ function AccountInfo({
<RelatedActions <RelatedActions
info={info} info={info}
instance={instance} instance={instance}
standalone={standalone}
authenticated={authenticated} authenticated={authenticated}
onRelationshipChange={onRelationshipChange} onRelationshipChange={onRelationshipChange}
onProfileUpdate={onProfileUpdate}
/> />
</footer> </footer>
</> </>
@ -809,8 +822,10 @@ const FAMILIAR_FOLLOWERS_LIMIT = 3;
function RelatedActions({ function RelatedActions({
info, info,
instance, instance,
standalone,
authenticated, authenticated,
onRelationshipChange = () => {}, onRelationshipChange = () => {},
onProfileUpdate = () => {},
}) { }) {
if (!info) return null; if (!info) return null;
const { const {
@ -921,6 +936,7 @@ function RelatedActions({
const [showTranslatedBio, setShowTranslatedBio] = useState(false); const [showTranslatedBio, setShowTranslatedBio] = useState(false);
const [showAddRemoveLists, setShowAddRemoveLists] = useState(false); const [showAddRemoveLists, setShowAddRemoveLists] = useState(false);
const [showPrivateNoteModal, setShowPrivateNoteModal] = useState(false); const [showPrivateNoteModal, setShowPrivateNoteModal] = useState(false);
const [showEditProfile, setShowEditProfile] = useState(false);
const [lists, setLists] = useState([]); const [lists, setLists] = useState([]);
return ( return (
@ -1341,6 +1357,19 @@ function RelatedActions({
</MenuItem> </MenuItem>
</> </>
)} )}
{currentAuthenticated && isSelf && standalone && (
<>
<MenuDivider />
<MenuItem
onClick={() => {
setShowEditProfile(true);
}}
>
<Icon icon="pencil" />
<span>Edit profile</span>
</MenuItem>
</>
)}
{import.meta.env.DEV && currentAuthenticated && isSelf && ( {import.meta.env.DEV && currentAuthenticated && isSelf && (
<> <>
<MenuDivider /> <MenuDivider />
@ -1482,6 +1511,22 @@ function RelatedActions({
/> />
</Modal> </Modal>
)} )}
{!!showEditProfile && (
<Modal
onClose={() => {
setShowEditProfile(false);
}}
>
<EditProfileSheet
onClose={({ state, account } = {}) => {
setShowEditProfile(false);
if (state === 'success' && account) {
onProfileUpdate(account);
}
}}
/>
</Modal>
)}
</> </>
); );
} }
@ -1769,4 +1814,112 @@ function PrivateNoteSheet({
); );
} }
function EditProfileSheet({ onClose = () => {} }) {
const { masto } = api();
const [uiState, setUIState] = useState('loading');
const [account, setAccount] = useState(null);
useEffect(() => {
(async () => {
try {
const acc = await masto.v1.accounts.verifyCredentials();
setAccount(acc);
setUIState('default');
} catch (e) {
console.error(e);
setUIState('error');
}
})();
}, []);
console.log('EditProfileSheet', account);
const { displayName, source } = account || {};
const { note } = source || {};
return (
<div class="sheet" id="edit-profile-container">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<b>Edit profile</b>
</header>
<main>
{uiState === 'loading' ? (
<p class="ui-state">
<Loader abrupt />
</p>
) : (
<form
onSubmit={(e) => {
e.preventDefault();
const formData = new FormData(e.target);
const displayName = formData.get('display_name');
const note = formData.get('note');
(async () => {
try {
const newAccount = await masto.v1.accounts.updateCredentials({
displayName,
note,
});
console.log('updated account', newAccount);
onClose?.({
state: 'success',
account: newAccount,
});
} catch (e) {
console.error(e);
alert(e?.message || 'Unable to update profile.');
}
})();
}}
>
<p>
<label>
Name{' '}
<input
type="text"
name="display_name"
defaultValue={displayName}
maxLength={30}
disabled={uiState === 'loading'}
/>
</label>
</p>
<p>
<label>
Bio
<textarea
defaultValue={note}
name="note"
maxLength={500}
rows="5"
disabled={uiState === 'loading'}
/>
</label>
</p>
<footer>
<button
type="button"
class="light"
disabled={uiState === 'loading'}
onClick={() => {
onClose?.();
}}
>
Cancel
</button>
<button type="submit" disabled={uiState === 'loading'}>
Save
</button>
</footer>
</form>
)}
</main>
</div>
);
}
export default AccountInfo; export default AccountInfo;