Implements reducers for COMMENT_UPDATE, COMMENT_HIDE, and COMMENT_ABANDON

This commit is contained in:
Oleg Silkin 2020-01-13 17:00:04 -05:00
parent c0db949a53
commit 2bdbf3d645
5 changed files with 271 additions and 40 deletions

180
dist/bundle.es.js vendored
View file

@ -137,9 +137,9 @@ const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED';
const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED';
const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED';
const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED';
const COMMENT_EDIT_STARTED = 'COMMENT_EDIT_STARTED'; const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED';
const COMMENT_EDIT_COMPLETED = 'COMMENT_EDIT_COMPLETED'; const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED';
const COMMENT_EDIT_FAILED = 'COMMENT_EDIT_FAILED'; const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED';
const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED';
const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED';
const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED';
@ -389,9 +389,9 @@ var action_types = /*#__PURE__*/Object.freeze({
COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED,
COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED,
COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED,
COMMENT_EDIT_STARTED: COMMENT_EDIT_STARTED, COMMENT_UPDATE_STARTED: COMMENT_UPDATE_STARTED,
COMMENT_EDIT_COMPLETED: COMMENT_EDIT_COMPLETED, COMMENT_UPDATE_COMPLETED: COMMENT_UPDATE_COMPLETED,
COMMENT_EDIT_FAILED: COMMENT_EDIT_FAILED, COMMENT_UPDATE_FAILED: COMMENT_UPDATE_FAILED,
COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED,
COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED,
COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED,
@ -934,10 +934,10 @@ const Lbry = {
// Comments // Comments
comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_list: (params = {}) => daemonCallWithResult('comment_list', params),
comment_create: (params = {}) => daemonCallWithResult('comment_create', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params),
// todo: implement these in reducers
comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params),
comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params),
comment_edit: (params = {}) => daemonCallWithResult('comment_hide', params), // requires SDK ver. 0.53.0
comment_update: (params = {}) => daemonCallWithResult('comment_update', params),
// Connect to the sdk // Connect to the sdk
connect: () => { connect: () => {
@ -1246,18 +1246,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') {
deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']);
const { claimId, claimName, contentName } = deprecatedParts; const { claimId, claimName, contentName } = deprecatedParts;
{
if (claimId) {
console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead"));
}
if (claimName) {
console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead"));
}
if (contentName) {
console.error(__("'contentName' should no longer be used. Use 'streamName' instead"));
}
}
if (!claimName && !channelName && !streamName) { if (!claimName && !channelName && !streamName) {
console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url."));
} }
@ -1570,7 +1558,10 @@ function extractUserState(rawObj) {
function doPopulateSharedUserState(sharedSettings) { function doPopulateSharedUserState(sharedSettings) {
return dispatch => { return dispatch => {
const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings);
dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blocked, settings } }); dispatch({
type: USER_STATE_POPULATE,
data: { subscriptions, tags, blocked, settings }
});
}; };
} }
@ -4053,6 +4044,8 @@ const doUpdateSearchOptions = newOptions => (dispatch, getState) => {
} }
}; };
//
function savePosition(claimId, outpoint, position) { function savePosition(claimId, outpoint, position) {
return dispatch => { return dispatch => {
dispatch({ dispatch({
@ -4155,6 +4148,89 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) {
}; };
} }
function doCommentHide(comment_id) {
return dispatch => {
dispatch({
type: COMMENT_HIDE_STARTED
});
return lbryProxy.comment_hide({
comment_ids: [comment_id]
}).then(result => {
dispatch({
type: COMMENT_HIDE_COMPLETED,
data: result
});
}).catch(error => {
dispatch({
type: COMMENT_HIDE_FAILED,
data: error
});
dispatch(doToast({
message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`,
isError: true
}));
});
};
}
function doCommentAbandon(comment_id) {
return dispatch => {
dispatch({
type: COMMENT_ABANDON_STARTED
});
return lbryProxy.comment_abandon({
comment_id: comment_id
}).then(result => {
dispatch({
type: COMMENT_ABANDON_COMPLETED,
data: {
comment_id: comment_id,
abandoned: result
}
});
}).catch(error => {
dispatch({
type: COMMENT_ABANDON_FAILED,
data: error
});
dispatch(doToast({
message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`,
isError: true
}));
});
};
}
function doCommentUpdate(comment_id, comment) {
// if they provided an empty string, they must have wanted to abandon
if (comment === '') {
return doCommentAbandon(comment_id);
} else {
return dispatch => {
dispatch({
type: COMMENT_UPDATE_STARTED
});
return lbryProxy.comment_update({
comment_id: comment_id,
comment: comment
}).then(result => {
dispatch({
type: COMMENT_UPDATE_COMPLETED,
data: {
comment: result
}
});
}).catch(error => {
dispatch({ type: COMMENT_UPDATE_FAILED, data: error });
dispatch(doToast({
message: `SDK Errored during update on Comment w/ ID = ${comment_id}`,
isError: true
}));
});
};
}
}
// //
const doToggleBlockChannel = uri => ({ const doToggleBlockChannel = uri => ({
@ -4616,7 +4692,11 @@ const commentReducer = handleActions({
const commentsByUri = Object.assign({}, state.commentsByUri); const commentsByUri = Object.assign({}, state.commentsByUri);
if (comments) { 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); const commentIds = Array(comments.length);
// map the comment_ids to the new comments // map the comment_ids to the new comments
for (let i = 0; i < comments.length; i++) { for (let i = 0; i < comments.length; i++) {
commentIds[i] = comments[i].comment_id; commentIds[i] = comments[i].comment_id;
@ -4640,27 +4720,64 @@ const commentReducer = handleActions({
[COMMENT_ABANDON_STARTED]: (state, action) => _extends$7({}, state, { [COMMENT_ABANDON_STARTED]: (state, action) => _extends$7({}, state, {
isLoading: true isLoading: true
}), }),
[COMMENT_ABANDON_COMPLETED]: (state, action) => _extends$7({}, state, { // remove the existing comment from the id -> comment list and claim -> commentIds
[COMMENT_ABANDON_COMPLETED]: (state, action) => {
const { comment_id, abandoned } = action.data;
const commentById = Object.assign({}, state.commentById);
const byId = Object.assign({}, state.byId);
if (abandoned && comment_id in abandoned) {
// messy but necessary for the time being
const comment = commentById[comment_id];
const commentIds = byId[comment.claim_id];
byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id);
Object.keys(commentById).forEach(commentId => {
if (commentId === comment_id) {
delete commentById[commentId];
}
});
}
return _extends$7({}, state, {
commentById,
byId,
isLoading: false isLoading: false
}), });
},
// do nothing
[COMMENT_ABANDON_FAILED]: (state, action) => _extends$7({}, state, { [COMMENT_ABANDON_FAILED]: (state, action) => _extends$7({}, state, {
isLoading: false isLoading: false
}), }),
[COMMENT_EDIT_STARTED]: (state, action) => _extends$7({}, state, { // do nothing
[COMMENT_UPDATE_STARTED]: (state, action) => _extends$7({}, state, {
isLoading: true isLoading: true
}), }),
[COMMENT_EDIT_COMPLETED]: (state, action) => _extends$7({}, state, { // replace existing comment with comment returned here under its comment_id
isLoading: false [COMMENT_UPDATE_COMPLETED]: (state, action) => {
}), const { comment } = action.data;
[COMMENT_EDIT_FAILED]: (state, action) => _extends$7({}, state, { const commentById = Object.assign({}, state.commentById);
if (comment) {
commentById[comment.comment_id] = comment;
}
return _extends$7({}, state, {
commentById,
isLoading: false
});
},
// nothing can be done here
[COMMENT_UPDATE_FAILED]: (state, action) => _extends$7({}, state, {
isLoading: false isLoading: false
}), }),
// nothing can really be done here
[COMMENT_HIDE_STARTED]: (state, action) => _extends$7({}, state, { [COMMENT_HIDE_STARTED]: (state, action) => _extends$7({}, state, {
isLoading: true isLoading: true
}), }),
[COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { // todo: add HiddenComments state & create selectors
isLoading: false isLoading: false
}), }),
// nothing can be done here
[COMMENT_HIDE_FAILED]: (state, action) => _extends$7({}, state, { [COMMENT_HIDE_FAILED]: (state, action) => _extends$7({}, state, {
isLoading: false isLoading: false
}) })
@ -5502,6 +5619,8 @@ const walletReducer = handleActions({
}) })
}, defaultState$a); }, defaultState$a);
//
const selectState$6 = state => state.content || {}; const selectState$6 = state => state.content || {};
const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => { const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => {
@ -5666,8 +5785,11 @@ exports.doCheckPendingPublishes = doCheckPendingPublishes;
exports.doClaimSearch = doClaimSearch; exports.doClaimSearch = doClaimSearch;
exports.doClearPublish = doClearPublish; exports.doClearPublish = doClearPublish;
exports.doClearSupport = doClearSupport; exports.doClearSupport = doClearSupport;
exports.doCommentAbandon = doCommentAbandon;
exports.doCommentCreate = doCommentCreate; exports.doCommentCreate = doCommentCreate;
exports.doCommentHide = doCommentHide;
exports.doCommentList = doCommentList; exports.doCommentList = doCommentList;
exports.doCommentUpdate = doCommentUpdate;
exports.doCreateChannel = doCreateChannel; exports.doCreateChannel = doCreateChannel;
exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDeletePurchasedUri = doDeletePurchasedUri;
exports.doDeleteTag = doDeleteTag; exports.doDeleteTag = doDeleteTag;

View file

@ -125,7 +125,7 @@ declare type ChannelUpdateResponse = GenericTxResponse & {
}; };
declare type CommentCreateResponse = Comment; declare type CommentCreateResponse = Comment;
declare type CommentEditResponse = Comment; declare type CommentUpdateResponse = Comment;
declare type CommentListResponse = { declare type CommentListResponse = {
items: Array<Comment>, items: Array<Comment>,
@ -254,6 +254,10 @@ declare type LbryTypes = {
// Commenting // Commenting
comment_list: (params: {}) => Promise<CommentListResponse>, comment_list: (params: {}) => Promise<CommentListResponse>,
comment_create: (params: {}) => Promise<CommentCreateResponse>, comment_create: (params: {}) => Promise<CommentCreateResponse>,
comment_update: (params: {}) => Promise<CommentUpdateResponse>,
comment_hide: (params: {}) => Promise<CommentHideResponse>,
comment_abandon: (params: {}) => Promise<CommentAbandonResponse>,
// Wallet utilities // Wallet utilities
wallet_balance: (params: {}) => Promise<BalanceResponse>, wallet_balance: (params: {}) => Promise<BalanceResponse>,
wallet_decrypt: (prams: {}) => Promise<boolean>, wallet_decrypt: (prams: {}) => Promise<boolean>,

4
flow-typed/Lbry.js vendored
View file

@ -254,6 +254,10 @@ declare type LbryTypes = {
// Commenting // Commenting
comment_list: (params: {}) => Promise<CommentListResponse>, comment_list: (params: {}) => Promise<CommentListResponse>,
comment_create: (params: {}) => Promise<CommentCreateResponse>, comment_create: (params: {}) => Promise<CommentCreateResponse>,
comment_update: (params: {}) => Promise<CommentUpdateResponse>,
comment_hide: (params: {}) => Promise<CommentHideResponse>,
comment_abandon: (params: {}) => Promise<CommentAbandonResponse>,
// Wallet utilities // Wallet utilities
wallet_balance: (params: {}) => Promise<BalanceResponse>, wallet_balance: (params: {}) => Promise<BalanceResponse>,
wallet_decrypt: (prams: {}) => Promise<boolean>, wallet_decrypt: (prams: {}) => Promise<boolean>,

View file

@ -121,7 +121,13 @@ export {
export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags';
export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export {
doCommentList,
doCommentCreate,
doCommentAbandon,
doCommentHide,
doCommentUpdate,
} from 'redux/actions/comments';
export { doToggleBlockChannel } from 'redux/actions/blocked'; export { doToggleBlockChannel } from 'redux/actions/blocked';

View file

@ -43,7 +43,7 @@ export function doCommentCreate(
comment: string = '', comment: string = '',
claim_id: string = '', claim_id: string = '',
channel: ?string, channel: ?string,
parent_id?: string, parent_id?: string
) { ) {
return (dispatch: Dispatch, getState: GetState) => { return (dispatch: Dispatch, getState: GetState) => {
const state = getState(); const state = getState();
@ -60,7 +60,7 @@ export function doCommentCreate(
channel_id: channel_id, channel_id: channel_id,
parent_id: parent_id, parent_id: parent_id,
}) })
.then((result: Comment) => { .then((result: CommentCreateResponse) => {
dispatch({ dispatch({
type: ACTIONS.COMMENT_CREATE_COMPLETED, type: ACTIONS.COMMENT_CREATE_COMPLETED,
data: { data: {
@ -83,3 +83,98 @@ export function doCommentCreate(
}); });
}; };
} }
export function doCommentHide(comment_id: string) {
return (dispatch: Dispatch) => {
dispatch({
type: ACTIONS.COMMENT_HIDE_STARTED,
});
return Lbry.comment_hide({
comment_ids: [comment_id],
})
.then((result: CommentHideResponse) => {
dispatch({
type: ACTIONS.COMMENT_HIDE_COMPLETED,
data: result,
});
})
.catch(error => {
dispatch({
type: ACTIONS.COMMENT_HIDE_FAILED,
data: error,
});
dispatch(
doToast({
message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`,
isError: true,
})
);
});
};
}
export function doCommentAbandon(comment_id: string) {
return (dispatch: Dispatch) => {
dispatch({
type: ACTIONS.COMMENT_ABANDON_STARTED,
});
return Lbry.comment_abandon({
comment_id: comment_id,
})
.then((result: CommentAbandonResponse) => {
dispatch({
type: ACTIONS.COMMENT_ABANDON_COMPLETED,
data: {
comment_id: comment_id,
abandoned: result,
},
});
})
.catch(error => {
dispatch({
type: ACTIONS.COMMENT_ABANDON_FAILED,
data: error,
});
dispatch(
doToast({
message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`,
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 {
return (dispatch: Dispatch) => {
dispatch({
type: ACTIONS.COMMENT_UPDATE_STARTED,
});
return Lbry.comment_update({
comment_id: comment_id,
comment: comment,
})
.then((result: CommentUpdateResponse) => {
dispatch({
type: ACTIONS.COMMENT_UPDATE_COMPLETED,
data: {
comment: result,
},
});
})
.catch(error => {
dispatch({ type: ACTIONS.COMMENT_UPDATE_FAILED, data: error });
dispatch(
doToast({
message: `SDK Errored during update on Comment w/ ID = ${comment_id}`,
isError: true,
})
);
});
};
}
}