2020-06-23 13:38:18 -04:00
|
|
|
// @flow
|
|
|
|
import * as ACTIONS from 'constants/action_types';
|
2020-09-29 10:10:23 -04:00
|
|
|
import * as REACTION_TYPES from 'constants/reactions';
|
2021-03-03 13:50:16 -05:00
|
|
|
import { Lbry, parseURI, buildURI, selectClaimsByUri, selectMyChannelClaims } from 'lbry-redux';
|
odysee
fix replay select styling
make meme a link
Fix audio references
get newest livestream claim in livestreamLink
pin crackermilk
fix livestream banner placement
fix live page
fix rebase
fix rebase
fix error nag
fix darkmode blockquote style
break word on livestream comment text
fix dark mode snack
fix live badge
fix lint
small fixes - word wrap, live badge
wip
Fix invisible snack in Odysee Light Theme
Revert "wip"
This reverts commit d17e477fe0e6633709ea30bdc403448825db4c71.
Revert "small fixes - word wrap, live badge"
This reverts commit 0e431d4038d774079c78f0de32238aac7260e4ca.
fix blank
pinned destiny
fix badges and homepage again
only get livestreams live for less than a day
pinned hammy and olivia
multi pin
pin destiny
updated pinned videos
update tagline
Update view.jsx
pins
updated destiny's video
updated pinned videos
removed destiny, added lie likes music
pinned destiny and mason's woodshop
removed hammy and olivia
unpinned mason's woodshop
removed pins
added hammy and olivia
pinned sam seder
unpinned destiny and hammy and olivia
Fix merge on ChannelThumbnails
- sam seder, + hammy & olivia and passion for food
update tagline (#6086)
removed everyone, added kona and suba
Theme color fixes (odysee) (#6089)
* Cherry-pick master's 'base-theme.scss'
* Non-functional cleanup (remove dups, re-order, etc.)
* Dark: update positive Toast to --color-primary as well.
This follows the intention of the refactoring, which I guess was (1) reduce the number of color names (2) reduce the number of customizations needed.
The only issue I have with this is that the current Odysee primary color is pink, which can be intepreted as an error.
The original (pre-refactoring color was green).
For now, I follow the refactoring path. We can tweak this later.
* Fix text color inside '--color-card-background-highlighted'
Light: use base-theme (it was the same value anyway).
Dark: use bright text.
* Dark: add some contrast between the components
The color for the background, header, card, placeholder, etc. is almost identical -- it looks like there are all in the same component. The almost-invisible border doesn't help. One would have to crank up the monitor's contrast setting to see separation of components.
Brighten up the components a bit, somewhat following the same scale as lbry.tv's dark theme.
Overall, I still think it's too dark. The Card's background color can still be brightened up further for better contrast, but I try not to make too drastic of a change for now.
The original lbry.tv's gray theme is the most pleasant theme I've seen so far, but this is all subjective.
changed pins
removed kona and suba
added destiny
changed pins
removed destiny
pinned sgtducky
changed pins
removed sgtducky
added hammy and olivia
added chrissie mayr
added the bite shot
changed pins
removed the bite shot
added heads of tech
changed pins
removed hammy and olivia
removed chrissie mayr
changed pins
removed heads of tech
added crackermilk
changed pins
removed crackermilk
added some ordinary gamer
added passion for food
changed pins
removed some ordinary gamers
removed passion for food
added emmy hucker
changed pins
added game knights
Update view.jsx
Force rebuild
changed pins
removed emmy hucker
changed pins
removed game knights
added crackermilk
changed pins
removed crackermilk
added some ordinary gamer
changed pins
removed some ordinary gamers
added passion for food
added green renaissance
changed pins
removed passion for food
removed green renaissance
added expand love
changed pins
removed expand love
added dr nora
change tagline (#6122)
there's so much room for activities
comment out music
changed pins
removed dr nora
added kona and suba
changed pins
removed kona and suba
added destiny
changed pins
removed destiny
added crackermilk
changed pins
removed crackermilk
added someordinarygamers
change tagline
Drake, where's the door hole?
changed pins
unpinned someordinarygamers
pinned kona and suba
Add message for mature content
changed pin
changed pins
removed creative model
changed pins
added bcpov
added krish mohan
added cigarvixen
changed pins
removed krish mohan
added adrian logan
bump
fix footer
change tagline
just like the simulations
changed pins
removed:
bcpov
cigarvixen
adrian logan
added:
someordinarygamers
quick fix for reposts
oops
fix channel tabs
changed pin
removed someordinarygamers
added kona and suba
changed pins
removed kona and suba
added dirtyworkz
added crackermilk
2021-06-11 13:47:56 -04:00
|
|
|
// import { BANNED_LIVESTREAM_WORDS } from 'constants/comment';
|
2020-10-20 09:29:49 -04:00
|
|
|
import { doToast, doSeeNotifications } from 'redux/actions/notifications';
|
2020-09-29 14:45:28 -04:00
|
|
|
import {
|
|
|
|
makeSelectCommentIdsForUri,
|
|
|
|
makeSelectMyReactionsForComment,
|
|
|
|
makeSelectOthersReactionsForComment,
|
2020-09-30 11:59:05 -04:00
|
|
|
selectPendingCommentReacts,
|
2021-03-03 13:50:16 -05:00
|
|
|
selectModerationBlockList,
|
2020-09-29 14:45:28 -04:00
|
|
|
} from 'redux/selectors/comments';
|
2020-10-20 09:29:49 -04:00
|
|
|
import { makeSelectNotificationForCommentId } from 'redux/selectors/notifications';
|
2021-02-09 11:05:56 -05:00
|
|
|
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
2021-02-11 00:12:41 -05:00
|
|
|
import { toHex } from 'util/hex';
|
|
|
|
import Comments from 'comments';
|
2020-06-23 13:38:18 -04:00
|
|
|
|
|
|
|
export function doCommentList(uri: string, page: number = 1, pageSize: number = 99999) {
|
2020-11-16 14:09:00 -05:00
|
|
|
return (dispatch: Dispatch, getState: GetState) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
const state = getState();
|
|
|
|
const claim = selectClaimsByUri(state)[uri];
|
|
|
|
const claimId = claim ? claim.claim_id : null;
|
|
|
|
|
2021-02-11 00:12:41 -05:00
|
|
|
if (!claimId) {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_LIST_FAILED,
|
|
|
|
data: 'unable to find claim for uri',
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_LIST_STARTED,
|
|
|
|
});
|
2021-02-11 00:12:41 -05:00
|
|
|
|
|
|
|
return Comments.comment_list({
|
2020-06-23 13:38:18 -04:00
|
|
|
page,
|
2021-02-11 00:12:41 -05:00
|
|
|
claim_id: claimId,
|
2020-06-23 13:38:18 -04:00
|
|
|
page_size: pageSize,
|
|
|
|
})
|
|
|
|
.then((result: CommentListResponse) => {
|
|
|
|
const { items: comments } = result;
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_LIST_COMPLETED,
|
|
|
|
data: {
|
|
|
|
comments,
|
|
|
|
claimId: claimId,
|
|
|
|
uri: uri,
|
|
|
|
},
|
|
|
|
});
|
2020-10-19 23:20:38 -04:00
|
|
|
return result;
|
2020-06-23 13:38:18 -04:00
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_LIST_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-04-23 15:59:48 -04:00
|
|
|
export function doSuperChatList(uri: string) {
|
|
|
|
return (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const claim = selectClaimsByUri(state)[uri];
|
|
|
|
const claimId = claim ? claim.claim_id : null;
|
|
|
|
|
|
|
|
if (!claimId) {
|
|
|
|
console.error('No claimId found for uri: ', uri); //eslint-disable-line
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_SUPER_CHAT_LIST_STARTED,
|
|
|
|
});
|
|
|
|
|
|
|
|
return Comments.super_list({
|
|
|
|
claim_id: claimId,
|
|
|
|
})
|
|
|
|
.then((result: CommentListResponse) => {
|
|
|
|
const { items: comments, total_amount: totalAmount } = result;
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_SUPER_CHAT_LIST_COMPLETED,
|
|
|
|
data: {
|
|
|
|
comments,
|
|
|
|
totalAmount,
|
|
|
|
uri: uri,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_SUPER_CHAT_LIST_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-09-29 10:10:23 -04:00
|
|
|
export function doCommentReactList(uri: string | null, commentId?: string) {
|
2020-11-16 14:09:00 -05:00
|
|
|
return (dispatch: Dispatch, getState: GetState) => {
|
2020-09-29 10:10:23 -04:00
|
|
|
const state = getState();
|
2021-02-09 11:05:56 -05:00
|
|
|
const activeChannelClaim = selectActiveChannelClaim(state);
|
2020-09-29 10:10:23 -04:00
|
|
|
const commentIds = uri ? makeSelectCommentIdsForUri(uri)(state) : [commentId];
|
2020-09-30 11:59:05 -04:00
|
|
|
|
2020-09-29 10:10:23 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACTION_LIST_STARTED,
|
|
|
|
});
|
2021-02-09 11:05:56 -05:00
|
|
|
|
2020-09-30 11:59:05 -04:00
|
|
|
const params: { comment_ids: string, channel_name?: string, channel_id?: string } = {
|
2020-09-29 10:10:23 -04:00
|
|
|
comment_ids: commentIds.join(','),
|
2020-09-30 11:59:05 -04:00
|
|
|
};
|
|
|
|
|
2021-02-09 11:05:56 -05:00
|
|
|
if (activeChannelClaim) {
|
|
|
|
params['channel_name'] = activeChannelClaim.name;
|
|
|
|
params['channel_id'] = activeChannelClaim.claim_id;
|
2020-09-30 11:59:05 -04:00
|
|
|
}
|
2020-10-06 15:35:13 -04:00
|
|
|
|
|
|
|
return Lbry.comment_react_list(params)
|
2020-09-29 10:10:23 -04:00
|
|
|
.then((result: CommentReactListResponse) => {
|
|
|
|
const { my_reactions: myReactions, others_reactions: othersReactions } = result;
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
|
|
|
|
data: {
|
2020-09-30 11:59:05 -04:00
|
|
|
myReactions: myReactions || {},
|
2020-09-29 10:10:23 -04:00
|
|
|
othersReactions,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-09-29 10:10:23 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACTION_LIST_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function doCommentReact(commentId: string, type: string) {
|
2020-11-16 14:09:00 -05:00
|
|
|
return (dispatch: Dispatch, getState: GetState) => {
|
2020-09-29 10:10:23 -04:00
|
|
|
const state = getState();
|
2021-02-09 11:05:56 -05:00
|
|
|
const activeChannelClaim = selectActiveChannelClaim(state);
|
2020-09-30 11:59:05 -04:00
|
|
|
const pendingReacts = selectPendingCommentReacts(state);
|
2020-10-20 09:29:49 -04:00
|
|
|
const notification = makeSelectNotificationForCommentId(commentId)(state);
|
2021-02-09 11:05:56 -05:00
|
|
|
|
|
|
|
if (!activeChannelClaim) {
|
|
|
|
console.error('Unable to react to comment. No activeChannel is set.'); // eslint-disable-line
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-20 09:29:49 -04:00
|
|
|
if (notification && !notification.is_seen) {
|
|
|
|
dispatch(doSeeNotifications([notification.id]));
|
|
|
|
}
|
2021-02-09 11:05:56 -05:00
|
|
|
|
2020-09-30 11:59:05 -04:00
|
|
|
const exclusiveTypes = {
|
|
|
|
[REACTION_TYPES.LIKE]: REACTION_TYPES.DISLIKE,
|
|
|
|
[REACTION_TYPES.DISLIKE]: REACTION_TYPES.LIKE,
|
|
|
|
};
|
2021-02-09 11:05:56 -05:00
|
|
|
|
2020-10-01 20:25:30 -04:00
|
|
|
if (pendingReacts.includes(commentId + exclusiveTypes[type]) || pendingReacts.includes(commentId + type)) {
|
2020-09-30 11:59:05 -04:00
|
|
|
// ignore dislikes during likes, for example
|
|
|
|
return;
|
|
|
|
}
|
2021-02-09 11:05:56 -05:00
|
|
|
|
2020-09-29 14:45:28 -04:00
|
|
|
let myReacts = makeSelectMyReactionsForComment(commentId)(state);
|
|
|
|
const othersReacts = makeSelectOthersReactionsForComment(commentId)(state);
|
2020-09-29 10:10:23 -04:00
|
|
|
const params: CommentReactParams = {
|
|
|
|
comment_ids: commentId,
|
2021-02-09 11:05:56 -05:00
|
|
|
channel_name: activeChannelClaim.name,
|
|
|
|
channel_id: activeChannelClaim.claim_id,
|
2020-09-29 10:10:23 -04:00
|
|
|
react_type: type,
|
|
|
|
};
|
2021-02-09 11:05:56 -05:00
|
|
|
|
2020-09-29 10:10:23 -04:00
|
|
|
if (myReacts.includes(type)) {
|
|
|
|
params['remove'] = true;
|
2020-09-29 14:45:28 -04:00
|
|
|
myReacts.splice(myReacts.indexOf(type), 1);
|
|
|
|
} else {
|
|
|
|
myReacts.push(type);
|
|
|
|
if (Object.keys(exclusiveTypes).includes(type)) {
|
|
|
|
params['clear_types'] = exclusiveTypes[type];
|
|
|
|
if (myReacts.indexOf(exclusiveTypes[type]) !== -1) {
|
|
|
|
myReacts.splice(myReacts.indexOf(exclusiveTypes[type]), 1);
|
|
|
|
}
|
|
|
|
}
|
2020-09-29 10:10:23 -04:00
|
|
|
}
|
2020-09-29 14:45:28 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACT_STARTED,
|
2020-09-30 11:59:05 -04:00
|
|
|
data: commentId + type,
|
2020-09-29 14:45:28 -04:00
|
|
|
});
|
2020-10-01 20:25:30 -04:00
|
|
|
|
2020-09-29 14:45:28 -04:00
|
|
|
// simulate api return shape: ['like'] -> { 'like': 1 }
|
|
|
|
const myReactsObj = myReacts.reduce((acc, el) => {
|
|
|
|
acc[el] = 1;
|
|
|
|
return acc;
|
|
|
|
}, {});
|
2020-09-29 10:10:23 -04:00
|
|
|
|
2020-10-01 20:25:30 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
|
|
|
|
data: {
|
|
|
|
myReactions: { [commentId]: myReactsObj },
|
|
|
|
othersReactions: { [commentId]: othersReacts },
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2020-09-29 10:10:23 -04:00
|
|
|
Lbry.comment_react(params)
|
|
|
|
.then((result: CommentReactListResponse) => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACT_COMPLETED,
|
2020-09-30 11:59:05 -04:00
|
|
|
data: commentId + type,
|
2020-09-29 14:45:28 -04:00
|
|
|
});
|
2020-09-29 10:10:23 -04:00
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-09-29 10:10:23 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACT_FAILED,
|
2020-09-30 11:59:05 -04:00
|
|
|
data: commentId + type,
|
2020-09-29 10:10:23 -04:00
|
|
|
});
|
2020-10-01 20:25:30 -04:00
|
|
|
|
|
|
|
const myRevertedReactsObj = myReacts
|
2021-03-03 13:50:16 -05:00
|
|
|
.filter((el) => el !== type)
|
2020-10-01 20:25:30 -04:00
|
|
|
.reduce((acc, el) => {
|
|
|
|
acc[el] = 1;
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_REACTION_LIST_COMPLETED,
|
|
|
|
data: {
|
|
|
|
myReactions: { [commentId]: myRevertedReactsObj },
|
|
|
|
othersReactions: { [commentId]: othersReacts },
|
|
|
|
},
|
|
|
|
});
|
2020-09-29 10:10:23 -04:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-03-16 14:37:19 -04:00
|
|
|
export function doCommentCreate(
|
|
|
|
comment: string = '',
|
|
|
|
claim_id: string = '',
|
|
|
|
parent_id?: string,
|
|
|
|
uri: string,
|
2021-04-23 15:59:48 -04:00
|
|
|
livestream?: boolean = false,
|
|
|
|
txid?: string
|
2021-03-16 14:37:19 -04:00
|
|
|
) {
|
2021-04-23 15:59:48 -04:00
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
const state = getState();
|
2021-02-09 11:05:56 -05:00
|
|
|
const activeChannelClaim = selectActiveChannelClaim(state);
|
|
|
|
|
|
|
|
if (!activeChannelClaim) {
|
|
|
|
console.error('Unable to create comment. No activeChannel is set.'); // eslint-disable-line
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_CREATE_STARTED,
|
|
|
|
});
|
|
|
|
|
2021-04-23 15:59:48 -04:00
|
|
|
let signatureData;
|
|
|
|
if (activeChannelClaim) {
|
|
|
|
try {
|
|
|
|
signatureData = await Lbry.channel_sign({
|
|
|
|
channel_id: activeChannelClaim.claim_id,
|
|
|
|
hexdata: toHex(comment),
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
2020-10-20 09:29:49 -04:00
|
|
|
if (parent_id) {
|
|
|
|
const notification = makeSelectNotificationForCommentId(parent_id)(state);
|
|
|
|
if (notification && !notification.is_seen) {
|
|
|
|
dispatch(doSeeNotifications([notification.id]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-23 15:59:48 -04:00
|
|
|
if (!signatureData) {
|
|
|
|
return dispatch(doToast({ isError: true, message: __('Unable to verify your channel. Please try again.') }));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Comments.comment_create({
|
2020-06-23 13:38:18 -04:00
|
|
|
comment: comment,
|
|
|
|
claim_id: claim_id,
|
2021-02-09 11:05:56 -05:00
|
|
|
channel_id: activeChannelClaim.claim_id,
|
2021-04-23 15:59:48 -04:00
|
|
|
channel_name: activeChannelClaim.name,
|
2020-06-23 13:38:18 -04:00
|
|
|
parent_id: parent_id,
|
2021-04-23 15:59:48 -04:00
|
|
|
signature: signatureData.signature,
|
|
|
|
signing_ts: signatureData.signing_ts,
|
|
|
|
...(txid ? { support_tx_id: txid } : {}),
|
2020-06-23 13:38:18 -04:00
|
|
|
})
|
|
|
|
.then((result: CommentCreateResponse) => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_CREATE_COMPLETED,
|
|
|
|
data: {
|
2020-09-09 14:53:31 -04:00
|
|
|
uri,
|
2021-03-16 14:37:19 -04:00
|
|
|
livestream,
|
2020-06-23 13:38:18 -04:00
|
|
|
comment: result,
|
|
|
|
claimId: claim_id,
|
|
|
|
},
|
|
|
|
});
|
2020-09-29 20:11:48 -04:00
|
|
|
return result;
|
2020-06-23 13:38:18 -04:00
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_CREATE_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
2021-03-03 13:50:16 -05:00
|
|
|
|
|
|
|
let toastMessage = __('Unable to create comment, please try again later.');
|
|
|
|
if (error && error.message === 'channel is blocked by publisher') {
|
|
|
|
toastMessage = __('Unable to comment. This channel has blocked you.');
|
|
|
|
}
|
|
|
|
|
2021-04-22 21:36:40 +08:00
|
|
|
if (error) {
|
|
|
|
const BLOCKED_WORDS_ERR_MSG = 'the comment contents are blocked by';
|
|
|
|
|
|
|
|
if (error.message === 'channel is blocked by publisher') {
|
|
|
|
toastMessage = __('Unable to comment. This channel has blocked you.');
|
|
|
|
} else if (error.message.startsWith(BLOCKED_WORDS_ERR_MSG)) {
|
|
|
|
const channelName = error.message.substring(BLOCKED_WORDS_ERR_MSG.length);
|
|
|
|
toastMessage = __('The comment contains contents that are blocked by %author%', { author: channelName });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch(
|
|
|
|
doToast({
|
2021-03-03 13:50:16 -05:00
|
|
|
message: toastMessage,
|
2020-06-23 13:38:18 -04:00
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
2021-04-23 15:59:48 -04:00
|
|
|
|
|
|
|
return Promise.reject(error);
|
2020-06-23 13:38:18 -04:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-10-19 23:20:38 -04:00
|
|
|
export function doCommentPin(commentId: string, remove: boolean) {
|
2020-11-16 14:09:00 -05:00
|
|
|
return (dispatch: Dispatch, getState: GetState) => {
|
2020-10-19 23:20:38 -04:00
|
|
|
const state = getState();
|
2021-02-09 11:05:56 -05:00
|
|
|
const activeChannel = selectActiveChannelClaim(state);
|
|
|
|
|
|
|
|
if (!activeChannel) {
|
|
|
|
console.error('Unable to pin comment. No activeChannel is set.'); // eslint-disable-line
|
|
|
|
return;
|
|
|
|
}
|
2020-10-19 23:20:38 -04:00
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_PIN_STARTED,
|
|
|
|
});
|
|
|
|
|
2021-02-09 11:05:56 -05:00
|
|
|
return Lbry.comment_pin({
|
|
|
|
comment_id: commentId,
|
|
|
|
channel_name: activeChannel.name,
|
|
|
|
channel_id: activeChannel.claim_id,
|
|
|
|
...(remove ? { remove: true } : {}),
|
|
|
|
})
|
2020-10-19 23:20:38 -04:00
|
|
|
.then((result: CommentPinResponse) => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_PIN_COMPLETED,
|
|
|
|
data: result,
|
|
|
|
});
|
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-10-19 23:20:38 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_PIN_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: 'Unable to pin this comment, please try again later.',
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-02-11 00:12:41 -05:00
|
|
|
export function doCommentAbandon(commentId: string, creatorChannelUri?: string) {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const claim = creatorChannelUri ? selectClaimsByUri(state)[creatorChannelUri] : undefined;
|
|
|
|
const creatorChannelId = claim ? claim.claim_id : null;
|
|
|
|
const creatorChannelName = claim ? claim.name : null;
|
|
|
|
const activeChannelClaim = selectActiveChannelClaim(state);
|
|
|
|
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_ABANDON_STARTED,
|
|
|
|
});
|
2021-02-11 00:12:41 -05:00
|
|
|
|
|
|
|
let commentIdSignature;
|
|
|
|
if (activeChannelClaim) {
|
|
|
|
try {
|
|
|
|
commentIdSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: activeChannelClaim.claim_id,
|
|
|
|
hexdata: toHex(commentId),
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Comments.comment_abandon({
|
|
|
|
comment_id: commentId,
|
|
|
|
...(creatorChannelId ? { creator_channel_id: creatorChannelId } : {}),
|
|
|
|
...(creatorChannelName ? { creator_channel_name: creatorChannelName } : {}),
|
|
|
|
...(commentIdSignature || {}),
|
2020-06-23 13:38:18 -04:00
|
|
|
})
|
|
|
|
.then((result: CommentAbandonResponse) => {
|
|
|
|
// Comment may not be deleted if the signing channel can't be signed.
|
|
|
|
// This will happen if the channel was recently created or abandoned.
|
|
|
|
if (result.abandoned) {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_ABANDON_COMPLETED,
|
|
|
|
data: {
|
2021-02-11 00:12:41 -05:00
|
|
|
comment_id: commentId,
|
2020-06-23 13:38:18 -04:00
|
|
|
},
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_ABANDON_FAILED,
|
|
|
|
});
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: 'Your channel is still being setup, try again in a few moments.',
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_ABANDON_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
2021-02-11 00:12:41 -05:00
|
|
|
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: 'Unable to delete this comment, please try again later.',
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function doCommentUpdate(comment_id: string, comment: string) {
|
|
|
|
// if they provided an empty string, they must have wanted to abandon
|
|
|
|
if (comment === '') {
|
|
|
|
return doCommentAbandon(comment_id);
|
|
|
|
} else {
|
2020-11-16 14:09:00 -05:00
|
|
|
return (dispatch: Dispatch) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_UPDATE_STARTED,
|
|
|
|
});
|
|
|
|
return Lbry.comment_update({
|
|
|
|
comment_id: comment_id,
|
|
|
|
comment: comment,
|
|
|
|
})
|
|
|
|
.then((result: CommentUpdateResponse) => {
|
|
|
|
if (result != null) {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_UPDATE_COMPLETED,
|
|
|
|
data: {
|
|
|
|
comment: result,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// the result will return null
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_UPDATE_FAILED,
|
|
|
|
});
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: 'Your channel is still being setup, try again in a few moments.',
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})
|
2021-03-03 13:50:16 -05:00
|
|
|
.catch((error) => {
|
2020-06-23 13:38:18 -04:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_UPDATE_FAILED,
|
|
|
|
data: error,
|
|
|
|
});
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: 'Unable to edit this comment, please try again later.',
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2021-02-11 00:12:41 -05:00
|
|
|
|
2021-05-28 09:06:07 +08:00
|
|
|
async function channelSignName(channelClaimId: string, channelName: string) {
|
|
|
|
let signedObject;
|
|
|
|
|
|
|
|
try {
|
|
|
|
signedObject = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaimId,
|
|
|
|
hexdata: toHex(channelName),
|
|
|
|
});
|
|
|
|
|
|
|
|
signedObject['claim_id'] = channelClaimId;
|
|
|
|
signedObject['name'] = channelName;
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
return signedObject;
|
|
|
|
}
|
|
|
|
|
2021-02-11 00:12:41 -05:00
|
|
|
// Hides a users comments from all creator's claims and prevent them from commenting in the future
|
2021-06-11 17:49:18 -03:00
|
|
|
export function doCommentModToggleBlock(channelUri: string, showLink: boolean, unblock: boolean = false) {
|
2021-02-11 00:12:41 -05:00
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
2021-03-03 13:50:16 -05:00
|
|
|
const myChannels = selectMyChannelClaims(state);
|
|
|
|
const claim = selectClaimsByUri(state)[channelUri];
|
2021-02-11 00:12:41 -05:00
|
|
|
|
|
|
|
if (!claim) {
|
|
|
|
console.error("Can't find claim to block"); // eslint-disable-line
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-03 13:50:16 -05:00
|
|
|
dispatch({
|
|
|
|
type: unblock ? ACTIONS.COMMENT_MODERATION_UN_BLOCK_STARTED : ACTIONS.COMMENT_MODERATION_BLOCK_STARTED,
|
|
|
|
data: {
|
|
|
|
uri: channelUri,
|
|
|
|
},
|
|
|
|
});
|
2021-02-11 00:12:41 -05:00
|
|
|
|
2021-03-03 13:50:16 -05:00
|
|
|
const creatorIdForAction = claim ? claim.claim_id : null;
|
|
|
|
const creatorNameForAction = claim ? claim.name : null;
|
|
|
|
|
|
|
|
let channelSignatures = [];
|
2021-02-11 00:12:41 -05:00
|
|
|
|
2021-03-03 13:50:16 -05:00
|
|
|
const sharedModBlockParams = unblock
|
|
|
|
? {
|
2021-06-11 17:49:18 -03:00
|
|
|
un_blocked_channel_id: creatorIdForAction,
|
|
|
|
un_blocked_channel_name: creatorNameForAction,
|
|
|
|
}
|
2021-03-03 13:50:16 -05:00
|
|
|
: {
|
2021-06-11 17:49:18 -03:00
|
|
|
blocked_channel_id: creatorIdForAction,
|
|
|
|
blocked_channel_name: creatorNameForAction,
|
|
|
|
};
|
2021-03-03 13:50:16 -05:00
|
|
|
|
|
|
|
const commentAction = unblock ? Comments.moderation_unblock : Comments.moderation_block;
|
|
|
|
|
2021-05-28 09:06:07 +08:00
|
|
|
return Promise.all(myChannels.map((channel) => channelSignName(channel.claim_id, channel.name)))
|
|
|
|
.then((response) => {
|
|
|
|
channelSignatures = response;
|
|
|
|
// $FlowFixMe
|
|
|
|
return Promise.allSettled(
|
|
|
|
channelSignatures
|
|
|
|
.filter((x) => x !== undefined && x !== null)
|
|
|
|
.map((signatureData) =>
|
|
|
|
commentAction({
|
|
|
|
mod_channel_id: signatureData.claim_id,
|
|
|
|
mod_channel_name: signatureData.name,
|
|
|
|
signature: signatureData.signature,
|
|
|
|
signing_ts: signatureData.signing_ts,
|
|
|
|
...sharedModBlockParams,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.then(() => {
|
|
|
|
dispatch({
|
|
|
|
type: unblock ? ACTIONS.COMMENT_MODERATION_UN_BLOCK_COMPLETE : ACTIONS.COMMENT_MODERATION_BLOCK_COMPLETE,
|
|
|
|
data: { channelUri },
|
|
|
|
});
|
|
|
|
|
2021-06-11 17:49:18 -03:00
|
|
|
dispatch(doToast({
|
|
|
|
message: __(!unblock ? 'Channel blocked. They will not interact with you again.' : 'Channel unblocked!'),
|
|
|
|
linkText: __(showLink ? 'See All' : ''),
|
|
|
|
linkTarget: '/settings/block_and_mute',
|
|
|
|
}));
|
2021-05-28 09:06:07 +08:00
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch({
|
|
|
|
type: unblock ? ACTIONS.COMMENT_MODERATION_UN_BLOCK_FAILED : ACTIONS.COMMENT_MODERATION_BLOCK_FAILED,
|
|
|
|
});
|
|
|
|
});
|
2021-03-03 13:50:16 -05:00
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch({
|
|
|
|
type: unblock ? ACTIONS.COMMENT_MODERATION_UN_BLOCK_FAILED : ACTIONS.COMMENT_MODERATION_BLOCK_FAILED,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-06-11 17:49:18 -03:00
|
|
|
export function doCommentModBlock(commentAuthor: string, showLink: boolean = true) {
|
2021-03-03 13:50:16 -05:00
|
|
|
return (dispatch: Dispatch) => {
|
2021-06-11 17:49:18 -03:00
|
|
|
return dispatch(doCommentModToggleBlock(commentAuthor, showLink));
|
2021-03-03 13:50:16 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-06-11 17:49:18 -03:00
|
|
|
export function doCommentModUnBlock(commentAuthor: string, showLink: boolean = true) {
|
2021-03-03 13:50:16 -05:00
|
|
|
return (dispatch: Dispatch) => {
|
2021-06-11 17:49:18 -03:00
|
|
|
return dispatch(doCommentModToggleBlock(commentAuthor, showLink, true));
|
2021-03-03 13:50:16 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function doFetchModBlockedList() {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const myChannels = selectMyChannelClaims(state);
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_MODERATION_BLOCK_LIST_STARTED,
|
2021-02-11 00:12:41 -05:00
|
|
|
});
|
2021-03-03 13:50:16 -05:00
|
|
|
|
|
|
|
let channelSignatures = [];
|
|
|
|
|
2021-05-28 09:06:07 +08:00
|
|
|
return Promise.all(myChannels.map((channel) => channelSignName(channel.claim_id, channel.name)))
|
|
|
|
.then((response) => {
|
|
|
|
channelSignatures = response;
|
|
|
|
// $FlowFixMe
|
|
|
|
return Promise.allSettled(
|
|
|
|
channelSignatures
|
|
|
|
.filter((x) => x !== undefined && x !== null)
|
|
|
|
.map((signatureData) =>
|
|
|
|
Comments.moderation_block_list({
|
|
|
|
mod_channel_id: signatureData.claim_id,
|
|
|
|
mod_channel_name: signatureData.name,
|
|
|
|
signature: signatureData.signature,
|
|
|
|
signing_ts: signatureData.signing_ts,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.then((res) => {
|
|
|
|
const blockLists = res.map((r) => r.value);
|
|
|
|
let globalBlockList = [];
|
|
|
|
blockLists
|
|
|
|
.sort((a, b) => {
|
|
|
|
return 1;
|
|
|
|
})
|
|
|
|
.forEach((channelBlockListData) => {
|
|
|
|
const blockListForChannel = channelBlockListData && channelBlockListData.blocked_channels;
|
|
|
|
if (blockListForChannel) {
|
|
|
|
blockListForChannel.forEach((blockedChannel) => {
|
|
|
|
if (blockedChannel.blocked_channel_name) {
|
|
|
|
const channelUri = buildURI({
|
|
|
|
channelName: blockedChannel.blocked_channel_name,
|
|
|
|
claimId: blockedChannel.blocked_channel_id,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!globalBlockList.find((blockedChannel) => blockedChannel.channelUri === channelUri)) {
|
|
|
|
globalBlockList.push({ channelUri, blockedAt: blockedChannel.blocked_at });
|
|
|
|
}
|
|
|
|
}
|
2021-03-03 13:50:16 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-05-28 09:06:07 +08:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_MODERATION_BLOCK_LIST_COMPLETED,
|
|
|
|
data: {
|
|
|
|
blockList:
|
|
|
|
globalBlockList.length > 0
|
|
|
|
? globalBlockList
|
|
|
|
.sort((a, b) => new Date(a.blockedAt) - new Date(b.blockedAt))
|
|
|
|
.map((blockedChannel) => blockedChannel.channelUri)
|
|
|
|
: null,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_MODERATION_BLOCK_LIST_FAILED,
|
|
|
|
});
|
|
|
|
});
|
2021-03-03 13:50:16 -05:00
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_MODERATION_BLOCK_LIST_FAILED,
|
|
|
|
});
|
|
|
|
});
|
2021-02-11 00:12:41 -05:00
|
|
|
};
|
|
|
|
}
|
2021-03-03 13:50:16 -05:00
|
|
|
|
|
|
|
export const doUpdateBlockListForPublishedChannel = (channelClaim: ChannelClaim) => {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const blockedUris = selectModerationBlockList(state);
|
|
|
|
|
|
|
|
let channelSignature: ?{
|
|
|
|
signature: string,
|
|
|
|
signing_ts: string,
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
channelSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
hexdata: toHex(channelClaim.name),
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
if (!channelSignature) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.all(
|
|
|
|
blockedUris.map((uri) => {
|
|
|
|
const { channelName, channelClaimId } = parseURI(uri);
|
|
|
|
|
|
|
|
return Comments.moderation_block({
|
|
|
|
mod_channel_id: channelClaim.claim_id,
|
|
|
|
mod_channel_name: channelClaim.name,
|
|
|
|
// $FlowFixMe
|
|
|
|
signature: channelSignature.signature,
|
|
|
|
// $FlowFixMe
|
|
|
|
signing_ts: channelSignature.signing_ts,
|
|
|
|
blocked_channel_id: channelClaimId,
|
|
|
|
blocked_channel_name: channelName,
|
|
|
|
});
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
2021-04-20 16:40:53 +08:00
|
|
|
|
|
|
|
export const doFetchCreatorSettings = (channelClaimIds: Array<string> = []) => {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const myChannels = selectMyChannelClaims(state);
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_SETTINGS_STARTED,
|
|
|
|
});
|
|
|
|
|
|
|
|
let channelSignatures = [];
|
|
|
|
if (myChannels) {
|
|
|
|
for (const channelClaim of myChannels) {
|
|
|
|
if (channelClaimIds.length !== 0 && !channelClaimIds.includes(channelClaim.claim_id)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const channelSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
hexdata: toHex(channelClaim.name),
|
|
|
|
});
|
|
|
|
|
|
|
|
channelSignatures.push({ ...channelSignature, claim_id: channelClaim.claim_id, name: channelClaim.name });
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.all(
|
|
|
|
channelSignatures.map((signatureData) =>
|
|
|
|
Comments.setting_list({
|
|
|
|
channel_name: signatureData.name,
|
|
|
|
channel_id: signatureData.claim_id,
|
|
|
|
signature: signatureData.signature,
|
|
|
|
signing_ts: signatureData.signing_ts,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.then((settings) => {
|
|
|
|
const settingsByChannelId = {};
|
|
|
|
|
|
|
|
for (let i = 0; i < channelSignatures.length; ++i) {
|
|
|
|
const channelId = channelSignatures[i].claim_id;
|
|
|
|
settingsByChannelId[channelId] = settings[i];
|
|
|
|
|
|
|
|
settingsByChannelId[channelId].words = settingsByChannelId[channelId].words.split(',');
|
|
|
|
|
|
|
|
delete settingsByChannelId[channelId].channel_name;
|
|
|
|
delete settingsByChannelId[channelId].channel_id;
|
|
|
|
delete settingsByChannelId[channelId].signature;
|
|
|
|
delete settingsByChannelId[channelId].signing_ts;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_SETTINGS_COMPLETED,
|
|
|
|
data: settingsByChannelId,
|
|
|
|
});
|
|
|
|
})
|
2021-05-25 10:58:42 +08:00
|
|
|
.catch((err) => {
|
|
|
|
// TODO: Use error codes when available.
|
|
|
|
// TODO: The "validation is disallowed" thing ideally should just be a
|
|
|
|
// success case that returns a null setting, instead of an error.
|
|
|
|
// As we are using 'Promise.all', if one channel fails, everyone
|
|
|
|
// fails. This forces us to remove the batch functionality of this
|
|
|
|
// function. However, since this "validation is disallowed" thing
|
|
|
|
// is potentially a temporary one to handle spammers, I retained
|
|
|
|
// the batch functionality for now.
|
|
|
|
if (err.message === 'validation is disallowed for non controlling channels') {
|
|
|
|
const settingsByChannelId = {};
|
|
|
|
for (let i = 0; i < channelSignatures.length; ++i) {
|
|
|
|
const channelId = channelSignatures[i].claim_id;
|
|
|
|
// 'undefined' means "fetching or have not fetched";
|
|
|
|
// 'null' means "feature not available for this channel";
|
|
|
|
settingsByChannelId[channelId] = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_SETTINGS_COMPLETED,
|
|
|
|
data: settingsByChannelId,
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-04-20 16:40:53 +08:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_SETTINGS_FAILED,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates creator settings, except for 'Words', which will be handled by
|
|
|
|
* 'doCommentWords, doCommentBlockWords, etc.'
|
|
|
|
*
|
|
|
|
* @param channelClaim
|
|
|
|
* @param settings
|
|
|
|
* @returns {function(Dispatch, GetState): Promise<R>|Promise<unknown>|*}
|
|
|
|
*/
|
|
|
|
export const doUpdateCreatorSettings = (channelClaim: ChannelClaim, settings: PerChannelSettings) => {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
let channelSignature: ?{
|
|
|
|
signature: string,
|
|
|
|
signing_ts: string,
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
channelSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
hexdata: toHex(channelClaim.name),
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
if (!channelSignature) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Comments.setting_update({
|
|
|
|
channel_name: channelClaim.name,
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
signature: channelSignature.signature,
|
|
|
|
signing_ts: channelSignature.signing_ts,
|
|
|
|
...settings,
|
|
|
|
}).catch((err) => {
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: err.message,
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const doCommentWords = (channelClaim: ChannelClaim, words: Array<string>, isUnblock: boolean) => {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
let channelSignature: ?{
|
|
|
|
signature: string,
|
|
|
|
signing_ts: string,
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
channelSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
hexdata: toHex(channelClaim.name),
|
|
|
|
});
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
if (!channelSignature) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const cmd = isUnblock ? Comments.setting_unblock_word : Comments.setting_block_word;
|
|
|
|
|
|
|
|
return cmd({
|
|
|
|
channel_name: channelClaim.name,
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
words: words.join(','),
|
|
|
|
signature: channelSignature.signature,
|
|
|
|
signing_ts: channelSignature.signing_ts,
|
|
|
|
}).catch((err) => {
|
|
|
|
dispatch(
|
|
|
|
doToast({
|
|
|
|
message: err.message,
|
|
|
|
isError: true,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const doCommentBlockWords = (channelClaim: ChannelClaim, words: Array<string>) => {
|
|
|
|
return (dispatch: Dispatch) => {
|
|
|
|
return dispatch(doCommentWords(channelClaim, words, false));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const doCommentUnblockWords = (channelClaim: ChannelClaim, words: Array<string>) => {
|
|
|
|
return (dispatch: Dispatch) => {
|
|
|
|
return dispatch(doCommentWords(channelClaim, words, true));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const doFetchBlockedWords = () => {
|
|
|
|
return async (dispatch: Dispatch, getState: GetState) => {
|
|
|
|
const state = getState();
|
|
|
|
const myChannels = selectMyChannelClaims(state);
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_STARTED,
|
|
|
|
});
|
|
|
|
|
|
|
|
let channelSignatures = [];
|
|
|
|
if (myChannels) {
|
|
|
|
for (const channelClaim of myChannels) {
|
|
|
|
try {
|
|
|
|
const channelSignature = await Lbry.channel_sign({
|
|
|
|
channel_id: channelClaim.claim_id,
|
|
|
|
hexdata: toHex(channelClaim.name),
|
|
|
|
});
|
|
|
|
|
|
|
|
channelSignatures.push({ ...channelSignature, claim_id: channelClaim.claim_id, name: channelClaim.name });
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.all(
|
|
|
|
channelSignatures.map((signatureData) =>
|
|
|
|
Comments.setting_list_blocked_words({
|
|
|
|
channel_name: signatureData.name,
|
|
|
|
channel_id: signatureData.claim_id,
|
|
|
|
signature: signatureData.signature,
|
|
|
|
signing_ts: signatureData.signing_ts,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.then((blockedWords) => {
|
|
|
|
const blockedWordsByChannelId = {};
|
|
|
|
|
|
|
|
for (let i = 0; i < channelSignatures.length; ++i) {
|
|
|
|
const claim_id = channelSignatures[i].claim_id;
|
|
|
|
blockedWordsByChannelId[claim_id] = blockedWords[i].word_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_COMPLETED,
|
|
|
|
data: blockedWordsByChannelId,
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.COMMENT_FETCH_BLOCKED_WORDS_FAILED,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|