Combine familiar followers into followers section

This commit is contained in:
Lim Chee Aun 2023-09-15 23:59:27 +08:00
parent 9571271d83
commit e102a9f925
3 changed files with 56 additions and 54 deletions

View file

@ -154,6 +154,14 @@
cursor: pointer; cursor: pointer;
text-decoration-color: var(--text-insignificant-color); text-decoration-color: var(--text-insignificant-color);
} }
.stats-avatars-bunch {
animation: appear 1s both ease-in-out;
> *:not(:first-child) {
margin: 0 0 0 -4px;
}
}
} }
.timeline-start .account-container .stats { .timeline-start .account-container .stats {
flex-wrap: wrap; flex-wrap: wrap;

View file

@ -2,6 +2,7 @@ import './account-info.css';
import { Menu, MenuDivider, MenuItem, SubMenu } from '@szhsin/react-menu'; import { Menu, MenuDivider, MenuItem, SubMenu } from '@szhsin/react-menu';
import { useEffect, useMemo, useReducer, useRef, useState } from 'preact/hooks'; import { useEffect, useMemo, useReducer, useRef, useState } from 'preact/hooks';
import { proxy, useSnapshot } from 'valtio';
import { api } from '../utils/api'; import { api } from '../utils/api';
import enhanceContent from '../utils/enhance-content'; import enhanceContent from '../utils/enhance-content';
@ -48,6 +49,10 @@ const MUTE_DURATIONS_LABELS = {
const LIMIT = 80; const LIMIT = 80;
const accountInfoStates = proxy({
familiarFollowers: [],
});
function AccountInfo({ function AccountInfo({
account, account,
fetchAccount = () => {}, fetchAccount = () => {},
@ -61,6 +66,7 @@ function AccountInfo({
const [uiState, setUIState] = useState('default'); const [uiState, setUIState] = useState('default');
const isString = typeof account === 'string'; const isString = typeof account === 'string';
const [info, setInfo] = useState(isString ? null : account); const [info, setInfo] = useState(isString ? null : account);
const snapAccountInfoStates = useSnapshot(accountInfoStates);
const isSelf = useMemo( const isSelf = useMemo(
() => account.id === store.session.get('currentAccount'), () => account.id === store.session.get('currentAccount'),
@ -394,6 +400,22 @@ function AccountInfo({
}; };
}} }}
> >
{!!snapAccountInfoStates.familiarFollowers.length && (
<span class="shazam-container-horizontal">
<span class="shazam-container-inner stats-avatars-bunch">
{(snapAccountInfoStates.familiarFollowers || []).map(
(follower) => (
<Avatar
url={follower.avatarStatic}
size="s"
alt={`${follower.displayName} @${follower.acct}`}
squircle={follower?.bot}
/>
),
)}
</span>
</span>
)}
<span title={followersCount}> <span title={followersCount}>
{shortenNumber(followersCount)} {shortenNumber(followersCount)}
</span>{' '} </span>{' '}
@ -459,7 +481,7 @@ function AccountInfo({
); );
} }
const FAMILIAR_FOLLOWERS_LIMIT = 10; const FAMILIAR_FOLLOWERS_LIMIT = 3;
function RelatedActions({ info, instance, authenticated, standalone }) { function RelatedActions({ info, instance, authenticated, standalone }) {
if (!info) return null; if (!info) return null;
@ -472,7 +494,6 @@ function RelatedActions({ info, instance, authenticated, standalone }) {
const [relationshipUIState, setRelationshipUIState] = useState('default'); const [relationshipUIState, setRelationshipUIState] = useState('default');
const [relationship, setRelationship] = useState(null); const [relationship, setRelationship] = useState(null);
const [familiarFollowers, setFamiliarFollowers] = useState([]);
const [postingStats, setPostingStats] = useState(); const [postingStats, setPostingStats] = useState();
const { id, acct, url, username, locked, lastStatusAt, note, fields } = info; const { id, acct, url, username, locked, lastStatusAt, note, fields } = info;
@ -533,7 +554,7 @@ function RelatedActions({ info, instance, authenticated, standalone }) {
accountID.current = currentID; accountID.current = currentID;
setRelationshipUIState('loading'); setRelationshipUIState('loading');
setFamiliarFollowers([]); accountInfoStates.familiarFollowers = [];
setPostingStats(null); setPostingStats(null);
const fetchRelationships = currentMasto.v1.accounts.fetchRelationships([ const fetchRelationships = currentMasto.v1.accounts.fetchRelationships([
@ -559,7 +580,8 @@ function RelatedActions({ info, instance, authenticated, standalone }) {
const followers = await fetchFamiliarFollowers; const followers = await fetchFamiliarFollowers;
console.log('fetched familiar followers', followers); console.log('fetched familiar followers', followers);
setFamiliarFollowers(followers[0].accounts); accountInfoStates.familiarFollowers =
followers[0].accounts.slice(0, FAMILIAR_FOLLOWERS_LIMIT);
if (standalone) return; if (standalone) return;
@ -624,61 +646,12 @@ function RelatedActions({ info, instance, authenticated, standalone }) {
const [showTranslatedBio, setShowTranslatedBio] = useState(false); const [showTranslatedBio, setShowTranslatedBio] = useState(false);
const [showAddRemoveLists, setShowAddRemoveLists] = useState(false); const [showAddRemoveLists, setShowAddRemoveLists] = useState(false);
const hasFamiliarFollowers = familiarFollowers?.length > 0;
const hasPostingStats = postingStats?.total >= 3; const hasPostingStats = postingStats?.total >= 3;
return ( return (
<> <>
{(hasFamiliarFollowers || hasPostingStats) && ( {hasPostingStats && (
<div class="account-metadata-box"> <div class="account-metadata-box">
{hasFamiliarFollowers && (
<div class="shazam-container">
<div class="shazam-container-inner">
<p class="common-followers">
Followed by{' '}
<span class="ib">
{familiarFollowers
.slice(0, FAMILIAR_FOLLOWERS_LIMIT)
.map((follower) => (
<a
href={follower.url}
rel="noopener noreferrer"
onClick={(e) => {
e.preventDefault();
states.showAccount = {
account: follower,
instance,
};
}}
>
<Avatar
url={follower.avatarStatic}
size="l"
alt={`${follower.displayName} @${follower.acct}`}
squircle={follower?.bot}
/>
</a>
))}
{familiarFollowers.length > FAMILIAR_FOLLOWERS_LIMIT && (
<button
type="button"
class="small plain4"
onClick={() => {
states.showGenericAccounts = {
heading: 'Followed by',
accounts: familiarFollowers,
};
}}
>
+{familiarFollowers.length - FAMILIAR_FOLLOWERS_LIMIT}
<Icon icon="chevron-down" size="s" />
</button>
)}
</span>
</p>
</div>
</div>
)}
{hasPostingStats && ( {hasPostingStats && (
<div class="shazam-container"> <div class="shazam-container">
<div class="shazam-container-inner"> <div class="shazam-container-inner">

View file

@ -438,3 +438,24 @@ kbd {
.shazam-container-inner { .shazam-container-inner {
overflow: hidden; overflow: hidden;
} }
@keyframes shazam-horizontal {
0% {
grid-template-columns: 0fr;
}
100% {
grid-template-columns: 1fr;
}
}
.shazam-container-horizontal {
display: grid;
grid-template-columns: 1fr;
transition: grid-template-columns 0.5s ease-in-out;
white-space: nowrap;
}
.shazam-container-horizontal:not(.no-animation) {
animation: shazam-horizontal 0.5s ease-in-out both !important;
}
.shazam-container-horizontal[hidden] {
grid-template-columns: 0fr;
}