124 lines
3.9 KiB
TypeScript
124 lines
3.9 KiB
TypeScript
import { Map as ImmutableMap } from 'immutable';
|
|
|
|
import { isFulfilled } from '@reduxjs/toolkit';
|
|
import type { Reducer } from 'redux';
|
|
|
|
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
|
import type { Account } from 'mastodon/models/account';
|
|
import { createRelationship } from 'mastodon/models/relationship';
|
|
import type { Relationship } from 'mastodon/models/relationship';
|
|
|
|
import { submitAccountNote } from '../actions/account_notes';
|
|
import {
|
|
followAccountSuccess,
|
|
unfollowAccountSuccess,
|
|
authorizeFollowRequestSuccess,
|
|
rejectFollowRequestSuccess,
|
|
followAccountRequest,
|
|
followAccountFail,
|
|
unfollowAccountRequest,
|
|
unfollowAccountFail,
|
|
blockAccountSuccess,
|
|
unblockAccountSuccess,
|
|
muteAccountSuccess,
|
|
unmuteAccountSuccess,
|
|
pinAccountSuccess,
|
|
unpinAccountSuccess,
|
|
fetchRelationshipsSuccess,
|
|
} from '../actions/accounts_typed';
|
|
import {
|
|
blockDomainSuccess,
|
|
unblockDomainSuccess,
|
|
} from '../actions/domain_blocks_typed';
|
|
import { notificationsUpdate } from '../actions/notifications_typed';
|
|
|
|
const initialState = ImmutableMap<string, Relationship>();
|
|
type State = typeof initialState;
|
|
|
|
const normalizeRelationship = (
|
|
state: State,
|
|
relationship: ApiRelationshipJSON,
|
|
) => state.set(relationship.id, createRelationship(relationship));
|
|
|
|
const normalizeRelationships = (
|
|
state: State,
|
|
relationships: ApiRelationshipJSON[],
|
|
) => {
|
|
relationships.forEach((relationship) => {
|
|
state = normalizeRelationship(state, relationship);
|
|
});
|
|
|
|
return state;
|
|
};
|
|
|
|
const setDomainBlocking = (
|
|
state: State,
|
|
accounts: Account[],
|
|
blocking: boolean,
|
|
) => {
|
|
return state.withMutations((map) => {
|
|
accounts.forEach((id) => {
|
|
map.setIn([id, 'domain_blocking'], blocking);
|
|
});
|
|
});
|
|
};
|
|
|
|
export const relationshipsReducer: Reducer<State> = (
|
|
state = initialState,
|
|
action,
|
|
) => {
|
|
if (authorizeFollowRequestSuccess.match(action))
|
|
return state
|
|
.setIn([action.payload.id, 'followed_by'], true)
|
|
.setIn([action.payload.id, 'requested_by'], false);
|
|
else if (rejectFollowRequestSuccess.match(action))
|
|
return state
|
|
.setIn([action.payload.id, 'followed_by'], false)
|
|
.setIn([action.payload.id, 'requested_by'], false);
|
|
else if (notificationsUpdate.match(action))
|
|
return action.payload.notification.type === 'follow_request'
|
|
? state.setIn(
|
|
[action.payload.notification.account.id, 'requested_by'],
|
|
true,
|
|
)
|
|
: state;
|
|
else if (followAccountRequest.match(action))
|
|
return state.getIn([action.payload.id, 'following'])
|
|
? state
|
|
: state.setIn(
|
|
[
|
|
action.payload.id,
|
|
action.payload.locked ? 'requested' : 'following',
|
|
],
|
|
true,
|
|
);
|
|
else if (followAccountFail.match(action))
|
|
return state.setIn(
|
|
[action.payload.id, action.payload.locked ? 'requested' : 'following'],
|
|
false,
|
|
);
|
|
else if (unfollowAccountRequest.match(action))
|
|
return state.setIn([action.payload.id, 'following'], false);
|
|
else if (unfollowAccountFail.match(action))
|
|
return state.setIn([action.payload.id, 'following'], true);
|
|
else if (
|
|
followAccountSuccess.match(action) ||
|
|
unfollowAccountSuccess.match(action) ||
|
|
blockAccountSuccess.match(action) ||
|
|
unblockAccountSuccess.match(action) ||
|
|
muteAccountSuccess.match(action) ||
|
|
unmuteAccountSuccess.match(action) ||
|
|
pinAccountSuccess.match(action) ||
|
|
unpinAccountSuccess.match(action) ||
|
|
isFulfilled(submitAccountNote)(action)
|
|
)
|
|
return normalizeRelationship(state, action.payload.relationship);
|
|
else if (fetchRelationshipsSuccess.match(action))
|
|
return normalizeRelationships(state, action.payload.relationships);
|
|
else if (blockDomainSuccess.match(action))
|
|
return setDomainBlocking(state, action.payload.accounts, true);
|
|
else if (unblockDomainSuccess.match(action))
|
|
return setDomainBlocking(state, action.payload.accounts, false);
|
|
else return state;
|
|
};
|