From bd07919a72daa841a4b377beb18a3fda73a6113f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 10 Feb 2020 10:49:45 -0500 Subject: [PATCH] redux for reposts --- dist/bundle.es.js | 104 ++++++++++++++++++++++++++++++++-- dist/flow-typed/Lbry.js | 10 ++++ flow-typed/Lbry.js | 10 ++++ src/constants/action_types.js | 4 ++ src/index.js | 4 ++ src/lbry.js | 2 +- src/redux/actions/claims.js | 61 +++++++++++++++++--- src/redux/reducers/claims.js | 45 +++++++++++++++ src/redux/selectors/claims.js | 14 ++++- 9 files changed, 238 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c83f84b..93e2949 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -126,6 +126,10 @@ const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; +const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; +const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; +const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; +const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -383,6 +387,10 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_SEARCH_BY_TAGS_STARTED: CLAIM_SEARCH_BY_TAGS_STARTED, CLAIM_SEARCH_BY_TAGS_COMPLETED: CLAIM_SEARCH_BY_TAGS_COMPLETED, CLAIM_SEARCH_BY_TAGS_FAILED: CLAIM_SEARCH_BY_TAGS_FAILED, + CLAIM_REPOST_STARTED: CLAIM_REPOST_STARTED, + CLAIM_REPOST_COMPLETED: CLAIM_REPOST_COMPLETED, + CLAIM_REPOST_FAILED: CLAIM_REPOST_FAILED, + CLEAR_REPOST_ERROR: CLEAR_REPOST_ERROR, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -865,7 +873,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { @@ -907,6 +915,7 @@ const Lbry = { channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), support_list: params => daemonCallWithResult('support_list', params), + stream_repost: params => daemonCallWithResult('stream_repost', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), @@ -942,7 +951,6 @@ const Lbry = { comment_create: (params = {}) => daemonCallWithResult('comment_create', params), comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - // requires SDK ver. 0.53.0 comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk @@ -1953,6 +1961,10 @@ const selectCreatingChannel = reselect.createSelector(selectState$2, state => st const selectCreateChannelError = reselect.createSelector(selectState$2, state => state.createChannelError); +const selectRepostLoading = reselect.createSelector(selectState$2, state => state.repostLoading); + +const selectRepostError = reselect.createSelector(selectState$2, state => state.repostError); + const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; const claims = {}; @@ -2874,7 +2886,7 @@ function doFetchClaimListMine(page = 1, pageSize = 99999) { type: FETCH_CLAIM_LIST_MINE_STARTED }); - lbryProxy.stream_list({ page, page_size: pageSize }).then(result => { + lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then(result => { const claims = result.items; dispatch({ @@ -3190,6 +3202,47 @@ function doClaimSearch(options = { }; } +function doRepost(options) { + return dispatch => { + // $FlowFixMe + return new Promise(resolve => { + dispatch({ + type: CLAIM_REPOST_STARTED + }); + + function success(response) { + const repostClaim = response.outputs[0]; + dispatch({ + type: CLAIM_REPOST_COMPLETED, + data: { + originalClaimId: options.claim_id, + repostClaim + } + }); + + resolve(); + } + + function failure(error) { + dispatch({ + type: CLAIM_REPOST_FAILED, + data: { + error: error.message + } + }); + } + + lbryProxy.stream_repost(options).then(success, failure); + }); + }; +} + +function doClearRepostError() { + return { + type: CLEAR_REPOST_ERROR + }; +} + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -4450,7 +4503,9 @@ const defaultState = { updatingChannel: false, creatingChannel: false, createChannelError: undefined, - pendingChannelImport: false + pendingChannelImport: false, + repostLoading: false, + repostError: undefined }; function handleClaimAction(state, action) { @@ -4805,6 +4860,43 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }); }; +reducers[CLAIM_REPOST_STARTED] = state => { + return _extends$9({}, state, { + repostLoading: true, + repostError: null + }); +}; +reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { + const { originalClaimId, repostClaim } = action.data; + const byId = _extends$9({}, state.byId); + const claimsByUri = _extends$9({}, state.claimsByUri); + const claimThatWasReposted = byId[originalClaimId]; + + const repostStub = _extends$9({}, repostClaim, { reposted_claim: claimThatWasReposted }); + byId[repostStub.claim_id] = repostStub; + claimsByUri[repostStub.permanent_url] = repostStub.claim_id; + + return _extends$9({}, state, { + byId, + claimsByUri, + repostLoading: false, + repostError: null + }); +}; +reducers[CLAIM_REPOST_FAILED] = (state, action) => { + const { error } = action.data; + + return _extends$9({}, state, { + repostLoading: false, + repostError: error + }); +}; +reducers[CLEAR_REPOST_ERROR] = state => { + return _extends$9({}, state, { + repostError: null + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -5997,6 +6089,7 @@ exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; +exports.doClearRepostError = doClearRepostError; exports.doClearSupport = doClearSupport; exports.doCommentAbandon = doCommentAbandon; exports.doCommentCreate = doCommentCreate; @@ -6026,6 +6119,7 @@ exports.doPreferenceSet = doPreferenceSet; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; +exports.doRepost = doRepost; exports.doResetThumbnailStatus = doResetThumbnailStatus; exports.doResolveUri = doResolveUri; exports.doResolveUris = doResolveUris; @@ -6192,6 +6286,8 @@ exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; +exports.selectRepostError = selectRepostError; +exports.selectRepostLoading = selectRepostLoading; exports.selectReservedBalance = selectReservedBalance; exports.selectResolvedSearchResultsByQuery = selectResolvedSearchResultsByQuery; exports.selectResolvedSearchResultsByQueryLastPageReached = selectResolvedSearchResultsByQueryLastPageReached; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index d2657cb..ba88d27 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -204,6 +204,15 @@ declare type StreamListResponse = { total_pages: number, }; +declare type StreamRepostOptions = { + name: string, + bid: string, + claim_id: string, + channel_id: string, +}; + +declare type StreamRepostResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -240,6 +249,7 @@ declare type LbryTypes = { support_create: (params: {}) => Promise, support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, + stream_repost: (params: StreamRepostOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index d2657cb..ba88d27 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -204,6 +204,15 @@ declare type StreamListResponse = { total_pages: number, }; +declare type StreamRepostOptions = { + name: string, + bid: string, + claim_id: string, + channel_id: string, +}; + +declare type StreamRepostResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -240,6 +249,7 @@ declare type LbryTypes = { support_create: (params: {}) => Promise, support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, + stream_repost: (params: StreamRepostOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 1f8b841..ae74a0d 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -103,6 +103,10 @@ export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; export const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; export const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; export const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; +export const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; +export const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; +export const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; +export const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index 3650efd..7dd8200 100644 --- a/src/index.js +++ b/src/index.js @@ -67,6 +67,8 @@ export { doUpdateChannel, doClaimSearch, doImportChannel, + doRepost, + doClearRepostError, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -232,6 +234,8 @@ export { selectChannelImportPending, makeSelectMyStreamUrlsForPage, selectMyStreamUrlsCount, + selectRepostError, + selectRepostLoading, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/lbry.js b/src/lbry.js index 0332011..ea72713 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -86,6 +86,7 @@ const Lbry: LbryTypes = { channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), support_list: params => daemonCallWithResult('support_list', params), + stream_repost: params => daemonCallWithResult('stream_repost', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), @@ -121,7 +122,6 @@ const Lbry: LbryTypes = { comment_create: (params = {}) => daemonCallWithResult('comment_create', params), comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - // requires SDK ver. 0.53.0 comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index cd21153..2857097 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -100,16 +100,18 @@ export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999) type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - Lbry.stream_list({ page, page_size: pageSize }).then((result: StreamListResponse) => { - const claims = result.items; + Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then( + (result: StreamListResponse) => { + const claims = result.items; - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims, - }, - }); - }); + dispatch({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims, + }, + }); + } + ); }; } @@ -455,3 +457,44 @@ export function doClaimSearch( Lbry.claim_search(options).then(success, failure); }; } + +export function doRepost(options: StreamRepostOptions) { + return (dispatch: Dispatch) => { + // $FlowFixMe + return new Promise(resolve => { + dispatch({ + type: ACTIONS.CLAIM_REPOST_STARTED, + }); + + function success(response) { + const repostClaim = response.outputs[0]; + dispatch({ + type: ACTIONS.CLAIM_REPOST_COMPLETED, + data: { + originalClaimId: options.claim_id, + repostClaim, + }, + }); + + resolve(); + } + + function failure(error) { + dispatch({ + type: ACTIONS.CLAIM_REPOST_FAILED, + data: { + error: error.message, + }, + }); + } + + Lbry.stream_repost(options).then(success, failure); + }); + }; +} + +export function doClearRepostError() { + return { + type: ACTIONS.CLEAR_REPOST_ERROR, + }; +} diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f60cdca..2935cc4 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -39,6 +39,8 @@ type State = { updateChannelError: string, updatingChannel: boolean, pendingChannelImport: string | boolean, + repostLoading: boolean, + repostError: ?string, }; const reducers = {}; @@ -65,6 +67,8 @@ const defaultState = { creatingChannel: false, createChannelError: undefined, pendingChannelImport: false, + repostLoading: false, + repostError: undefined, }; function handleClaimAction(state: State, action: any): State { @@ -447,6 +451,47 @@ reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State, action: any): State => { }); }; +reducers[ACTIONS.CLAIM_REPOST_STARTED] = (state: State): State => { + return { + ...state, + repostLoading: true, + repostError: null, + }; +}; +reducers[ACTIONS.CLAIM_REPOST_COMPLETED] = (state: State, action: any): State => { + const { originalClaimId, repostClaim } = action.data; + const byId = { ...state.byId }; + const claimsByUri = { ...state.claimsByUri }; + const claimThatWasReposted = byId[originalClaimId]; + + const repostStub = { ...repostClaim, reposted_claim: claimThatWasReposted }; + byId[repostStub.claim_id] = repostStub; + claimsByUri[repostStub.permanent_url] = repostStub.claim_id; + + return { + ...state, + byId, + claimsByUri, + repostLoading: false, + repostError: null, + }; +}; +reducers[ACTIONS.CLAIM_REPOST_FAILED] = (state: State, action: any): State => { + const { error } = action.data; + + return { + ...state, + repostLoading: false, + repostError: error, + }; +}; +reducers[ACTIONS.CLEAR_REPOST_ERROR] = (state: State): State => { + return { + ...state, + repostError: null, + }; +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 73a3018..47b6a49 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -31,6 +31,16 @@ export const selectCreateChannelError = createSelector( state => state.createChannelError ); +export const selectRepostLoading = createSelector( + selectState, + state => state.repostLoading +); + +export const selectRepostError = createSelector( + selectState, + state => state.repostError +); + export const selectClaimsByUri = createSelector( selectState, selectClaimsById, @@ -279,8 +289,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; }