2020-06-23 19:38:18 +02:00
|
|
|
// @flow
|
|
|
|
import * as ACTIONS from 'constants/action_types';
|
|
|
|
import { handleActions } from 'util/redux-utils';
|
2021-05-25 08:17:36 +02:00
|
|
|
import { BLOCK_LEVEL } from 'constants/comment';
|
2020-06-23 19:38:18 +02:00
|
|
|
|
|
|
|
const defaultState: CommentsState = {
|
|
|
|
commentById: {}, // commentId -> Comment
|
|
|
|
byId: {}, // ClaimID -> list of comments
|
2020-08-24 19:35:21 +02:00
|
|
|
repliesByParentId: {}, // ParentCommentID -> list of reply comments
|
|
|
|
topLevelCommentsById: {}, // ClaimID -> list of top level comments
|
2021-03-16 19:37:19 +01:00
|
|
|
// TODO:
|
|
|
|
// Remove commentsByUri
|
|
|
|
// It is not needed and doesn't provide anything but confusion
|
2020-06-23 19:38:18 +02:00
|
|
|
commentsByUri: {}, // URI -> claimId
|
2021-04-23 21:59:48 +02:00
|
|
|
superChatsByUri: {},
|
2020-06-23 19:38:18 +02:00
|
|
|
isLoading: false,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
myComments: undefined,
|
2020-09-29 16:10:23 +02:00
|
|
|
isFetchingReacts: false,
|
2020-09-30 17:59:05 +02:00
|
|
|
pendingCommentReactions: [],
|
2020-09-29 20:45:28 +02:00
|
|
|
typesReacting: [],
|
2020-10-28 03:07:40 +01:00
|
|
|
myReactsByCommentId: undefined,
|
|
|
|
othersReactsByCommentId: undefined,
|
2021-03-03 19:50:16 +01:00
|
|
|
moderationBlockList: undefined,
|
2021-05-25 08:17:36 +02:00
|
|
|
adminBlockList: undefined,
|
|
|
|
moderatorBlockList: undefined,
|
|
|
|
moderatorBlockListDelegatorsMap: {},
|
2021-03-03 19:50:16 +01:00
|
|
|
fetchingModerationBlockList: false,
|
2021-05-25 08:17:36 +02:00
|
|
|
moderationDelegatesById: {},
|
|
|
|
fetchingModerationDelegates: false,
|
|
|
|
moderationDelegatorsById: {},
|
|
|
|
fetchingModerationDelegators: false,
|
2021-03-03 19:50:16 +01:00
|
|
|
blockingByUri: {},
|
|
|
|
unBlockingByUri: {},
|
2021-05-25 08:17:36 +02:00
|
|
|
togglingForDelegatorMap: {},
|
2021-06-03 07:57:50 +02:00
|
|
|
commentsDisabledChannelIds: [],
|
2021-04-20 10:40:53 +02:00
|
|
|
settingsByChannelId: {}, // ChannelId -> PerChannelSettings
|
|
|
|
fetchingSettings: false,
|
|
|
|
fetchingBlockedWords: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
export default handleActions(
|
|
|
|
{
|
|
|
|
[ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: true,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_CREATE_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => {
|
2021-03-16 19:37:19 +01:00
|
|
|
const {
|
|
|
|
comment,
|
|
|
|
claimId,
|
|
|
|
uri,
|
|
|
|
livestream,
|
|
|
|
}: { comment: Comment, claimId: string, uri: string, livestream: boolean } = action.data;
|
2020-06-23 19:38:18 +02:00
|
|
|
const commentById = Object.assign({}, state.commentById);
|
|
|
|
const byId = Object.assign({}, state.byId);
|
2020-08-24 19:35:21 +02:00
|
|
|
const topLevelCommentsById = Object.assign({}, state.topLevelCommentsById); // was byId {ClaimId -> [commentIds...]}
|
|
|
|
const repliesByParentId = Object.assign({}, state.repliesByParentId); // {ParentCommentID -> [commentIds...] } list of reply comments
|
2020-09-08 20:08:39 +02:00
|
|
|
const commentsByUri = Object.assign({}, state.commentsByUri);
|
2020-09-02 02:27:13 +02:00
|
|
|
const comments = byId[claimId] || [];
|
2020-06-23 19:38:18 +02:00
|
|
|
const newCommentIds = comments.slice();
|
|
|
|
|
2021-03-16 19:37:19 +01:00
|
|
|
// If it was created during a livestream, let the websocket handler perform the state update
|
|
|
|
if (!livestream) {
|
|
|
|
// add the comment by its ID
|
|
|
|
commentById[comment.comment_id] = comment;
|
2020-06-23 19:38:18 +02:00
|
|
|
|
2021-03-16 19:37:19 +01:00
|
|
|
// push the comment_id to the top of ID list
|
|
|
|
newCommentIds.unshift(comment.comment_id);
|
|
|
|
byId[claimId] = newCommentIds;
|
2020-06-23 19:38:18 +02:00
|
|
|
|
2021-03-16 19:37:19 +01:00
|
|
|
if (comment['parent_id']) {
|
|
|
|
if (!repliesByParentId[comment.parent_id]) {
|
|
|
|
repliesByParentId[comment.parent_id] = [comment.comment_id];
|
|
|
|
} else {
|
|
|
|
repliesByParentId[comment.parent_id].unshift(comment.comment_id);
|
|
|
|
}
|
2020-08-24 19:35:21 +02:00
|
|
|
} else {
|
2021-03-16 19:37:19 +01:00
|
|
|
if (!topLevelCommentsById[claimId]) {
|
|
|
|
commentsByUri[uri] = claimId;
|
|
|
|
topLevelCommentsById[claimId] = [comment.comment_id];
|
|
|
|
} else {
|
|
|
|
topLevelCommentsById[claimId].unshift(comment.comment_id);
|
|
|
|
}
|
2020-08-24 19:35:21 +02:00
|
|
|
}
|
2020-09-09 20:53:31 +02:00
|
|
|
}
|
2021-03-16 19:37:19 +01:00
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
return {
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
topLevelCommentsById,
|
|
|
|
repliesByParentId,
|
2020-06-23 19:38:18 +02:00
|
|
|
commentById,
|
|
|
|
byId,
|
2020-09-09 20:53:31 +02:00
|
|
|
commentsByUri,
|
2020-06-23 19:38:18 +02:00
|
|
|
isLoading: false,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2020-09-29 16:10:23 +02:00
|
|
|
[ACTIONS.COMMENT_REACTION_LIST_STARTED]: (state: CommentsState, action: any): CommentsState => ({
|
|
|
|
...state,
|
|
|
|
isFetchingReacts: true,
|
|
|
|
}),
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_REACTION_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
isFetchingReacts: false,
|
|
|
|
}),
|
|
|
|
|
2020-09-29 20:45:28 +02:00
|
|
|
[ACTIONS.COMMENT_REACT_FAILED]: (state: CommentsState, action: any): CommentsState => {
|
2020-09-30 17:59:05 +02:00
|
|
|
const commentReaction = action.data; // String: reactionHash + type
|
|
|
|
const newReactingTypes = new Set(state.pendingCommentReactions);
|
|
|
|
newReactingTypes.delete(commentReaction);
|
|
|
|
|
2020-09-29 20:45:28 +02:00
|
|
|
return {
|
|
|
|
...state,
|
2020-09-30 17:59:05 +02:00
|
|
|
pendingCommentReactions: Array.from(newReactingTypes),
|
2020-09-29 20:45:28 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_REACT_STARTED]: (state: CommentsState, action: any): CommentsState => {
|
2020-09-30 17:59:05 +02:00
|
|
|
const commentReaction = action.data;
|
|
|
|
const newReactingTypes = new Set(state.pendingCommentReactions);
|
|
|
|
newReactingTypes.add(commentReaction);
|
2020-09-29 20:45:28 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
2020-09-30 17:59:05 +02:00
|
|
|
pendingCommentReactions: Array.from(newReactingTypes),
|
2020-09-29 20:45:28 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_REACT_COMPLETED]: (state: CommentsState, action: any): CommentsState => {
|
2020-09-30 17:59:05 +02:00
|
|
|
const commentReaction = action.data; // String: reactionHash + type
|
|
|
|
const newReactingTypes = new Set(state.pendingCommentReactions);
|
|
|
|
newReactingTypes.delete(commentReaction);
|
2020-09-29 20:45:28 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
2020-09-30 17:59:05 +02:00
|
|
|
pendingCommentReactions: Array.from(newReactingTypes),
|
2020-09-29 20:45:28 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2020-09-29 16:10:23 +02:00
|
|
|
[ACTIONS.COMMENT_REACTION_LIST_COMPLETED]: (state: CommentsState, action: any): CommentsState => {
|
|
|
|
const { myReactions, othersReactions } = action.data;
|
|
|
|
const myReacts = Object.assign({}, state.myReactsByCommentId);
|
|
|
|
const othersReacts = Object.assign({}, state.othersReactsByCommentId);
|
|
|
|
if (myReactions) {
|
2020-09-29 20:45:28 +02:00
|
|
|
Object.entries(myReactions).forEach(([commentId, reactions]) => {
|
|
|
|
myReacts[commentId] = Object.entries(reactions).reduce((acc, [name, count]) => {
|
|
|
|
if (count === 1) {
|
|
|
|
acc.push(name);
|
2020-09-29 16:10:23 +02:00
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, []);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (othersReactions) {
|
2020-09-29 20:45:28 +02:00
|
|
|
Object.entries(othersReactions).forEach(([commentId, reactions]) => {
|
|
|
|
othersReacts[commentId] = reactions;
|
2020-09-29 16:10:23 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
isFetchingReacts: false,
|
|
|
|
myReactsByCommentId: myReacts,
|
|
|
|
othersReactsByCommentId: othersReacts,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2021-03-03 19:50:16 +01:00
|
|
|
[ACTIONS.COMMENT_LIST_STARTED]: (state) => ({ ...state, isLoading: true }),
|
2020-06-23 19:38:18 +02:00
|
|
|
|
|
|
|
[ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => {
|
2021-06-03 07:57:50 +02:00
|
|
|
const { comments, claimId, uri, disabled, authorClaimId } = action.data;
|
|
|
|
const commentsDisabledChannelIds = [...state.commentsDisabledChannelIds];
|
|
|
|
|
|
|
|
if (disabled) {
|
|
|
|
if (!commentsDisabledChannelIds.includes(authorClaimId)) {
|
|
|
|
commentsDisabledChannelIds.push(authorClaimId);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentsDisabledChannelIds,
|
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
const index = commentsDisabledChannelIds.indexOf(authorClaimId);
|
|
|
|
if (index > -1) {
|
|
|
|
commentsDisabledChannelIds.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
2020-06-23 19:38:18 +02:00
|
|
|
|
|
|
|
const commentById = Object.assign({}, state.commentById);
|
|
|
|
const byId = Object.assign({}, state.byId);
|
2020-08-24 19:35:21 +02:00
|
|
|
const topLevelCommentsById = Object.assign({}, state.topLevelCommentsById); // was byId {ClaimId -> [commentIds...]}
|
2020-06-23 19:38:18 +02:00
|
|
|
const commentsByUri = Object.assign({}, state.commentsByUri);
|
|
|
|
|
2020-08-24 19:35:21 +02:00
|
|
|
const tempRepliesByParent = {};
|
|
|
|
const topLevelComments = [];
|
2020-06-23 19:38:18 +02:00
|
|
|
if (comments) {
|
|
|
|
// we use an Array to preserve order of listing
|
|
|
|
// in reality this doesn't matter and we can just
|
|
|
|
// sort comments by their timestamp
|
|
|
|
const commentIds = Array(comments.length);
|
|
|
|
|
|
|
|
// map the comment_ids to the new comments
|
|
|
|
for (let i = 0; i < comments.length; i++) {
|
2020-08-24 19:35:21 +02:00
|
|
|
const comment = comments[i];
|
|
|
|
if (comment['parent_id']) {
|
|
|
|
if (!tempRepliesByParent[comment.parent_id]) {
|
|
|
|
tempRepliesByParent[comment.parent_id] = [comment.comment_id];
|
|
|
|
} else {
|
|
|
|
tempRepliesByParent[comment.parent_id].push(comment.comment_id);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
commentById[comment.comment_id] = comment;
|
|
|
|
topLevelComments.push(comment.comment_id);
|
|
|
|
}
|
2020-06-23 19:38:18 +02:00
|
|
|
commentIds[i] = comments[i].comment_id;
|
|
|
|
commentById[commentIds[i]] = comments[i];
|
|
|
|
}
|
2020-08-24 19:35:21 +02:00
|
|
|
topLevelCommentsById[claimId] = topLevelComments;
|
2020-06-23 19:38:18 +02:00
|
|
|
|
|
|
|
byId[claimId] = commentIds;
|
|
|
|
commentsByUri[uri] = claimId;
|
|
|
|
}
|
2020-08-24 19:35:21 +02:00
|
|
|
|
|
|
|
const repliesByParentId = Object.assign({}, state.repliesByParentId, tempRepliesByParent); // {ParentCommentID -> [commentIds...] } list of reply comments
|
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
return {
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
topLevelCommentsById,
|
|
|
|
repliesByParentId,
|
2020-06-23 19:38:18 +02:00
|
|
|
byId,
|
|
|
|
commentById,
|
|
|
|
commentsByUri,
|
2021-06-03 07:57:50 +02:00
|
|
|
commentsDisabledChannelIds,
|
2020-06-23 19:38:18 +02:00
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2021-04-23 21:59:48 +02:00
|
|
|
[ACTIONS.COMMENT_SUPER_CHAT_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
isLoading: false,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_SUPER_CHAT_LIST_STARTED]: (state) => ({ ...state, isLoading: true }),
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_SUPER_CHAT_LIST_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
const { comments, totalAmount, uri } = action.data;
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
superChatsByUri: {
|
|
|
|
...state.superChatsByUri,
|
|
|
|
[uri]: {
|
|
|
|
comments,
|
|
|
|
totalAmount,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
[ACTIONS.COMMENT_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
isLoading: false,
|
|
|
|
}),
|
2021-03-16 19:37:19 +01:00
|
|
|
|
|
|
|
[ACTIONS.COMMENT_RECEIVED]: (state: CommentsState, action: any) => {
|
|
|
|
const { uri, claimId, comment } = action.data;
|
|
|
|
const commentsByUri = Object.assign({}, state.commentsByUri);
|
|
|
|
const commentsByClaimId = Object.assign({}, state.byId);
|
|
|
|
const allCommentsById = Object.assign({}, state.commentById);
|
|
|
|
const topLevelCommentsById = Object.assign({}, state.topLevelCommentsById);
|
2021-04-23 21:59:48 +02:00
|
|
|
const superChatsByUri = Object.assign({}, state.superChatsByUri);
|
2021-03-16 19:37:19 +01:00
|
|
|
const commentsForId = topLevelCommentsById[claimId];
|
|
|
|
|
|
|
|
allCommentsById[comment.comment_id] = comment;
|
|
|
|
commentsByUri[uri] = claimId;
|
|
|
|
|
|
|
|
if (commentsForId) {
|
|
|
|
const newCommentsForId = commentsForId.slice();
|
|
|
|
const commentExists = newCommentsForId.includes(comment.comment_id);
|
|
|
|
if (!commentExists) {
|
|
|
|
newCommentsForId.unshift(comment.comment_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
topLevelCommentsById[claimId] = newCommentsForId;
|
|
|
|
} else {
|
|
|
|
topLevelCommentsById[claimId] = [comment.comment_id];
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't care to keep existing lower level comments since this is just for livestreams
|
|
|
|
commentsByClaimId[claimId] = topLevelCommentsById[claimId];
|
|
|
|
|
2021-04-23 21:59:48 +02:00
|
|
|
if (comment.support_amount > 0) {
|
|
|
|
const superChatForUri = superChatsByUri[uri];
|
|
|
|
const superChatCommentsForUri = superChatForUri && superChatForUri.comments;
|
|
|
|
|
|
|
|
let sortedSuperChatComments = [];
|
|
|
|
let hasAddedNewComment = false;
|
|
|
|
if (superChatCommentsForUri && superChatCommentsForUri.length > 0) {
|
|
|
|
// Go for the entire length of superChatCommentsForUri since a comment will be added to this list
|
|
|
|
for (var i = 0; i < superChatCommentsForUri.length; i++) {
|
|
|
|
const existingSuperChat = superChatCommentsForUri[i];
|
|
|
|
if (existingSuperChat.support_amount < comment.support_amount && !hasAddedNewComment) {
|
|
|
|
hasAddedNewComment = true;
|
|
|
|
sortedSuperChatComments.push(comment);
|
|
|
|
sortedSuperChatComments.push(existingSuperChat);
|
|
|
|
} else {
|
|
|
|
sortedSuperChatComments.push(existingSuperChat);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the new superchat hasn't been added yet, it must be the smallest superchat in the list
|
|
|
|
if (
|
|
|
|
i === superChatCommentsForUri.length - 1 &&
|
|
|
|
sortedSuperChatComments.length === superChatCommentsForUri.length
|
|
|
|
) {
|
|
|
|
sortedSuperChatComments.push(comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
superChatsByUri[uri].comments = sortedSuperChatComments;
|
2021-04-26 06:15:35 +02:00
|
|
|
superChatsByUri[uri].totalAmount += comment.support_amount;
|
2021-04-23 21:59:48 +02:00
|
|
|
} else {
|
|
|
|
superChatsByUri[uri] = { comments: [comment], totalAmount: comment.support_amount };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 19:37:19 +01:00
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
byId: commentsByClaimId,
|
|
|
|
commentById: allCommentsById,
|
|
|
|
commentsByUri,
|
|
|
|
topLevelCommentsById,
|
2021-04-23 21:59:48 +02:00
|
|
|
superChatsByUri,
|
2021-03-16 19:37:19 +01:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
[ACTIONS.COMMENT_ABANDON_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
isLoading: true,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
const { comment_id } = action.data;
|
|
|
|
const commentById = Object.assign({}, state.commentById);
|
|
|
|
const byId = Object.assign({}, state.byId);
|
|
|
|
|
|
|
|
// to remove the comment and its references
|
|
|
|
const claimId = commentById[comment_id].claim_id;
|
|
|
|
for (let i = 0; i < byId[claimId].length; i++) {
|
|
|
|
if (byId[claimId][i] === comment_id) {
|
|
|
|
byId[claimId].splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete commentById[comment_id];
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentById,
|
|
|
|
byId,
|
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
},
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
[ACTIONS.COMMENT_ABANDON_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_UPDATE_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: true,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_UPDATE_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
const { comment } = action.data;
|
|
|
|
const commentById = Object.assign({}, state.commentById);
|
|
|
|
commentById[comment.comment_id] = comment;
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentById,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCommenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
};
|
|
|
|
},
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2020-06-23 19:38:18 +02:00
|
|
|
[ACTIONS.COMMENT_UPDATE_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
2020-08-24 19:35:21 +02:00
|
|
|
isCmmenting: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
2021-03-03 19:50:16 +01:00
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_LIST_STARTED]: (state: CommentsState, action: any) => ({
|
2020-06-23 19:38:18 +02:00
|
|
|
...state,
|
2021-03-03 19:50:16 +01:00
|
|
|
fetchingModerationBlockList: true,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
2021-03-03 19:50:16 +01:00
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_LIST_COMPLETED]: (state: CommentsState, action: any) => {
|
2021-05-25 08:17:36 +02:00
|
|
|
const { personalBlockList, adminBlockList, moderatorBlockList, moderatorBlockListDelegatorsMap } = action.data;
|
2021-03-03 19:50:16 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
2021-05-25 08:17:36 +02:00
|
|
|
moderationBlockList: personalBlockList,
|
|
|
|
adminBlockList: adminBlockList,
|
|
|
|
moderatorBlockList: moderatorBlockList,
|
|
|
|
moderatorBlockListDelegatorsMap: moderatorBlockListDelegatorsMap,
|
2021-03-03 19:50:16 +01:00
|
|
|
fetchingModerationBlockList: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingModerationBlockList: false,
|
2020-06-23 19:38:18 +02:00
|
|
|
}),
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_STARTED]: (state: CommentsState, action: any) => {
|
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
|
|
|
|
|
|
|
switch (blockLevel) {
|
|
|
|
default:
|
|
|
|
case BLOCK_LEVEL.SELF:
|
|
|
|
case BLOCK_LEVEL.ADMIN:
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
blockingByUri: {
|
|
|
|
...state.blockingByUri,
|
|
|
|
[blockedUri]: true,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR:
|
|
|
|
const newMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
const togglingDelegatorsForBlockedUri = newMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
if (!togglingDelegatorsForBlockedUri.includes(creatorUri)) {
|
|
|
|
togglingDelegatorsForBlockedUri.push(creatorUri);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
newMap[blockedUri] = [creatorUri];
|
|
|
|
}
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
togglingForDelegatorMap: newMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
[ACTIONS.COMMENT_MODERATION_UN_BLOCK_STARTED]: (state: CommentsState, action: any) => {
|
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
|
|
|
|
|
|
|
switch (blockLevel) {
|
|
|
|
default:
|
|
|
|
case BLOCK_LEVEL.SELF:
|
|
|
|
case BLOCK_LEVEL.ADMIN:
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
unBlockingByUri: {
|
|
|
|
...state.unBlockingByUri,
|
|
|
|
[blockedUri]: true,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR:
|
|
|
|
const newMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
const togglingDelegatorsForBlockedUri = newMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
if (!togglingDelegatorsForBlockedUri.includes(creatorUri)) {
|
|
|
|
togglingDelegatorsForBlockedUri.push(creatorUri);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
newMap[blockedUri] = [creatorUri];
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
togglingForDelegatorMap: newMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_FAILED]: (state: CommentsState, action: any) => {
|
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
|
|
|
|
|
|
|
switch (blockLevel) {
|
|
|
|
default:
|
|
|
|
case BLOCK_LEVEL.SELF:
|
|
|
|
case BLOCK_LEVEL.ADMIN:
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
blockingByUri: {
|
|
|
|
...state.blockingByUri,
|
|
|
|
[blockedUri]: false,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR:
|
|
|
|
const newMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
const togglingDelegatorsForBlockedUri = newMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
newMap[blockedUri] = togglingDelegatorsForBlockedUri.filter((x) => x !== creatorUri);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
togglingForDelegatorMap: newMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_MODERATION_UN_BLOCK_FAILED]: (state: CommentsState, action: any) => {
|
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
|
|
|
|
|
|
|
switch (blockLevel) {
|
|
|
|
default:
|
|
|
|
case BLOCK_LEVEL.SELF:
|
|
|
|
case BLOCK_LEVEL.ADMIN:
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
unBlockingByUri: {
|
|
|
|
...state.unBlockingByUri,
|
|
|
|
[blockedUri]: false,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR:
|
|
|
|
const newMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
const togglingDelegatorsForBlockedUri = newMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
newMap[blockedUri] = togglingDelegatorsForBlockedUri.filter((x) => x !== creatorUri);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
togglingForDelegatorMap: newMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
2021-03-03 19:50:16 +01:00
|
|
|
|
|
|
|
[ACTIONS.COMMENT_MODERATION_BLOCK_COMPLETE]: (state: CommentsState, action: any) => {
|
2021-05-25 08:17:36 +02:00
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
2021-03-03 19:50:16 +01:00
|
|
|
const commentById = Object.assign({}, state.commentById);
|
|
|
|
const blockingByUri = Object.assign({}, state.blockingByUri);
|
|
|
|
|
|
|
|
for (const commentId in commentById) {
|
|
|
|
const comment = commentById[commentId];
|
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
if (blockedUri === comment.channel_url) {
|
2021-03-03 19:50:16 +01:00
|
|
|
delete commentById[comment.comment_id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
switch (blockLevel) {
|
|
|
|
case BLOCK_LEVEL.SELF: {
|
|
|
|
const blockList = state.moderationBlockList || [];
|
|
|
|
const newBlockList = blockList.slice();
|
|
|
|
newBlockList.push(blockedUri);
|
|
|
|
delete blockingByUri[blockedUri];
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentById,
|
|
|
|
blockingByUri,
|
|
|
|
moderationBlockList: newBlockList,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR: {
|
|
|
|
const blockList = state.moderatorBlockList || [];
|
|
|
|
const newBlockList = blockList.slice();
|
|
|
|
|
|
|
|
// Update main block list
|
|
|
|
if (!newBlockList.includes(blockedUri)) {
|
|
|
|
newBlockList.push(blockedUri);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update list of delegators
|
|
|
|
const moderatorBlockListDelegatorsMap = Object.assign({}, state.moderatorBlockListDelegatorsMap);
|
|
|
|
const delegatorUrisForBlockedUri = moderatorBlockListDelegatorsMap[blockedUri];
|
|
|
|
if (delegatorUrisForBlockedUri) {
|
|
|
|
if (!delegatorUrisForBlockedUri.includes(creatorUri)) {
|
|
|
|
delegatorUrisForBlockedUri.push(creatorUri);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
moderatorBlockListDelegatorsMap[blockedUri] = [creatorUri];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove "toggling" flag
|
|
|
|
const togglingMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
const togglingDelegatorsForBlockedUri = togglingMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
togglingMap[blockedUri] = togglingDelegatorsForBlockedUri.filter((x) => x !== creatorUri);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentById,
|
|
|
|
moderatorBlockList: newBlockList,
|
|
|
|
moderatorBlockListDelegatorsMap,
|
|
|
|
togglingForDelegatorMap: togglingMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.ADMIN:
|
|
|
|
const blockList = state.adminBlockList || [];
|
|
|
|
const newBlockList = blockList.slice();
|
|
|
|
newBlockList.push(blockedUri);
|
|
|
|
delete blockingByUri[blockedUri];
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
commentById,
|
|
|
|
blockingByUri,
|
|
|
|
adminBlockList: newBlockList,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[ACTIONS.COMMENT_MODERATION_UN_BLOCK_COMPLETE]: (state: CommentsState, action: any) => {
|
|
|
|
const { blockedUri, creatorUri, blockLevel } = action.data;
|
|
|
|
const unBlockingByUri = Object.assign(state.unBlockingByUri, {});
|
|
|
|
|
|
|
|
switch (blockLevel) {
|
|
|
|
case BLOCK_LEVEL.SELF: {
|
|
|
|
const blockList = state.moderationBlockList || [];
|
|
|
|
delete unBlockingByUri[blockedUri];
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
unBlockingByUri,
|
|
|
|
moderationBlockList: blockList.slice().filter((uri) => uri !== blockedUri),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.ADMIN: {
|
|
|
|
const blockList = state.adminBlockList || [];
|
|
|
|
delete unBlockingByUri[blockedUri];
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
unBlockingByUri,
|
|
|
|
adminBlockList: blockList.slice().filter((uri) => uri !== blockedUri),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
case BLOCK_LEVEL.MODERATOR: {
|
|
|
|
const blockList = state.moderatorBlockList || [];
|
|
|
|
const newBlockList = blockList.slice();
|
|
|
|
const togglingMap = Object.assign({}, state.togglingForDelegatorMap);
|
|
|
|
|
|
|
|
const moderatorBlockListDelegatorsMap = Object.assign({}, state.moderatorBlockListDelegatorsMap);
|
|
|
|
const delegatorUrisForBlockedUri = moderatorBlockListDelegatorsMap[blockedUri];
|
|
|
|
if (delegatorUrisForBlockedUri) {
|
|
|
|
const index = delegatorUrisForBlockedUri.indexOf(creatorUri);
|
|
|
|
if (index > -1) {
|
|
|
|
// Remove from delegators list
|
|
|
|
delegatorUrisForBlockedUri.splice(index, 1);
|
|
|
|
|
|
|
|
// // Remove blocked entry if it was removed for all delegators
|
|
|
|
// if (delegatorUrisForBlockedUri.length === 0) {
|
|
|
|
// delete moderatorBlockListDelegatorsMap[blockedUri];
|
|
|
|
// newBlockList = newBlockList.filter((uri) => uri !== blockedUri);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Remove from "toggling" flag
|
|
|
|
const togglingDelegatorsForBlockedUri = togglingMap[blockedUri];
|
|
|
|
if (togglingDelegatorsForBlockedUri) {
|
|
|
|
togglingMap[blockedUri] = togglingDelegatorsForBlockedUri.filter((x) => x !== creatorUri);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
moderatorBlockList: newBlockList,
|
|
|
|
togglingForDelegatorMap: togglingMap,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
[ACTIONS.COMMENT_FETCH_MODERATION_DELEGATES_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingModerationDelegates: true,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_MODERATION_DELEGATES_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingModerationDelegates: false,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_MODERATION_DELEGATES_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
const moderationDelegatesById = Object.assign({}, state.moderationDelegatesById);
|
|
|
|
if (action.data.delegates) {
|
|
|
|
moderationDelegatesById[action.data.id] = action.data.delegates.map((delegate) => {
|
|
|
|
return {
|
|
|
|
channelId: delegate.channel_id,
|
|
|
|
channelName: delegate.channel_name,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
moderationDelegatesById[action.data.id] = [];
|
|
|
|
}
|
2021-03-03 19:50:16 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
2021-05-25 08:17:36 +02:00
|
|
|
fetchingModerationDelegates: false,
|
|
|
|
moderationDelegatesById: moderationDelegatesById,
|
2021-03-03 19:50:16 +01:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
[ACTIONS.COMMENT_MODERATION_AM_I_LIST_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingModerationDelegators: true,
|
|
|
|
}),
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_MODERATION_AM_I_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingModerationDelegators: true,
|
|
|
|
}),
|
2021-03-03 19:50:16 +01:00
|
|
|
|
2021-05-25 08:17:36 +02:00
|
|
|
[ACTIONS.COMMENT_MODERATION_AM_I_LIST_COMPLETED]: (state: CommentsState, action: any) => {
|
2021-03-03 19:50:16 +01:00
|
|
|
return {
|
|
|
|
...state,
|
2021-05-25 08:17:36 +02:00
|
|
|
fetchingModerationDelegators: true,
|
|
|
|
moderationDelegatorsById: action.data,
|
2021-03-03 19:50:16 +01:00
|
|
|
};
|
|
|
|
},
|
2021-04-20 10:40:53 +02:00
|
|
|
|
|
|
|
[ACTIONS.COMMENT_FETCH_SETTINGS_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingSettings: true,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_SETTINGS_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingSettings: false,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_SETTINGS_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
settingsByChannelId: action.data,
|
|
|
|
fetchingSettings: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
[ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_STARTED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingBlockedWords: true,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_FAILED]: (state: CommentsState, action: any) => ({
|
|
|
|
...state,
|
|
|
|
fetchingBlockedWords: false,
|
|
|
|
}),
|
|
|
|
[ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_COMPLETED]: (state: CommentsState, action: any) => {
|
|
|
|
const blockedWordsByChannelId = action.data;
|
|
|
|
const settingsByChannelId = Object.assign({}, state.settingsByChannelId);
|
|
|
|
|
|
|
|
// blockedWordsByChannelId: {string: [string]}
|
|
|
|
Object.entries(blockedWordsByChannelId).forEach((x) => {
|
|
|
|
const channelId = x[0];
|
|
|
|
if (!settingsByChannelId[channelId]) {
|
|
|
|
settingsByChannelId[channelId] = {};
|
|
|
|
}
|
|
|
|
settingsByChannelId[channelId].words = x[1];
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
settingsByChannelId,
|
|
|
|
fetchingBlockedWords: false,
|
|
|
|
};
|
|
|
|
},
|
2020-06-23 19:38:18 +02:00
|
|
|
},
|
|
|
|
defaultState
|
|
|
|
);
|