phanpy/src/components/account.jsx

259 lines
7.5 KiB
React
Raw Normal View History

2022-12-10 12:14:48 +03:00
import './account.css';
import { useEffect, useState } from 'preact/hooks';
import enhanceContent from '../utils/enhance-content';
2022-12-10 12:14:48 +03:00
import shortenNumber from '../utils/shorten-number';
import store from '../utils/store';
2022-12-10 12:14:48 +03:00
import Avatar from './avatar';
import Icon from './icon';
2022-12-10 12:14:48 +03:00
import NameText from './name-text';
2022-12-16 08:27:04 +03:00
function Account({ account }) {
2022-12-10 12:14:48 +03:00
const [uiState, setUIState] = useState('default');
const isString = typeof account === 'string';
const [info, setInfo] = useState(isString ? null : account);
useEffect(() => {
if (isString) {
setUIState('loading');
(async () => {
try {
const info = await masto.v1.accounts.lookup({
2022-12-10 12:14:48 +03:00
acct: account,
skip_webfinger: false,
});
setInfo(info);
setUIState('default');
} catch (e) {
alert(e);
setUIState('error');
}
})();
}
}, []);
const {
acct,
avatar,
avatarStatic,
bot,
createdAt,
displayName,
emojis,
fields,
followersCount,
followingCount,
group,
header,
headerStatic,
id,
lastStatusAt,
locked,
note,
statusesCount,
url,
username,
} = info || {};
const [relationshipUIState, setRelationshipUIState] = useState('default');
const [relationship, setRelationship] = useState(null);
useEffect(() => {
if (info) {
const currentAccount = store.session.get('currentAccount');
if (currentAccount === id) {
// It's myself!
return;
}
2022-12-10 12:14:48 +03:00
setRelationshipUIState('loading');
(async () => {
try {
const relationships = await masto.v1.accounts.fetchRelationships([
id,
]);
2022-12-10 12:14:48 +03:00
console.log('fetched relationship', relationships);
if (relationships.length) {
setRelationship(relationships[0]);
}
setRelationshipUIState('default');
} catch (e) {
console.error(e);
setRelationshipUIState('error');
}
})();
}
}, [info]);
const {
following,
showingReblogs,
notifying,
followedBy,
blocking,
blockedBy,
muting,
mutingNotifications,
requested,
domainBlocking,
endorsed,
} = relationship || {};
return (
<div
id="account-container"
class={`sheet ${uiState === 'loading' ? 'skeleton' : ''}`}
>
{!info || uiState === 'loading' ? (
<>
<header>
<Avatar size="xxxl" />
2022-12-10 12:14:48 +03:00
</header>
<main>
<div class="note">
<p> </p>
<p> </p>
</div>
<p class="stats">
<span> Posts</span>
<span> Following</span>
<span> Followers</span>
</p>
</main>
2022-12-10 12:14:48 +03:00
</>
) : (
<>
<header>
<Avatar url={avatar} size="xxxl" />
2022-12-10 12:14:48 +03:00
<NameText account={info} showAcct external />
</header>
2022-12-30 15:37:57 +03:00
<main tabIndex="-1">
2022-12-27 12:54:48 +03:00
{bot && (
<>
<span class="tag">
<Icon icon="bot" /> Automated
</span>
</>
)}
<div
class="note"
dangerouslySetInnerHTML={{
__html: enhanceContent(note, { emojis }),
}}
/>
{fields?.length > 0 && (
<div class="profile-metadata">
{fields.map(({ name, value, verifiedAt }) => (
<div
class={`profile-field ${
verifiedAt ? 'profile-verified' : ''
}`}
key={name}
>
<b>
{name}{' '}
{!!verifiedAt && <Icon icon="check-circle" size="s" />}
</b>
<p
dangerouslySetInnerHTML={{
__html: value,
}}
/>
</div>
))}
</div>
)}
<p class="stats">
<span>
<b title={statusesCount}>{shortenNumber(statusesCount)}</b>{' '}
Posts
</span>
<span>
<b title={followingCount}>{shortenNumber(followingCount)}</b>{' '}
Following
</span>
<span>
<b title={followersCount}>{shortenNumber(followersCount)}</b>{' '}
Followers
</span>
{!!createdAt && (
<span>
Joined:{' '}
<b>
<time datetime={createdAt}>
{Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).format(new Date(createdAt))}
</time>
</b>
</span>
)}
</p>
<p class="actions">
{followedBy ? <span class="tag">Following you</span> : <span />}{' '}
{relationshipUIState !== 'loading' && relationship && (
<button
type="button"
2023-01-03 08:25:55 +03:00
class={`${following || requested ? 'light swap' : ''}`}
data-swap-state={following || requested ? 'danger' : ''}
disabled={relationshipUIState === 'loading'}
onClick={() => {
setRelationshipUIState('loading');
(async () => {
try {
let newRelationship;
2023-01-03 08:25:55 +03:00
if (following || requested) {
const yes = confirm(
2023-01-03 08:25:55 +03:00
requested
? 'Are you sure that you want to withdraw follow request?'
: 'Are you sure that you want to unfollow this account?',
);
if (yes) {
newRelationship = await masto.v1.accounts.unfollow(
id,
);
}
} else {
newRelationship = await masto.v1.accounts.follow(id);
2022-12-12 05:03:41 +03:00
}
if (newRelationship) setRelationship(newRelationship);
setRelationshipUIState('default');
} catch (e) {
alert(e);
setRelationshipUIState('error');
2022-12-10 12:14:48 +03:00
}
})();
}}
>
{following ? (
<>
<span>Following</span>
<span>Unfollow</span>
</>
2023-01-03 08:25:55 +03:00
) : requested ? (
<>
<span>Requested</span>
<span>Withdraw</span>
</>
) : locked ? (
<>
<Icon icon="lock" /> <span>Follow</span>
</>
) : (
'Follow'
)}
</button>
)}
</p>
</main>
2022-12-10 12:14:48 +03:00
</>
)}
</div>
);
2022-12-16 08:27:04 +03:00
}
export default Account;