mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-16 07:11:15 +03:00
Fix race conditions when accept/rejecting many follow requests
- No longer reload the whole list of follow requests and notifications for every accept/reject action - Notifications list now exclude follow requests (experimental)
This commit is contained in:
parent
37ce48ae6e
commit
8b74a32168
5 changed files with 52 additions and 12 deletions
|
@ -2,11 +2,17 @@ import { useState } from 'preact/hooks';
|
|||
|
||||
import { api } from '../utils/api';
|
||||
|
||||
import Icon from './icon';
|
||||
import Loader from './loader';
|
||||
|
||||
function FollowRequestButtons({ accountID, onChange }) {
|
||||
const { masto } = api();
|
||||
const [uiState, setUIState] = useState('default');
|
||||
const [requestState, setRequestState] = useState(null); // accept, reject
|
||||
const [relationship, setRelationship] = useState(null);
|
||||
|
||||
const hasRelationship = relationship !== null;
|
||||
|
||||
return (
|
||||
<p class="follow-request-buttons">
|
||||
<button
|
||||
|
@ -14,14 +20,19 @@ function FollowRequestButtons({ accountID, onChange }) {
|
|||
disabled={uiState === 'loading'}
|
||||
onClick={() => {
|
||||
setUIState('loading');
|
||||
setRequestState('accept');
|
||||
(async () => {
|
||||
try {
|
||||
await masto.v1.followRequests.authorize(accountID);
|
||||
const rel = await masto.v1.followRequests.authorize(accountID);
|
||||
if (!rel?.followedBy) {
|
||||
throw new Error('Follow request not accepted');
|
||||
}
|
||||
setRelationship(rel);
|
||||
onChange();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setUIState('default');
|
||||
}
|
||||
setUIState('default');
|
||||
})();
|
||||
}}
|
||||
>
|
||||
|
@ -33,9 +44,14 @@ function FollowRequestButtons({ accountID, onChange }) {
|
|||
class="light danger"
|
||||
onClick={() => {
|
||||
setUIState('loading');
|
||||
setRequestState('reject');
|
||||
(async () => {
|
||||
try {
|
||||
await masto.v1.followRequests.reject(accountID);
|
||||
const rel = await masto.v1.followRequests.reject(accountID);
|
||||
if (rel?.followedBy) {
|
||||
throw new Error('Follow request not rejected');
|
||||
}
|
||||
setRelationship(rel);
|
||||
onChange();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -46,7 +62,17 @@ function FollowRequestButtons({ accountID, onChange }) {
|
|||
>
|
||||
Reject
|
||||
</button>
|
||||
<Loader hidden={uiState !== 'loading'} />
|
||||
<span class="follow-request-states">
|
||||
{hasRelationship && requestState ? (
|
||||
requestState === 'accept' ? (
|
||||
<Icon icon="check-circle" alt="Accepted" class="follow-accepted" />
|
||||
) : (
|
||||
<Icon icon="x-circle" alt="Rejected" class="follow-rejected" />
|
||||
)
|
||||
) : (
|
||||
<Loader hidden={uiState !== 'loading'} />
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ const ICONS = {
|
|||
heart: () => import('@iconify-icons/mingcute/heart-line'),
|
||||
bookmark: () => import('@iconify-icons/mingcute/bookmark-line'),
|
||||
'check-circle': () => import('@iconify-icons/mingcute/check-circle-line'),
|
||||
'x-circle': () => import('@iconify-icons/mingcute/close-circle-line'),
|
||||
transfer: () => import('@iconify-icons/mingcute/transfer-4-line'),
|
||||
rocket: () => import('@iconify-icons/mingcute/rocket-line'),
|
||||
'arrow-left': () => import('@iconify-icons/mingcute/arrow-left-line'),
|
||||
|
|
|
@ -137,7 +137,7 @@ function Notification({ notification, instance, reload }) {
|
|||
<FollowRequestButtons
|
||||
accountID={account.id}
|
||||
onChange={() => {
|
||||
reload();
|
||||
// reload();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -204,7 +204,19 @@
|
|||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.follow-requests ul li .follow-request-buttons .loader-container {
|
||||
.follow-request-buttons .follow-request-states {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.follow-request-buttons .follow-request-states .icon {
|
||||
margin-inline: 8px;
|
||||
}
|
||||
.follow-request-buttons .follow-request-states .icon.follow-accepted {
|
||||
color: var(--green-color);
|
||||
}
|
||||
.follow-request-buttons .follow-request-states .icon.follow-rejected {
|
||||
color: var(--red-color);
|
||||
}
|
||||
.follow-requests ul li .follow-request-buttons .follow-request-states {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ function Notifications() {
|
|||
// Reset iterator
|
||||
notificationsIterator.current = masto.v1.notifications.list({
|
||||
limit: LIMIT,
|
||||
excludeTypes: ['follow_request'],
|
||||
});
|
||||
}
|
||||
const allNotifications = await notificationsIterator.current.next();
|
||||
|
@ -295,13 +296,13 @@ function Notifications() {
|
|||
<summary>{followRequests.length} follow requests</summary>
|
||||
<ul>
|
||||
{followRequests.map((account) => (
|
||||
<li>
|
||||
<li key={account.id}>
|
||||
<AccountBlock account={account} />
|
||||
<FollowRequestButtons
|
||||
accountID={account.id}
|
||||
onChange={() => {
|
||||
loadFollowRequests();
|
||||
loadNotifications(true);
|
||||
// loadFollowRequests();
|
||||
// loadNotifications(true);
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
|
@ -311,13 +312,13 @@ function Notifications() {
|
|||
) : (
|
||||
<ul>
|
||||
{followRequests.map((account) => (
|
||||
<li>
|
||||
<li key={account.id}>
|
||||
<AccountBlock account={account} />
|
||||
<FollowRequestButtons
|
||||
accountID={account.id}
|
||||
onChange={() => {
|
||||
loadFollowRequests();
|
||||
loadNotifications(true);
|
||||
// loadFollowRequests();
|
||||
// loadNotifications(true);
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
|
|
Loading…
Add table
Reference in a new issue