1
0
Fork 0
mirror of https://github.com/cheeaun/phanpy.git synced 2025-03-30 21:23:45 +03:00

Enable on-demand posting stats

- Slight refactor
- Make sure stats also work when switching instances
- Make sure zero stats fallback
This commit is contained in:
Lim Chee Aun 2023-10-12 23:11:20 +08:00
parent a095a30500
commit d1b8d737cc
2 changed files with 232 additions and 122 deletions

View file

@ -342,23 +342,82 @@
opacity: 1; opacity: 1;
} }
} }
.account-container .posting-stats { .account-container .posting-stats-button {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
color: inherit;
background-color: var(--bg-faded-color);
padding: 8px 12px;
font-size: 90%;
color: var(--text-insignificant-color);
line-height: 1;
vertical-align: text-top;
border-radius: 4px;
&:is(:hover, :focus-within) {
color: var(--text-color);
background-color: var(--link-bg-hover-color);
filter: none !important;
}
.loader-container {
margin: 0;
opacity: 0.5;
transform: scale(0.75);
}
}
@keyframes wobble {
0% {
transform: rotate(-4deg);
}
100% {
transform: rotate(4deg);
}
}
@keyframes loading-spin {
0% {
transform: rotate(0deg) scale(0.75);
}
100% {
transform: rotate(360deg) scale(0.75);
}
}
.posting-stats-icon {
display: inline-block;
width: 24px;
height: 8px;
filter: opacity(0.75);
animation: wobble 2s linear both infinite alternate !important;
&.loading {
animation: loading-spin 0.35s linear both infinite !important;
}
}
.account-container {
--posting-stats-size: 8px;
--original-color: var(--link-color);
.posting-stats {
font-size: 90%; font-size: 90%;
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
background-color: var(--bg-faded-color); background-color: var(--bg-faded-color);
padding: 8px 12px; padding: 8px 12px;
--size: 8px;
--original-color: var(--link-color);
&:is(:hover, :focus-within) { &:is(:hover, :focus-within) {
background-color: var(--link-bg-hover-color); background-color: var(--link-bg-hover-color);
} }
}
.posting-stats-bar { .posting-stats-bar {
--gap: 0.5px; --gap: 0.5px;
--gap-color: var(--outline-color); --gap-color: var(--outline-color);
height: var(--size); height: var(--posting-stats-size);
border-radius: var(--size); border-radius: var(--posting-stats-size);
overflow: hidden; overflow: hidden;
margin: 8px 0; margin: 8px 0;
box-shadow: inset 0 0 0 1px var(--outline-color), box-shadow: inset 0 0 0 1px var(--outline-color),
@ -388,9 +447,9 @@
.posting-stats-legend-item { .posting-stats-legend-item {
display: inline-block; display: inline-block;
width: var(--size); width: var(--posting-stats-size);
height: var(--size); height: var(--posting-stats-size);
border-radius: var(--size); border-radius: var(--posting-stats-size);
background-color: var(--text-insignificant-color); background-color: var(--text-insignificant-color);
vertical-align: middle; vertical-align: middle;
margin: 0 4px 2px; margin: 0 4px 2px;

View file

@ -206,31 +206,39 @@ function AccountInfo({
const [familiarFollowers, setFamiliarFollowers] = useState([]); const [familiarFollowers, setFamiliarFollowers] = useState([]);
const [postingStats, setPostingStats] = useState(); const [postingStats, setPostingStats] = useState();
const hasPostingStats = postingStats?.total >= 3; const [postingStatsUIState, setPostingStatsUIState] = useState('default');
const hasPostingStats = !!postingStats?.total;
const currentIDRef = useRef();
const onRelationshipChange = useCallback( const renderFamiliarFollowers = async () => {
({ relationship, currentID }) => { if (!currentIDRef.current) return;
if (!relationship.following) { const currentID = currentIDRef.current;
(async () => {
try { try {
const fetchFamiliarFollowers = const fetchFamiliarFollowers =
currentMasto.v1.accounts.familiarFollowers.fetch({ currentMasto.v1.accounts.familiarFollowers.fetch({
id: [currentID], id: [currentID],
}); });
const fetchStatuses = currentMasto.v1.accounts
.$select(currentID)
.statuses.list({
limit: 20,
})
.next();
const followers = await fetchFamiliarFollowers; const followers = await fetchFamiliarFollowers;
console.log('fetched familiar followers', followers); console.log('fetched familiar followers', followers);
setFamiliarFollowers( setFamiliarFollowers(
followers[0].accounts.slice(0, FAMILIAR_FOLLOWERS_LIMIT), followers[0].accounts.slice(0, FAMILIAR_FOLLOWERS_LIMIT),
); );
} catch (e) {
console.error(e);
}
};
const renderPostingStats = async () => {
setPostingStatsUIState('loading');
try {
const fetchStatuses = masto.v1.accounts
.$select(id)
.statuses.list({
limit: 20,
})
.next();
if (!standalone) {
const { value: statuses } = await fetchStatuses; const { value: statuses } = await fetchStatuses;
console.log('fetched statuses', statuses); console.log('fetched statuses', statuses);
const stats = { const stats = {
@ -247,10 +255,7 @@ function AccountInfo({
statuses.forEach((status) => { statuses.forEach((status) => {
if (status.reblog) { if (status.reblog) {
stats.boosts++; stats.boosts++;
} else if ( } else if (status.inReplyToAccountId !== id && !!status.inReplyToId) {
status.inReplyToAccountId !== currentID &&
!!status.inReplyToId
) {
stats.replies++; stats.replies++;
} else { } else {
stats.originals++; stats.originals++;
@ -259,18 +264,27 @@ function AccountInfo({
// Count days since last post // Count days since last post
stats.daysSinceLastPost = Math.ceil( stats.daysSinceLastPost = Math.ceil(
(Date.now() - (Date.now() - new Date(statuses[statuses.length - 1].createdAt)) /
new Date(statuses[statuses.length - 1].createdAt)) /
86400000, 86400000,
); );
console.log('posting stats', stats); console.log('posting stats', stats);
setPostingStats(stats); setPostingStats(stats);
} setPostingStatsUIState('default');
} catch (e) { } catch (e) {
console.error(e); console.error(e);
setPostingStatsUIState('error');
}
};
const onRelationshipChange = useCallback(
({ relationship, currentID }) => {
currentIDRef.current = currentID;
if (!relationship.following) {
renderFamiliarFollowers();
if (!standalone) {
renderPostingStats();
} }
})();
} }
}, },
[standalone], [standalone],
@ -586,8 +600,8 @@ function AccountInfo({
)} )}
</div> </div>
</div> </div>
{hasPostingStats && ( {!!postingStats && (
<Link <LinkOrDiv
to={accountLink} to={accountLink}
class="account-metadata-box" class="account-metadata-box"
onClick={() => { onClick={() => {
@ -596,6 +610,7 @@ function AccountInfo({
> >
<div class="shazam-container"> <div class="shazam-container">
<div class="shazam-container-inner"> <div class="shazam-container-inner">
{hasPostingStats ? (
<div <div
class="posting-stats" class="posting-stats"
title={`${Math.round( title={`${Math.round(
@ -625,7 +640,8 @@ function AccountInfo({
100 100
}%`, }%`,
'--replies-percentage': `${ '--replies-percentage': `${
((postingStats.originals + postingStats.replies) / ((postingStats.originals +
postingStats.replies) /
postingStats.total) * postingStats.total) *
100 100
}%`, }%`,
@ -646,10 +662,45 @@ function AccountInfo({
</span> </span>
</div> </div>
</div> </div>
</div> ) : (
</div> <div class="posting-stats">Post stats unavailable.</div>
</Link>
)} )}
</div>
</div>
</LinkOrDiv>
)}
<div class="account-metadata-box">
<div
class="shazam-container no-animation"
hidden={!!postingStats}
>
<div class="shazam-container-inner">
<button
type="button"
class="posting-stats-button"
disabled={postingStatsUIState === 'loading'}
onClick={() => {
renderPostingStats();
}}
>
<div
class={`posting-stats-bar posting-stats-icon ${
postingStatsUIState === 'loading' ? 'loading' : ''
}`}
style={{
'--originals-percentage': '33%',
'--replies-percentage': '66%',
}}
/>
View post stats{' '}
{/* <Loader
abrupt
hidden={postingStatsUIState !== 'loading'}
/> */}
</button>
</div>
</div>
</div>
<RelatedActions <RelatedActions
info={info} info={info}
instance={instance} instance={instance}