soapbox/src/api/hooks/accounts/useFollow.ts

88 wiersze
2.1 KiB
TypeScript
Czysty Zwykły widok Historia

2023-06-23 19:12:12 +00:00
import { importEntities } from 'soapbox/entity-store/actions';
2023-06-23 04:17:40 +00:00
import { Entities } from 'soapbox/entity-store/entities';
2023-06-23 19:12:12 +00:00
import { useTransaction } from 'soapbox/entity-store/hooks';
import { useAppDispatch, useLoggedIn } from 'soapbox/hooks';
2023-06-23 04:17:40 +00:00
import { useApi } from 'soapbox/hooks/useApi';
2023-06-23 19:12:12 +00:00
import { relationshipSchema } from 'soapbox/schemas';
2023-06-23 04:17:40 +00:00
interface FollowOpts {
reblogs?: boolean;
notify?: boolean;
languages?: string[];
}
2023-06-23 04:17:40 +00:00
function useFollow() {
const api = useApi();
2023-06-23 19:12:12 +00:00
const dispatch = useAppDispatch();
const { isLoggedIn } = useLoggedIn();
2023-06-23 19:12:12 +00:00
const { transaction } = useTransaction();
2023-06-23 04:17:40 +00:00
2023-06-23 19:12:12 +00:00
function followEffect(accountId: string) {
transaction({
Accounts: {
[accountId]: (account) => ({
...account,
followers_count: account.followers_count + 1,
}),
},
Relationships: {
[accountId]: (relationship) => ({
...relationship,
following: true,
}),
},
});
2023-06-23 04:17:40 +00:00
}
2023-06-23 19:12:12 +00:00
function unfollowEffect(accountId: string) {
transaction({
Accounts: {
[accountId]: (account) => ({
...account,
followers_count: Math.max(0, account.followers_count - 1),
}),
},
Relationships: {
[accountId]: (relationship) => ({
...relationship,
following: false,
}),
},
});
2023-06-23 04:17:40 +00:00
}
async function follow(accountId: string, options: FollowOpts = {}) {
if (!isLoggedIn) return;
2023-06-23 19:12:12 +00:00
followEffect(accountId);
2023-06-23 04:17:40 +00:00
try {
2023-06-23 19:12:12 +00:00
const response = await api.post(`/api/v1/accounts/${accountId}/follow`, options);
const result = relationshipSchema.safeParse(response.data);
if (result.success) {
dispatch(importEntities([result.data], Entities.RELATIONSHIPS));
}
2023-06-23 04:17:40 +00:00
} catch (e) {
2023-06-23 19:12:12 +00:00
unfollowEffect(accountId);
2023-06-23 04:17:40 +00:00
}
}
async function unfollow(accountId: string) {
if (!isLoggedIn) return;
2023-06-23 19:12:12 +00:00
unfollowEffect(accountId);
2023-06-23 04:17:40 +00:00
try {
await api.post(`/api/v1/accounts/${accountId}/unfollow`);
2023-06-23 04:17:40 +00:00
} catch (e) {
2023-06-23 19:12:12 +00:00
followEffect(accountId);
2023-06-23 04:17:40 +00:00
}
}
return {
follow,
unfollow,
2023-06-23 19:12:12 +00:00
followEffect,
unfollowEffect,
2023-06-23 04:17:40 +00:00
};
}
export { useFollow };