pl-fe: migrate follow requests to tanstack query
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
parent
0218fa445f
commit
f6e2f7c6c6
12 changed files with 103 additions and 499 deletions
|
@ -7,7 +7,6 @@ import { normalizeAccount } from 'pl-fe/normalizers/account';
|
||||||
import { ListRecord, ReducerRecord } from 'pl-fe/reducers/user-lists';
|
import { ListRecord, ReducerRecord } from 'pl-fe/reducers/user-lists';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
authorizeFollowRequest,
|
|
||||||
blockAccount,
|
blockAccount,
|
||||||
createAccount,
|
createAccount,
|
||||||
expandFollowRequests,
|
expandFollowRequests,
|
||||||
|
@ -940,240 +939,3 @@ describe('fetchRelationships()', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchFollowRequests()', () => {
|
|
||||||
describe('when logged out', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = { ...rootState, me: null };
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing', async() => {
|
|
||||||
await store.dispatch(fetchFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when logged in', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = { ...rootState, me: '123' };
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with a successful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = {
|
|
||||||
...rootState,
|
|
||||||
me: '123',
|
|
||||||
relationships: ImmutableMap(),
|
|
||||||
};
|
|
||||||
|
|
||||||
store = mockStore(state);
|
|
||||||
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onGet('/api/v1/follow_requests').reply(200, [], {
|
|
||||||
link: '<https://example.com/api/v1/follow_requests?since_id=1>; rel=\'prev\'',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUESTS_FETCH_REQUEST' },
|
|
||||||
{ type: 'ACCOUNTS_IMPORT', accounts: [] },
|
|
||||||
{
|
|
||||||
type: 'FOLLOW_REQUESTS_FETCH_SUCCESS',
|
|
||||||
accounts: [],
|
|
||||||
next: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
await store.dispatch(fetchFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an unsuccessful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onGet('/api/v1/follow_requests').networkError();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUESTS_FETCH_REQUEST' },
|
|
||||||
{ type: 'FOLLOW_REQUESTS_FETCH_FAIL', error: new Error('Network Error') },
|
|
||||||
];
|
|
||||||
await store.dispatch(fetchFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('expandFollowRequests()', () => {
|
|
||||||
describe('when logged out', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = { ...rootState, me: null };
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing', async() => {
|
|
||||||
await store.dispatch(expandFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when logged in', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = {
|
|
||||||
...rootState,
|
|
||||||
me: '123',
|
|
||||||
user_lists: ReducerRecord({
|
|
||||||
follow_requests: ListRecord({
|
|
||||||
next: 'next_url',
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the url is null', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = {
|
|
||||||
...rootState,
|
|
||||||
me: '123',
|
|
||||||
user_lists: ReducerRecord({
|
|
||||||
follow_requests: ListRecord({
|
|
||||||
next: null,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing', async() => {
|
|
||||||
await store.dispatch(expandFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with a successful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onGet('next_url').reply(200, [], {
|
|
||||||
link: '<next_url>; rel=\'prev\'',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUESTS_EXPAND_REQUEST' },
|
|
||||||
{ type: 'ACCOUNTS_IMPORT', accounts: [] },
|
|
||||||
{
|
|
||||||
type: 'FOLLOW_REQUESTS_EXPAND_SUCCESS',
|
|
||||||
accounts: [],
|
|
||||||
next: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
await store.dispatch(expandFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an unsuccessful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onGet('next_url').networkError();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUESTS_EXPAND_REQUEST' },
|
|
||||||
{ type: 'FOLLOW_REQUESTS_EXPAND_FAIL', error: new Error('Network Error') },
|
|
||||||
];
|
|
||||||
await store.dispatch(expandFollowRequests());
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('authorizeFollowRequest()', () => {
|
|
||||||
const id = '1';
|
|
||||||
|
|
||||||
describe('when logged out', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = { ...rootState, me: null };
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing', async() => {
|
|
||||||
await store.dispatch(authorizeFollowRequest(id));
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when logged in', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const state = { ...rootState, me: '123' };
|
|
||||||
store = mockStore(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with a successful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onPost(`/api/v1/follow_requests/${id}/authorize`).reply(200);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUEST_AUTHORIZE_REQUEST', id },
|
|
||||||
{ type: 'FOLLOW_REQUEST_AUTHORIZE_SUCCESS', id },
|
|
||||||
];
|
|
||||||
await store.dispatch(authorizeFollowRequest(id));
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an unsuccessful API request', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
__stub((mock) => {
|
|
||||||
mock.onPost(`/api/v1/follow_requests/${id}/authorize`).networkError();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the correct actions', async() => {
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'FOLLOW_REQUEST_AUTHORIZE_REQUEST', id },
|
|
||||||
{ type: 'FOLLOW_REQUEST_AUTHORIZE_FAIL', id, error: new Error('Network Error') },
|
|
||||||
];
|
|
||||||
await store.dispatch(authorizeFollowRequest(id));
|
|
||||||
const actions = store.getActions();
|
|
||||||
|
|
||||||
expect(actions).toEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import {
|
||||||
type UpdateNotificationSettingsParams,
|
type UpdateNotificationSettingsParams,
|
||||||
type Account,
|
type Account,
|
||||||
type CreateAccountParams,
|
type CreateAccountParams,
|
||||||
type PaginatedResponse,
|
|
||||||
type PlApiClient,
|
type PlApiClient,
|
||||||
type Relationship,
|
type Relationship,
|
||||||
type Token,
|
type Token,
|
||||||
|
@ -51,22 +50,6 @@ const ACCOUNT_LOOKUP_REQUEST = 'ACCOUNT_LOOKUP_REQUEST' as const;
|
||||||
const ACCOUNT_LOOKUP_SUCCESS = 'ACCOUNT_LOOKUP_SUCCESS' as const;
|
const ACCOUNT_LOOKUP_SUCCESS = 'ACCOUNT_LOOKUP_SUCCESS' as const;
|
||||||
const ACCOUNT_LOOKUP_FAIL = 'ACCOUNT_LOOKUP_FAIL' as const;
|
const ACCOUNT_LOOKUP_FAIL = 'ACCOUNT_LOOKUP_FAIL' as const;
|
||||||
|
|
||||||
const FOLLOW_REQUESTS_FETCH_REQUEST = 'FOLLOW_REQUESTS_FETCH_REQUEST' as const;
|
|
||||||
const FOLLOW_REQUESTS_FETCH_SUCCESS = 'FOLLOW_REQUESTS_FETCH_SUCCESS' as const;
|
|
||||||
const FOLLOW_REQUESTS_FETCH_FAIL = 'FOLLOW_REQUESTS_FETCH_FAIL' as const;
|
|
||||||
|
|
||||||
const FOLLOW_REQUESTS_EXPAND_REQUEST = 'FOLLOW_REQUESTS_EXPAND_REQUEST' as const;
|
|
||||||
const FOLLOW_REQUESTS_EXPAND_SUCCESS = 'FOLLOW_REQUESTS_EXPAND_SUCCESS' as const;
|
|
||||||
const FOLLOW_REQUESTS_EXPAND_FAIL = 'FOLLOW_REQUESTS_EXPAND_FAIL' as const;
|
|
||||||
|
|
||||||
const FOLLOW_REQUEST_AUTHORIZE_REQUEST = 'FOLLOW_REQUEST_AUTHORIZE_REQUEST' as const;
|
|
||||||
const FOLLOW_REQUEST_AUTHORIZE_SUCCESS = 'FOLLOW_REQUEST_AUTHORIZE_SUCCESS' as const;
|
|
||||||
const FOLLOW_REQUEST_AUTHORIZE_FAIL = 'FOLLOW_REQUEST_AUTHORIZE_FAIL' as const;
|
|
||||||
|
|
||||||
const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST' as const;
|
|
||||||
const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS' as const;
|
|
||||||
const FOLLOW_REQUEST_REJECT_FAIL = 'FOLLOW_REQUEST_REJECT_FAIL' as const;
|
|
||||||
|
|
||||||
const NOTIFICATION_SETTINGS_REQUEST = 'NOTIFICATION_SETTINGS_REQUEST' as const;
|
const NOTIFICATION_SETTINGS_REQUEST = 'NOTIFICATION_SETTINGS_REQUEST' as const;
|
||||||
const NOTIFICATION_SETTINGS_SUCCESS = 'NOTIFICATION_SETTINGS_SUCCESS' as const;
|
const NOTIFICATION_SETTINGS_SUCCESS = 'NOTIFICATION_SETTINGS_SUCCESS' as const;
|
||||||
const NOTIFICATION_SETTINGS_FAIL = 'NOTIFICATION_SETTINGS_FAIL' as const;
|
const NOTIFICATION_SETTINGS_FAIL = 'NOTIFICATION_SETTINGS_FAIL' as const;
|
||||||
|
@ -313,120 +296,6 @@ const fetchRelationships = (accountIds: string[]) =>
|
||||||
.then(response => dispatch(importEntities({ relationships: response })));
|
.then(response => dispatch(importEntities({ relationships: response })));
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchFollowRequests = () =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
if (!isLoggedIn(getState)) return null;
|
|
||||||
|
|
||||||
dispatch(fetchFollowRequestsRequest());
|
|
||||||
|
|
||||||
return getClient(getState()).myAccount.getFollowRequests()
|
|
||||||
.then(response => {
|
|
||||||
dispatch(importEntities({ accounts: response.items }));
|
|
||||||
dispatch(fetchFollowRequestsSuccess(response.items, response.next));
|
|
||||||
})
|
|
||||||
.catch(error => dispatch(fetchFollowRequestsFail(error)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchFollowRequestsRequest = () => ({
|
|
||||||
type: FOLLOW_REQUESTS_FETCH_REQUEST,
|
|
||||||
});
|
|
||||||
|
|
||||||
const fetchFollowRequestsSuccess = (accounts: Array<Account>, next: (() => Promise<PaginatedResponse<Account>>) | null) => ({
|
|
||||||
type: FOLLOW_REQUESTS_FETCH_SUCCESS,
|
|
||||||
accounts,
|
|
||||||
next,
|
|
||||||
});
|
|
||||||
|
|
||||||
const fetchFollowRequestsFail = (error: unknown) => ({
|
|
||||||
type: FOLLOW_REQUESTS_FETCH_FAIL,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expandFollowRequests = () =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
if (!isLoggedIn(getState)) return null;
|
|
||||||
|
|
||||||
const next = getState().user_lists.follow_requests.next;
|
|
||||||
|
|
||||||
if (next === null) return null;
|
|
||||||
|
|
||||||
dispatch(expandFollowRequestsRequest());
|
|
||||||
|
|
||||||
return next().then(response => {
|
|
||||||
dispatch(importEntities({ accounts: response.items }));
|
|
||||||
dispatch(expandFollowRequestsSuccess(response.items, response.next));
|
|
||||||
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const expandFollowRequestsRequest = () => ({
|
|
||||||
type: FOLLOW_REQUESTS_EXPAND_REQUEST,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expandFollowRequestsSuccess = (accounts: Array<Account>, next: (() => Promise<PaginatedResponse<Account>>) | null) => ({
|
|
||||||
type: FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
|
||||||
accounts,
|
|
||||||
next,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expandFollowRequestsFail = (error: unknown) => ({
|
|
||||||
type: FOLLOW_REQUESTS_EXPAND_FAIL,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
const authorizeFollowRequest = (accountId: string) =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
if (!isLoggedIn(getState)) return null;
|
|
||||||
|
|
||||||
dispatch(authorizeFollowRequestRequest(accountId));
|
|
||||||
|
|
||||||
return getClient(getState()).myAccount.acceptFollowRequest(accountId)
|
|
||||||
.then(() => dispatch(authorizeFollowRequestSuccess(accountId)))
|
|
||||||
.catch(error => dispatch(authorizeFollowRequestFail(accountId, error)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const authorizeFollowRequestRequest = (accountId: string) => ({
|
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const authorizeFollowRequestSuccess = (accountId: string) => ({
|
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const authorizeFollowRequestFail = (accountId: string, error: unknown) => ({
|
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_FAIL,
|
|
||||||
accountId,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rejectFollowRequest = (accountId: string) =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
if (!isLoggedIn(getState)) return;
|
|
||||||
|
|
||||||
dispatch(rejectFollowRequestRequest(accountId));
|
|
||||||
|
|
||||||
return getClient(getState()).myAccount.rejectFollowRequest(accountId)
|
|
||||||
.then(() => dispatch(rejectFollowRequestSuccess(accountId)))
|
|
||||||
.catch(error => dispatch(rejectFollowRequestFail(accountId, error)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const rejectFollowRequestRequest = (accountId: string) => ({
|
|
||||||
type: FOLLOW_REQUEST_REJECT_REQUEST,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rejectFollowRequestSuccess = (accountId: string) => ({
|
|
||||||
type: FOLLOW_REQUEST_REJECT_SUCCESS,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rejectFollowRequestFail = (accountId: string, error: unknown) => ({
|
|
||||||
type: FOLLOW_REQUEST_REJECT_FAIL,
|
|
||||||
accountId,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
const pinAccount = (accountId: string) =>
|
const pinAccount = (accountId: string) =>
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
if (!isLoggedIn(getState)) return dispatch(noOp);
|
if (!isLoggedIn(getState)) return dispatch(noOp);
|
||||||
|
@ -580,18 +449,6 @@ type AccountsAction =
|
||||||
| ReturnType<typeof muteAccountRequest>
|
| ReturnType<typeof muteAccountRequest>
|
||||||
| ReturnType<typeof muteAccountSuccess>
|
| ReturnType<typeof muteAccountSuccess>
|
||||||
| ReturnType<typeof muteAccountFail>
|
| ReturnType<typeof muteAccountFail>
|
||||||
| ReturnType<typeof fetchFollowRequestsRequest>
|
|
||||||
| ReturnType<typeof fetchFollowRequestsSuccess>
|
|
||||||
| ReturnType<typeof fetchFollowRequestsFail>
|
|
||||||
| ReturnType<typeof expandFollowRequestsRequest>
|
|
||||||
| ReturnType<typeof expandFollowRequestsSuccess>
|
|
||||||
| ReturnType<typeof expandFollowRequestsFail>
|
|
||||||
| ReturnType<typeof authorizeFollowRequestRequest>
|
|
||||||
| ReturnType<typeof authorizeFollowRequestSuccess>
|
|
||||||
| ReturnType<typeof authorizeFollowRequestFail>
|
|
||||||
| ReturnType<typeof rejectFollowRequestRequest>
|
|
||||||
| ReturnType<typeof rejectFollowRequestSuccess>
|
|
||||||
| ReturnType<typeof rejectFollowRequestFail>
|
|
||||||
| NotificationSettingsRequestAction
|
| NotificationSettingsRequestAction
|
||||||
| NotificationSettingsSuccessAction
|
| NotificationSettingsSuccessAction
|
||||||
| NotificationSettingsFailAction
|
| NotificationSettingsFailAction
|
||||||
|
@ -627,18 +484,6 @@ export {
|
||||||
ACCOUNT_LOOKUP_REQUEST,
|
ACCOUNT_LOOKUP_REQUEST,
|
||||||
ACCOUNT_LOOKUP_SUCCESS,
|
ACCOUNT_LOOKUP_SUCCESS,
|
||||||
ACCOUNT_LOOKUP_FAIL,
|
ACCOUNT_LOOKUP_FAIL,
|
||||||
FOLLOW_REQUESTS_FETCH_REQUEST,
|
|
||||||
FOLLOW_REQUESTS_FETCH_SUCCESS,
|
|
||||||
FOLLOW_REQUESTS_FETCH_FAIL,
|
|
||||||
FOLLOW_REQUESTS_EXPAND_REQUEST,
|
|
||||||
FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
|
||||||
FOLLOW_REQUESTS_EXPAND_FAIL,
|
|
||||||
FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
|
||||||
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
|
||||||
FOLLOW_REQUEST_AUTHORIZE_FAIL,
|
|
||||||
FOLLOW_REQUEST_REJECT_REQUEST,
|
|
||||||
FOLLOW_REQUEST_REJECT_SUCCESS,
|
|
||||||
FOLLOW_REQUEST_REJECT_FAIL,
|
|
||||||
NOTIFICATION_SETTINGS_REQUEST,
|
NOTIFICATION_SETTINGS_REQUEST,
|
||||||
NOTIFICATION_SETTINGS_SUCCESS,
|
NOTIFICATION_SETTINGS_SUCCESS,
|
||||||
NOTIFICATION_SETTINGS_FAIL,
|
NOTIFICATION_SETTINGS_FAIL,
|
||||||
|
@ -651,10 +496,6 @@ export {
|
||||||
unmuteAccount,
|
unmuteAccount,
|
||||||
removeFromFollowers,
|
removeFromFollowers,
|
||||||
fetchRelationships,
|
fetchRelationships,
|
||||||
fetchFollowRequests,
|
|
||||||
expandFollowRequests,
|
|
||||||
authorizeFollowRequest,
|
|
||||||
rejectFollowRequest,
|
|
||||||
pinAccount,
|
pinAccount,
|
||||||
unpinAccount,
|
unpinAccount,
|
||||||
updateNotificationSettings,
|
updateNotificationSettings,
|
||||||
|
|
|
@ -55,12 +55,6 @@ const REMOTE_INTERACTION_REQUEST = 'REMOTE_INTERACTION_REQUEST' as const;
|
||||||
const REMOTE_INTERACTION_SUCCESS = 'REMOTE_INTERACTION_SUCCESS' as const;
|
const REMOTE_INTERACTION_SUCCESS = 'REMOTE_INTERACTION_SUCCESS' as const;
|
||||||
const REMOTE_INTERACTION_FAIL = 'REMOTE_INTERACTION_FAIL' as const;
|
const REMOTE_INTERACTION_FAIL = 'REMOTE_INTERACTION_FAIL' as const;
|
||||||
|
|
||||||
const FAVOURITES_EXPAND_SUCCESS = 'FAVOURITES_EXPAND_SUCCESS' as const;
|
|
||||||
const FAVOURITES_EXPAND_FAIL = 'FAVOURITES_EXPAND_FAIL' as const;
|
|
||||||
|
|
||||||
const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS' as const;
|
|
||||||
const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL' as const;
|
|
||||||
|
|
||||||
const noOp = () => new Promise(f => f(undefined));
|
const noOp = () => new Promise(f => f(undefined));
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -551,10 +545,6 @@ export {
|
||||||
REMOTE_INTERACTION_REQUEST,
|
REMOTE_INTERACTION_REQUEST,
|
||||||
REMOTE_INTERACTION_SUCCESS,
|
REMOTE_INTERACTION_SUCCESS,
|
||||||
REMOTE_INTERACTION_FAIL,
|
REMOTE_INTERACTION_FAIL,
|
||||||
FAVOURITES_EXPAND_SUCCESS,
|
|
||||||
FAVOURITES_EXPAND_FAIL,
|
|
||||||
REBLOGS_EXPAND_SUCCESS,
|
|
||||||
REBLOGS_EXPAND_FAIL,
|
|
||||||
reblog,
|
reblog,
|
||||||
unreblog,
|
unreblog,
|
||||||
toggleReblog,
|
toggleReblog,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'intl-pluralrules';
|
||||||
import { defineMessages } from 'react-intl';
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { getClient } from 'pl-fe/api';
|
import { getClient } from 'pl-fe/api';
|
||||||
|
import { appendFollowRequest } from 'pl-fe/api/hooks/account-lists/use-follow-requests';
|
||||||
import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification';
|
import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification';
|
||||||
import { normalizeNotification } from 'pl-fe/normalizers/notification';
|
import { normalizeNotification } from 'pl-fe/normalizers/notification';
|
||||||
import { getFilters, regexFromFilters } from 'pl-fe/selectors';
|
import { getFilters, regexFromFilters } from 'pl-fe/selectors';
|
||||||
|
@ -74,9 +75,14 @@ const updateNotifications = (notification: BaseNotification) =>
|
||||||
statuses: [getNotificationStatus(notification) as any],
|
statuses: [getNotificationStatus(notification) as any],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
if (showInColumn) {
|
if (showInColumn) {
|
||||||
const normalizedNotification = normalizeNotification(notification);
|
const normalizedNotification = normalizeNotification(notification);
|
||||||
|
|
||||||
|
if (normalizedNotification.type === 'follow_request') {
|
||||||
|
normalizedNotification.sample_account_ids.forEach(appendFollowRequest);
|
||||||
|
}
|
||||||
|
|
||||||
dispatch<NotificationsUpdateAction>({
|
dispatch<NotificationsUpdateAction>({
|
||||||
type: NOTIFICATIONS_UPDATE,
|
type: NOTIFICATIONS_UPDATE,
|
||||||
notification: normalizedNotification,
|
notification: normalizedNotification,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import { InfiniteData, useInfiniteQuery, useMutation } from '@tanstack/react-query';
|
import { type InfiniteData, useInfiniteQuery, useMutation } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { importEntities } from 'pl-fe/actions/importer';
|
import { importEntities } from 'pl-fe/actions/importer';
|
||||||
import { minifyList } from 'pl-fe/api/normalizers/minify-list';
|
import { minifyList } from 'pl-fe/api/normalizers/minify-list';
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
import { useInfiniteQuery, useMutation, type InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { minifyAccountList } from 'pl-fe/api/normalizers/minify-list';
|
||||||
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
|
import { queryClient } from 'pl-fe/queries/client';
|
||||||
|
|
||||||
|
import type { PaginatedResponse, PlApiClient } from 'pl-api';
|
||||||
|
|
||||||
|
const appendFollowRequest = (accountId: string) =>
|
||||||
|
queryClient.setQueryData<InfiniteData<ReturnType<typeof minifyAccountList>>>(['accountsLists', 'followRequests'], (data) => {
|
||||||
|
if (!data || data.pages.some(page => page.items.includes(accountId))) return data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
pages: data.pages.map((page, index) => index === 0 ? ({ ...page, items: [accountId, ...page.items] }) : page),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeFollowRequest = (accountId: string) =>
|
||||||
|
queryClient.setQueryData<InfiniteData<ReturnType<typeof minifyAccountList>>>(['accountsLists', 'followRequests'], (data) => data ? {
|
||||||
|
...data,
|
||||||
|
pages: data.pages.map(({ items, ...page }) => ({ ...page, items: items.filter((id) => id !== accountId) })),
|
||||||
|
} : undefined);
|
||||||
|
|
||||||
|
const useFollowRequests = () => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useInfiniteQuery({
|
||||||
|
queryKey: ['accountsLists', 'followRequests'],
|
||||||
|
queryFn: ({ pageParam }) => pageParam.next?.() || client.myAccount.getFollowRequests().then(minifyAccountList),
|
||||||
|
initialPageParam: { previous: null, next: null, items: [], partial: false } as PaginatedResponse<string>,
|
||||||
|
getNextPageParam: (page) => page.next ? page : undefined,
|
||||||
|
select: (data) => data.pages.map(page => page.items).flat(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const useAcceptFollowRequestMutation = (accountId: string) => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ['accountsLists', 'followRequests', accountId],
|
||||||
|
mutationFn: () => client.myAccount.acceptFollowRequest(accountId),
|
||||||
|
onSettled: () => removeFollowRequest(accountId),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const useRejectFollowRequestMutation = (accountId: string) => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ['accountsLists', 'followRequests', accountId],
|
||||||
|
mutationFn: () => client.myAccount.rejectFollowRequest(accountId),
|
||||||
|
onSettled: () => removeFollowRequest(accountId),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const prefetchFollowRequests = (client: PlApiClient) => queryClient.prefetchInfiniteQuery({
|
||||||
|
queryKey: ['accountsLists', 'followRequests'],
|
||||||
|
queryFn: ({ pageParam }) => pageParam.next?.() || client.myAccount.getFollowRequests().then(minifyAccountList),
|
||||||
|
initialPageParam: { previous: null, next: null, items: [], partial: false } as PaginatedResponse<string>,
|
||||||
|
});
|
||||||
|
|
||||||
|
export { appendFollowRequest, useFollowRequests, useAcceptFollowRequestMutation, useRejectFollowRequestMutation, prefetchFollowRequests };
|
|
@ -1,21 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { authorizeFollowRequest, rejectFollowRequest } from 'pl-fe/actions/accounts';
|
import { useAcceptFollowRequestMutation, useRejectFollowRequestMutation } from 'pl-fe/api/hooks/account-lists/use-follow-requests';
|
||||||
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
||||||
import Account from 'pl-fe/components/account';
|
import Account from 'pl-fe/components/account';
|
||||||
import { AuthorizeRejectButtons } from 'pl-fe/components/authorize-reject-buttons';
|
import { AuthorizeRejectButtons } from 'pl-fe/components/authorize-reject-buttons';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
|
||||||
|
|
||||||
interface IAccountAuthorize {
|
interface IAccountAuthorize {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AccountAuthorize: React.FC<IAccountAuthorize> = ({ id }) => {
|
const AccountAuthorize: React.FC<IAccountAuthorize> = ({ id }) => {
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { account } = useAccount(id);
|
const { account } = useAccount(id);
|
||||||
|
|
||||||
const onAuthorize = () => dispatch(authorizeFollowRequest(id));
|
const { mutate: authorizeFollowRequest } = useAcceptFollowRequestMutation(id);
|
||||||
const onReject = () => dispatch(rejectFollowRequest(id));
|
const { mutate: rejectFollowRequest } = useRejectFollowRequestMutation(id);
|
||||||
|
|
||||||
|
const onAuthorize = () => authorizeFollowRequest();
|
||||||
|
const onReject = () => rejectFollowRequest();
|
||||||
|
|
||||||
if (!account) return null;
|
if (!account) return null;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import debounce from 'lodash/debounce';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { fetchFollowRequests, expandFollowRequests } from 'pl-fe/actions/accounts';
|
import { useFollowRequests } from 'pl-fe/api/hooks/account-lists/use-follow-requests';
|
||||||
import ScrollableList from 'pl-fe/components/scrollable-list';
|
import ScrollableList from 'pl-fe/components/scrollable-list';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Spinner from 'pl-fe/components/ui/spinner';
|
import Spinner from 'pl-fe/components/ui/spinner';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
|
||||||
|
|
||||||
import AccountAuthorize from './components/account-authorize';
|
import AccountAuthorize from './components/account-authorize';
|
||||||
|
|
||||||
|
@ -15,20 +12,10 @@ const messages = defineMessages({
|
||||||
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleLoadMore = debounce((dispatch) => {
|
|
||||||
dispatch(expandFollowRequests());
|
|
||||||
}, 300, { leading: true });
|
|
||||||
|
|
||||||
const FollowRequests: React.FC = () => {
|
const FollowRequests: React.FC = () => {
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const accountIds = useAppSelector((state) => state.user_lists.follow_requests.items);
|
const { data: accountIds, isLoading, hasNextPage, fetchNextPage } = useFollowRequests();
|
||||||
const hasMore = useAppSelector((state) => !!state.user_lists.follow_requests.next);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
dispatch(fetchFollowRequests());
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -43,8 +30,9 @@ const FollowRequests: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<Column label={intl.formatMessage(messages.heading)}>
|
<Column label={intl.formatMessage(messages.heading)}>
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
onLoadMore={() => handleLoadMore(dispatch)}
|
hasMore={hasNextPage}
|
||||||
hasMore={hasMore}
|
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
|
||||||
|
onLoadMore={() => fetchNextPage({ cancelRefetch: false })}
|
||||||
emptyMessage={emptyMessage}
|
emptyMessage={emptyMessage}
|
||||||
>
|
>
|
||||||
{accountIds.map(id =>
|
{accountIds.map(id =>
|
||||||
|
|
|
@ -6,10 +6,9 @@ import {
|
||||||
unblockAccount,
|
unblockAccount,
|
||||||
muteAccount,
|
muteAccount,
|
||||||
unmuteAccount,
|
unmuteAccount,
|
||||||
authorizeFollowRequest,
|
|
||||||
rejectFollowRequest,
|
|
||||||
biteAccount,
|
biteAccount,
|
||||||
} from 'pl-fe/actions/accounts';
|
} from 'pl-fe/actions/accounts';
|
||||||
|
import { useAcceptFollowRequestMutation, useRejectFollowRequestMutation } from 'pl-fe/api/hooks/account-lists/use-follow-requests';
|
||||||
import { useFollow } from 'pl-fe/api/hooks/accounts/use-follow';
|
import { useFollow } from 'pl-fe/api/hooks/accounts/use-follow';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
|
@ -63,6 +62,9 @@ const ActionButton: React.FC<IActionButton> = ({ account, actionType, small }) =
|
||||||
const { isLoggedIn, me } = useLoggedIn();
|
const { isLoggedIn, me } = useLoggedIn();
|
||||||
const { follow, unfollow } = useFollow();
|
const { follow, unfollow } = useFollow();
|
||||||
|
|
||||||
|
const { mutate: authorizeFollowRequest } = useAcceptFollowRequestMutation(account.id);
|
||||||
|
const { mutate: rejectFollowRequest } = useRejectFollowRequestMutation(account.id);
|
||||||
|
|
||||||
const handleFollow = () => {
|
const handleFollow = () => {
|
||||||
if (account.relationship?.following || account.relationship?.requested) {
|
if (account.relationship?.following || account.relationship?.requested) {
|
||||||
unfollow(account.id);
|
unfollow(account.id);
|
||||||
|
@ -88,11 +90,11 @@ const ActionButton: React.FC<IActionButton> = ({ account, actionType, small }) =
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAuthorize = () => {
|
const handleAuthorize = () => {
|
||||||
dispatch(authorizeFollowRequest(account.id));
|
authorizeFollowRequest();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReject = () => {
|
const handleReject = () => {
|
||||||
dispatch(rejectFollowRequest(account.id));
|
rejectFollowRequest();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBite = () => {
|
const handleBite = () => {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import clsx from 'clsx';
|
||||||
import React, { Suspense, lazy, useEffect, useRef } from 'react';
|
import React, { Suspense, lazy, useEffect, useRef } from 'react';
|
||||||
import { Redirect, Switch, useHistory, useLocation } from 'react-router-dom';
|
import { Redirect, Switch, useHistory, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
import { fetchFollowRequests } from 'pl-fe/actions/accounts';
|
|
||||||
import { fetchConfig, fetchReports, fetchUsers } from 'pl-fe/actions/admin';
|
import { fetchConfig, fetchReports, fetchUsers } from 'pl-fe/actions/admin';
|
||||||
import { fetchCustomEmojis } from 'pl-fe/actions/custom-emojis';
|
import { fetchCustomEmojis } from 'pl-fe/actions/custom-emojis';
|
||||||
import { fetchDraftStatuses } from 'pl-fe/actions/draft-statuses';
|
import { fetchDraftStatuses } from 'pl-fe/actions/draft-statuses';
|
||||||
|
@ -12,12 +11,14 @@ import { expandNotifications } from 'pl-fe/actions/notifications';
|
||||||
import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications/registerer';
|
import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications/registerer';
|
||||||
import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses';
|
import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses';
|
||||||
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
||||||
|
import { prefetchFollowRequests } from 'pl-fe/api/hooks/account-lists/use-follow-requests';
|
||||||
import { useUserStream } from 'pl-fe/api/hooks/streaming/use-user-stream';
|
import { useUserStream } from 'pl-fe/api/hooks/streaming/use-user-stream';
|
||||||
import SidebarNavigation from 'pl-fe/components/sidebar-navigation';
|
import SidebarNavigation from 'pl-fe/components/sidebar-navigation';
|
||||||
import ThumbNavigation from 'pl-fe/components/thumb-navigation';
|
import ThumbNavigation from 'pl-fe/components/thumb-navigation';
|
||||||
import Layout from 'pl-fe/components/ui/layout';
|
import Layout from 'pl-fe/components/ui/layout';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
import { useInstance } from 'pl-fe/hooks/use-instance';
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
@ -362,6 +363,7 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const vapidKey = useAppSelector(state => getVapidKey(state));
|
const vapidKey = useAppSelector(state => getVapidKey(state));
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
const { isDropdownMenuOpen } = useUiStore();
|
const { isDropdownMenuOpen } = useUiStore();
|
||||||
const standalone = useAppSelector(isStandalone);
|
const standalone = useAppSelector(isStandalone);
|
||||||
|
@ -409,7 +411,7 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
setTimeout(() => dispatch(fetchFilters()), 500);
|
setTimeout(() => dispatch(fetchFilters()), 500);
|
||||||
|
|
||||||
if (account.locked) {
|
if (account.locked) {
|
||||||
setTimeout(() => dispatch(fetchFollowRequests()), 700);
|
setTimeout(() => prefetchFollowRequests(client), 700);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => dispatch(fetchScheduledStatuses()), 900);
|
setTimeout(() => dispatch(fetchScheduledStatuses()), 900);
|
||||||
|
|
|
@ -3,8 +3,6 @@ import { create } from 'mutative';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
ACCOUNT_MUTE_SUCCESS,
|
ACCOUNT_MUTE_SUCCESS,
|
||||||
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
|
||||||
FOLLOW_REQUEST_REJECT_SUCCESS,
|
|
||||||
type AccountsAction,
|
type AccountsAction,
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
import {
|
import {
|
||||||
|
@ -87,11 +85,11 @@ const filterNotifications = (state: State, relationship: Relationship) =>
|
||||||
draft.items = draft.items.filter(item => !item.sample_account_ids.includes(relationship.id));
|
draft.items = draft.items.filter(item => !item.sample_account_ids.includes(relationship.id));
|
||||||
});
|
});
|
||||||
|
|
||||||
const filterNotificationIds = (state: State, accountIds: Array<string>, type?: string) =>
|
// const filterNotificationIds = (state: State, accountIds: Array<string>, type?: string) =>
|
||||||
create(state, (draft) => {
|
// create(state, (draft) => {
|
||||||
const helper = (list: Array<NotificationGroup>) => list.filter(item => !(accountIds.includes(item.sample_account_ids[0]) && (type === undefined || type === item.type)));
|
// const helper = (list: Array<NotificationGroup>) => list.filter(item => !(accountIds.includes(item.sample_account_ids[0]) && (type === undefined || type === item.type)));
|
||||||
draft.items = helper(draft.items);
|
// draft.items = helper(draft.items);
|
||||||
});
|
// });
|
||||||
|
|
||||||
const updateTop = (state: State, top: boolean) =>
|
const updateTop = (state: State, top: boolean) =>
|
||||||
create(state, (draft) => {
|
create(state, (draft) => {
|
||||||
|
@ -147,9 +145,9 @@ const notifications = (state: State = initialState, action: AccountsAction | Mar
|
||||||
return filterNotifications(state, action.relationship);
|
return filterNotifications(state, action.relationship);
|
||||||
case ACCOUNT_MUTE_SUCCESS:
|
case ACCOUNT_MUTE_SUCCESS:
|
||||||
return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state;
|
return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state;
|
||||||
case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
// case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
||||||
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
// case FOLLOW_REQUEST_REJECT_SUCCESS:
|
||||||
return filterNotificationIds(state, [action.accountId], 'follow_request');
|
// return filterNotificationIds(state, [action.accountId], 'follow_request');
|
||||||
case MARKER_FETCH_SUCCESS:
|
case MARKER_FETCH_SUCCESS:
|
||||||
case MARKER_SAVE_SUCCESS:
|
case MARKER_SAVE_SUCCESS:
|
||||||
return importMarker(state, action.marker);
|
return importMarker(state, action.marker);
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
import { create } from 'mutative';
|
import { create } from 'mutative';
|
||||||
|
|
||||||
import {
|
import { PINNED_ACCOUNTS_FETCH_SUCCESS, type AccountsAction } from 'pl-fe/actions/accounts';
|
||||||
FOLLOW_REQUESTS_FETCH_SUCCESS,
|
|
||||||
FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
|
||||||
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
|
||||||
FOLLOW_REQUEST_REJECT_SUCCESS,
|
|
||||||
PINNED_ACCOUNTS_FETCH_SUCCESS,
|
|
||||||
type AccountsAction,
|
|
||||||
} from 'pl-fe/actions/accounts';
|
|
||||||
import { FAMILIAR_FOLLOWERS_FETCH_SUCCESS, type FamiliarFollowersAction } from 'pl-fe/actions/familiar-followers';
|
import { FAMILIAR_FOLLOWERS_FETCH_SUCCESS, type FamiliarFollowersAction } from 'pl-fe/actions/familiar-followers';
|
||||||
import {
|
import {
|
||||||
GROUP_BLOCKS_FETCH_REQUEST,
|
GROUP_BLOCKS_FETCH_REQUEST,
|
||||||
|
@ -16,9 +9,8 @@ import {
|
||||||
GROUP_UNBLOCK_SUCCESS,
|
GROUP_UNBLOCK_SUCCESS,
|
||||||
type GroupsAction,
|
type GroupsAction,
|
||||||
} from 'pl-fe/actions/groups';
|
} from 'pl-fe/actions/groups';
|
||||||
import { NOTIFICATIONS_UPDATE, type NotificationsAction } from 'pl-fe/actions/notifications';
|
|
||||||
|
|
||||||
import type { Account, NotificationGroup, PaginatedResponse } from 'pl-api';
|
import type { Account, PaginatedResponse } from 'pl-api';
|
||||||
|
|
||||||
interface List {
|
interface List {
|
||||||
next: (() => Promise<PaginatedResponse<Account>>) | null;
|
next: (() => Promise<PaginatedResponse<Account>>) | null;
|
||||||
|
@ -61,50 +53,8 @@ const normalizeList = (state: State, path: NestedListPath | ListPath, accounts:
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const appendToList = (state: State, path: NestedListPath | ListPath, accounts: Array<Pick<Account, 'id'>>, next: (() => any) | null = null) =>
|
const userLists = (state = initialState, action: AccountsAction | FamiliarFollowersAction | GroupsAction): State => {
|
||||||
create(state, (draft) => {
|
|
||||||
let list: List;
|
|
||||||
|
|
||||||
if (path.length === 1) {
|
|
||||||
list = draft[path[0]];
|
|
||||||
} else {
|
|
||||||
list = draft[path[0]][path[1]];
|
|
||||||
}
|
|
||||||
|
|
||||||
list.next = next;
|
|
||||||
list.isLoading = false;
|
|
||||||
list.items = [...new Set([...list.items, ...accounts.map(item => item.id)])];
|
|
||||||
});
|
|
||||||
|
|
||||||
const removeFromList = (state: State, path: NestedListPath | ListPath, accountId: string) =>
|
|
||||||
create(state, (draft) => {
|
|
||||||
let list: List;
|
|
||||||
|
|
||||||
if (path.length === 1) {
|
|
||||||
list = draft[path[0]];
|
|
||||||
} else {
|
|
||||||
list = draft[path[0]][path[1]];
|
|
||||||
}
|
|
||||||
|
|
||||||
list.items = list.items.filter(item => item !== accountId);
|
|
||||||
});
|
|
||||||
|
|
||||||
const normalizeFollowRequest = (state: State, notification: NotificationGroup) =>
|
|
||||||
create(state, (draft) => {
|
|
||||||
draft.follow_requests.items = [...new Set([...notification.sample_account_ids, ...draft.follow_requests.items])];
|
|
||||||
});
|
|
||||||
|
|
||||||
const userLists = (state = initialState, action: AccountsAction | FamiliarFollowersAction | GroupsAction | NotificationsAction): State => {
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case NOTIFICATIONS_UPDATE:
|
|
||||||
return action.notification.type === 'follow_request' ? normalizeFollowRequest(state, action.notification) : state;
|
|
||||||
case FOLLOW_REQUESTS_FETCH_SUCCESS:
|
|
||||||
return normalizeList(state, ['follow_requests'], action.accounts, action.next);
|
|
||||||
case FOLLOW_REQUESTS_EXPAND_SUCCESS:
|
|
||||||
return appendToList(state, ['follow_requests'], action.accounts, action.next);
|
|
||||||
case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
|
||||||
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
|
||||||
return removeFromList(state, ['follow_requests'], action.accountId);
|
|
||||||
case PINNED_ACCOUNTS_FETCH_SUCCESS:
|
case PINNED_ACCOUNTS_FETCH_SUCCESS:
|
||||||
return normalizeList(state, ['pinned', action.accountId], action.accounts, action.next);
|
return normalizeList(state, ['pinned', action.accountId], action.accounts, action.next);
|
||||||
case FAMILIAR_FOLLOWERS_FETCH_SUCCESS:
|
case FAMILIAR_FOLLOWERS_FETCH_SUCCESS:
|
||||||
|
|
Loading…
Reference in a new issue