Merge pull request #162 from lbryio/reduxPublish
MERGE AFTER 34 RELEASE - enables publish for desktop - flow skipped WIP
This commit is contained in:
commit
49e57e8ba0
8 changed files with 257 additions and 328 deletions
315
dist/bundle.es.js
vendored
315
dist/bundle.es.js
vendored
|
@ -7,6 +7,8 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
|
||||||
require('proxy-polyfill');
|
require('proxy-polyfill');
|
||||||
var reselect = require('reselect');
|
var reselect = require('reselect');
|
||||||
var uuid = _interopDefault(require('uuid/v4'));
|
var uuid = _interopDefault(require('uuid/v4'));
|
||||||
|
var fs = _interopDefault(require('fs'));
|
||||||
|
var path = _interopDefault(require('path'));
|
||||||
|
|
||||||
const MINIMUM_PUBLISH_BID = 0.00000001;
|
const MINIMUM_PUBLISH_BID = 0.00000001;
|
||||||
|
|
||||||
|
@ -2082,14 +2084,6 @@ function doUpdateBlockHeight() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/reactjs/redux/issues/911
|
|
||||||
function batchActions(...actions) {
|
|
||||||
return {
|
|
||||||
type: 'BATCH_ACTIONS',
|
|
||||||
actions
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||||
|
|
||||||
function doResolveUris(uris, returnCachedClaims = false) {
|
function doResolveUris(uris, returnCachedClaims = false) {
|
||||||
|
@ -2786,18 +2780,88 @@ function doSetFileListSort(page, value) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// https://github.com/reactjs/redux/issues/911
|
||||||
|
function batchActions(...actions) {
|
||||||
|
return {
|
||||||
|
type: 'BATCH_ACTIONS',
|
||||||
|
actions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const formatLbryUriForWeb = uri => {
|
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
||||||
const { claimName, claimId } = parseURI(uri);
|
|
||||||
|
|
||||||
let webUrl = `/${claimName}`;
|
const selectState$5 = state => state.publish || {};
|
||||||
if (claimId) {
|
|
||||||
webUrl += `/${claimId}`;
|
const selectPublishFormValues = reselect.createSelector(selectState$5, state => {
|
||||||
|
const formValues = _objectWithoutProperties(state, ['pendingPublish']);
|
||||||
|
return formValues;
|
||||||
|
});
|
||||||
|
const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]);
|
||||||
|
|
||||||
|
// Is the current uri the same as the uri they clicked "edit" on
|
||||||
|
const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => {
|
||||||
|
const { editingURI, uri } = publishState;
|
||||||
|
|
||||||
|
if (!editingURI || !uri) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return webUrl;
|
const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri);
|
||||||
};
|
const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI);
|
||||||
|
|
||||||
|
// Depending on the previous/current use of a channel, we need to compare different things
|
||||||
|
// ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName
|
||||||
|
const currentName = currentIsChannel ? currentContentName : currentClaimName;
|
||||||
|
const editName = editIsChannel ? editContentName : editClaimName;
|
||||||
|
return currentName === editName;
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => {
|
||||||
|
const { contentName, claimName } = parseURI(uri);
|
||||||
|
const { claimId: editClaimId } = parseURI(editingURI);
|
||||||
|
|
||||||
|
// If isStillEditing
|
||||||
|
// They clicked "edit" from the file page
|
||||||
|
// They haven't changed the channel/name after clicking edit
|
||||||
|
// Get the claim so they can edit without re-uploading a new file
|
||||||
|
return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName);
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, selectResolvingUris, ({ uri, name }, resolvingUris) => {
|
||||||
|
if (uri) {
|
||||||
|
const isResolvingUri = resolvingUris.includes(uri);
|
||||||
|
const { isChannel } = parseURI(uri);
|
||||||
|
|
||||||
|
let isResolvingShortUri;
|
||||||
|
if (isChannel) {
|
||||||
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
isResolvingShortUri = resolvingUris.includes(shortUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isResolvingUri || isResolvingShortUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => {
|
||||||
|
// We only care about the winning claim for the short uri
|
||||||
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
const claimForShortUri = claimsByUri[shortUri];
|
||||||
|
|
||||||
|
if (!myClaimForUri && claimForShortUri) {
|
||||||
|
return claimForShortUri.effective_amount;
|
||||||
|
} else if (myClaimForUri && claimForShortUri) {
|
||||||
|
// https://github.com/lbryio/lbry/issues/1476
|
||||||
|
// We should check the current effective_amount on my claim to see how much additional lbc
|
||||||
|
// is needed to win the claim. Currently this is not possible during a takeover.
|
||||||
|
// With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim"
|
||||||
|
// For now just ignore supports. We will just show the winning claim's bid amount
|
||||||
|
return claimForShortUri.effective_amount || claimForShortUri.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
var _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
var _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||||
|
|
||||||
|
@ -2875,6 +2939,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch =>
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
const name = makeid();
|
const name = makeid();
|
||||||
data.append('name', name);
|
data.append('name', name);
|
||||||
|
// $FlowFixMe
|
||||||
data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName });
|
data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName });
|
||||||
|
|
||||||
return fetch('https://spee.ch/api/claim/publish', {
|
return fetch('https://spee.ch/api/claim/publish', {
|
||||||
|
@ -2923,15 +2988,15 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch =>
|
||||||
};
|
};
|
||||||
|
|
||||||
const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
||||||
const { name, amount, channel_name: channelName, value } = claim;
|
const { name, amount, value } = claim;
|
||||||
|
const channelName = claim && claim.signing_channel && claim.signing_channel.normalized_name || null;
|
||||||
const {
|
const {
|
||||||
author,
|
author,
|
||||||
description,
|
description,
|
||||||
// use same values as default state
|
// use same values as default state
|
||||||
// fee will be undefined for free content
|
// fee will be undefined for free content
|
||||||
fee = {
|
fee = {
|
||||||
amount: 0,
|
amount: '0',
|
||||||
currency: 'LBC'
|
currency: 'LBC'
|
||||||
},
|
},
|
||||||
languages,
|
languages,
|
||||||
|
@ -2943,12 +3008,11 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
||||||
|
|
||||||
const publishData = {
|
const publishData = {
|
||||||
name,
|
name,
|
||||||
channel: channelName,
|
|
||||||
bid: amount,
|
bid: amount,
|
||||||
contentIsFree: !fee.amount,
|
contentIsFree: fee.amount === '0',
|
||||||
author,
|
author,
|
||||||
description,
|
description,
|
||||||
fee: { amount: fee.amount, currency: fee.currency },
|
fee,
|
||||||
languages,
|
languages,
|
||||||
thumbnail: thumbnail ? thumbnail.url : null,
|
thumbnail: thumbnail ? thumbnail.url : null,
|
||||||
title,
|
title,
|
||||||
|
@ -2958,7 +3022,7 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
||||||
nsfw: isClaimNsfw(claim)
|
nsfw: isClaimNsfw(claim)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure custom liscence's are mapped properly
|
// Make sure custom licenses are mapped properly
|
||||||
// If the license isn't one of the standard licenses, map the custom license and description/url
|
// If the license isn't one of the standard licenses, map the custom license and description/url
|
||||||
if (!CC_LICENSES.some(({ value }) => value === license)) {
|
if (!CC_LICENSES.some(({ value }) => value === license)) {
|
||||||
if (!license || license === NONE || license === PUBLIC_DOMAIN) {
|
if (!license || license === NONE || license === PUBLIC_DOMAIN) {
|
||||||
|
@ -2973,6 +3037,9 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
||||||
} else {
|
} else {
|
||||||
publishData.licenseType = license;
|
publishData.licenseType = license;
|
||||||
}
|
}
|
||||||
|
if (channelName) {
|
||||||
|
publishData['channel'] = channelName;
|
||||||
|
}
|
||||||
|
|
||||||
if (fileInfo && fileInfo.download_path) {
|
if (fileInfo && fileInfo.download_path) {
|
||||||
try {
|
try {
|
||||||
|
@ -2986,13 +3053,17 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => {
|
||||||
dispatch({ type: DO_PREPARE_EDIT, data: publishData });
|
dispatch({ type: DO_PREPARE_EDIT, data: publishData });
|
||||||
};
|
};
|
||||||
|
|
||||||
const doPublish = params => (dispatch, getState) => {
|
const doPublish = (success, fail) => (dispatch, getState) => {
|
||||||
dispatch({ type: PUBLISH_START });
|
dispatch({ type: PUBLISH_START });
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
const myClaimForUri = selectMyClaimForUri(state);
|
||||||
const myChannels = selectMyChannelClaims(state);
|
const myChannels = selectMyChannelClaims(state);
|
||||||
const myClaims = selectMyClaimsWithoutChannels(state);
|
const myClaims = selectMyClaimsWithoutChannels(state);
|
||||||
|
// get redux publish form
|
||||||
|
const publishData = selectPublishFormValues(state);
|
||||||
|
|
||||||
|
// destructure the data values
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
bid,
|
bid,
|
||||||
|
@ -3001,15 +3072,27 @@ const doPublish = params => (dispatch, getState) => {
|
||||||
language,
|
language,
|
||||||
license,
|
license,
|
||||||
licenseUrl,
|
licenseUrl,
|
||||||
|
licenseType,
|
||||||
|
otherLicenseDescription,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
channel,
|
channel,
|
||||||
title,
|
title,
|
||||||
contentIsFree,
|
contentIsFree,
|
||||||
fee,
|
fee,
|
||||||
uri,
|
uri,
|
||||||
nsfw,
|
tags,
|
||||||
claim
|
locations
|
||||||
} = params;
|
} = publishData;
|
||||||
|
|
||||||
|
let publishingLicense;
|
||||||
|
switch (licenseType) {
|
||||||
|
case COPYRIGHT:
|
||||||
|
case OTHER:
|
||||||
|
publishingLicense = otherLicenseDescription;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
publishingLicense = licenseType;
|
||||||
|
}
|
||||||
|
|
||||||
// get the claim id from the channel name, we will use that instead
|
// get the claim id from the channel name, we will use that instead
|
||||||
const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel);
|
const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel);
|
||||||
|
@ -3017,19 +3100,22 @@ const doPublish = params => (dispatch, getState) => {
|
||||||
|
|
||||||
const publishPayload = {
|
const publishPayload = {
|
||||||
name,
|
name,
|
||||||
bid: creditsToString(bid),
|
|
||||||
title,
|
title,
|
||||||
license,
|
|
||||||
languages: [language],
|
|
||||||
description,
|
description,
|
||||||
tags: claim && claim.value.tags || [],
|
locations: locations,
|
||||||
locations: claim && claim.value.locations
|
bid: creditsToString(bid),
|
||||||
|
languages: [language],
|
||||||
|
tags: tags && tags.map(tag => tag.name),
|
||||||
|
thumbnail_url: thumbnail
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary solution to keep the same publish flow with the new tags api
|
// Temporary solution to keep the same publish flow with the new tags api
|
||||||
// Eventually we will allow users to enter their own tags on publish
|
// Eventually we will allow users to enter their own tags on publish
|
||||||
// `nsfw` will probably be removed
|
// `nsfw` will probably be removed
|
||||||
|
|
||||||
|
if (publishingLicense) {
|
||||||
|
publishPayload.license = publishingLicense;
|
||||||
|
}
|
||||||
|
|
||||||
if (licenseUrl) {
|
if (licenseUrl) {
|
||||||
publishPayload.license_url = licenseUrl;
|
publishPayload.license_url = licenseUrl;
|
||||||
}
|
}
|
||||||
|
@ -3038,19 +3124,13 @@ const doPublish = params => (dispatch, getState) => {
|
||||||
publishPayload.thumbnail_url = thumbnail;
|
publishPayload.thumbnail_url = thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claim && claim.value.release_time) {
|
// Set release time to curret date. On edits, keep original release/transaction time as release_time
|
||||||
publishPayload.release_time = Number(claim.value.release_time);
|
if (myClaimForUri && myClaimForUri.value.release_time) {
|
||||||
}
|
publishPayload.release_time = Number(myClaimForUri.value.release_time);
|
||||||
|
} else if (myClaimForUri && myClaimForUri.timestamp) {
|
||||||
if (nsfw) {
|
publishPayload.release_time = Number(myClaimForUri.timestamp);
|
||||||
if (!publishPayload.tags.includes('mature')) {
|
|
||||||
publishPayload.tags.push('mature');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const indexToRemove = publishPayload.tags.indexOf('mature');
|
publishPayload.release_time = Number(Math.round(Date.now() / 1000));
|
||||||
if (indexToRemove > -1) {
|
|
||||||
publishPayload.tags.splice(indexToRemove, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelId) {
|
if (channelId) {
|
||||||
|
@ -3066,45 +3146,11 @@ const doPublish = params => (dispatch, getState) => {
|
||||||
// The sdk will figure it out
|
// The sdk will figure it out
|
||||||
if (filePath) publishPayload.file_path = filePath;
|
if (filePath) publishPayload.file_path = filePath;
|
||||||
|
|
||||||
const success = successResponse => {
|
return lbryProxy.publish(publishPayload).then(success, fail);
|
||||||
//analytics.apiLogPublish();
|
|
||||||
|
|
||||||
const pendingClaim = successResponse.outputs[0];
|
|
||||||
const actions = [];
|
|
||||||
|
|
||||||
actions.push({
|
|
||||||
type: PUBLISH_SUCCESS
|
|
||||||
});
|
|
||||||
|
|
||||||
//actions.push(doOpenModal(MODALS.PUBLISH, { uri }));
|
|
||||||
|
|
||||||
// We have to fake a temp claim until the new pending one is returned by claim_list_mine
|
|
||||||
// We can't rely on claim_list_mine because there might be some delay before the new claims are returned
|
|
||||||
// Doing this allows us to show the pending claim immediately, it will get overwritten by the real one
|
|
||||||
const isMatch = claim => claim.claim_id === pendingClaim.claim_id;
|
|
||||||
const isEdit = myClaims.some(isMatch);
|
|
||||||
const myNewClaims = isEdit ? myClaims.map(claim => isMatch(claim) ? pendingClaim : claim) : myClaims.concat(pendingClaim);
|
|
||||||
|
|
||||||
actions.push({
|
|
||||||
type: FETCH_CLAIM_LIST_MINE_COMPLETED,
|
|
||||||
data: {
|
|
||||||
claims: myNewClaims
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(batchActions(...actions));
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({ type: PUBLISH_FAIL });
|
|
||||||
dispatch(doError(error.message));
|
|
||||||
};
|
|
||||||
|
|
||||||
return lbryProxy.publish(publishPayload).then(success, failure);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calls claim_list_mine until any pending publishes are confirmed
|
// Calls claim_list_mine until any pending publishes are confirmed
|
||||||
const doCheckPendingPublishes = () => (dispatch, getState) => {
|
const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const pendingById = selectPendingById(state);
|
const pendingById = selectPendingById(state);
|
||||||
|
|
||||||
|
@ -3116,20 +3162,13 @@ const doCheckPendingPublishes = () => (dispatch, getState) => {
|
||||||
|
|
||||||
const checkFileList = () => {
|
const checkFileList = () => {
|
||||||
lbryProxy.claim_list().then(claims => {
|
lbryProxy.claim_list().then(claims => {
|
||||||
|
// $FlowFixMe
|
||||||
claims.forEach(claim => {
|
claims.forEach(claim => {
|
||||||
// If it's confirmed, check if it was pending previously
|
// If it's confirmed, check if it was pending previously
|
||||||
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
|
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
|
||||||
delete pendingById[claim.claim_id];
|
delete pendingById[claim.claim_id];
|
||||||
|
if (onConfirmed) {
|
||||||
// If it's confirmed, check if we should notify the user
|
onConfirmed(claim);
|
||||||
if (selectosNotificationsEnabled(getState())) {
|
|
||||||
const notif = new window.Notification('LBRY Publish Complete', {
|
|
||||||
body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`,
|
|
||||||
silent: false
|
|
||||||
});
|
|
||||||
notif.onclick = () => {
|
|
||||||
dispatch(push(formatLbryUriForWeb(claim.permanent_url)));
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4170,7 +4209,7 @@ const notificationsReducer = handleActions({
|
||||||
|
|
||||||
var _extends$b = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
var _extends$b = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||||
|
|
||||||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
||||||
|
|
||||||
const defaultState$6 = {
|
const defaultState$6 = {
|
||||||
editingURI: undefined,
|
editingURI: undefined,
|
||||||
|
@ -4196,6 +4235,7 @@ const defaultState$6 = {
|
||||||
licenseType: 'None',
|
licenseType: 'None',
|
||||||
otherLicenseDescription: 'All rights reserved',
|
otherLicenseDescription: 'All rights reserved',
|
||||||
licenseUrl: '',
|
licenseUrl: '',
|
||||||
|
tags: [],
|
||||||
publishing: false,
|
publishing: false,
|
||||||
publishSuccess: false,
|
publishSuccess: false,
|
||||||
publishError: undefined
|
publishError: undefined
|
||||||
|
@ -4219,7 +4259,7 @@ const publishReducer = handleActions({
|
||||||
publishSuccess: true
|
publishSuccess: true
|
||||||
}),
|
}),
|
||||||
[DO_PREPARE_EDIT]: (state, action) => {
|
[DO_PREPARE_EDIT]: (state, action) => {
|
||||||
const publishData = _objectWithoutProperties(action.data, []);
|
const publishData = _objectWithoutProperties$1(action.data, []);
|
||||||
const { channel, name, uri } = publishData;
|
const { channel, name, uri } = publishData;
|
||||||
|
|
||||||
// The short uri is what is presented to the user
|
// The short uri is what is presented to the user
|
||||||
|
@ -4620,9 +4660,9 @@ const walletReducer = handleActions({
|
||||||
})
|
})
|
||||||
}, defaultState$9);
|
}, defaultState$9);
|
||||||
|
|
||||||
const selectState$5 = state => state.content || {};
|
const selectState$6 = state => state.content || {};
|
||||||
|
|
||||||
const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$5, makeSelectClaimForUri(uri), (state, claim) => {
|
const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => {
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -4633,9 +4673,9 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta
|
||||||
|
|
||||||
var _extends$f = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
var _extends$f = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||||
|
|
||||||
const selectState$6 = state => state.notifications || {};
|
const selectState$7 = state => state.notifications || {};
|
||||||
|
|
||||||
const selectToast = reselect.createSelector(selectState$6, state => {
|
const selectToast = reselect.createSelector(selectState$7, state => {
|
||||||
if (state.toasts.length) {
|
if (state.toasts.length) {
|
||||||
const { id, params } = state.toasts[0];
|
const { id, params } = state.toasts[0];
|
||||||
return _extends$f({
|
return _extends$f({
|
||||||
|
@ -4646,7 +4686,7 @@ const selectToast = reselect.createSelector(selectState$6, state => {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectError = reselect.createSelector(selectState$6, state => {
|
const selectError = reselect.createSelector(selectState$7, state => {
|
||||||
if (state.errors.length) {
|
if (state.errors.length) {
|
||||||
const { error } = state.errors[0];
|
const { error } = state.errors[0];
|
||||||
return {
|
return {
|
||||||
|
@ -4659,11 +4699,11 @@ const selectError = reselect.createSelector(selectState$6, state => {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
const selectState$7 = state => state.comments || {};
|
const selectState$8 = state => state.comments || {};
|
||||||
|
|
||||||
const selectCommentsById = reselect.createSelector(selectState$7, state => state.byId || {});
|
const selectCommentsById = reselect.createSelector(selectState$8, state => state.byId || {});
|
||||||
|
|
||||||
const selectCommentsByUri = reselect.createSelector(selectState$7, state => {
|
const selectCommentsByUri = reselect.createSelector(selectState$8, state => {
|
||||||
const byUri = state.commentsByUri || {};
|
const byUri = state.commentsByUri || {};
|
||||||
const comments = {};
|
const comments = {};
|
||||||
Object.keys(byUri).forEach(uri => {
|
Object.keys(byUri).forEach(uri => {
|
||||||
|
@ -4682,78 +4722,6 @@ const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsBy
|
||||||
return byId && byId[claimId];
|
return byId && byId[claimId];
|
||||||
});
|
});
|
||||||
|
|
||||||
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
|
||||||
|
|
||||||
const selectState$8 = state => state.publish || {};
|
|
||||||
|
|
||||||
const selectPublishFormValues = reselect.createSelector(selectState$8, state => {
|
|
||||||
const formValues = _objectWithoutProperties$1(state, ['pendingPublish']);
|
|
||||||
return formValues;
|
|
||||||
});
|
|
||||||
const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => {
|
|
||||||
const { editingURI, uri } = publishState;
|
|
||||||
|
|
||||||
if (!editingURI || !uri) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri);
|
|
||||||
const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI);
|
|
||||||
|
|
||||||
// Depending on the previous/current use of a channel, we need to compare different things
|
|
||||||
// ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName
|
|
||||||
const currentName = currentIsChannel ? currentContentName : currentClaimName;
|
|
||||||
const editName = editIsChannel ? editContentName : editClaimName;
|
|
||||||
return currentName === editName;
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => {
|
|
||||||
const { contentName, claimName } = parseURI(uri);
|
|
||||||
const { claimId: editClaimId } = parseURI(editingURI);
|
|
||||||
|
|
||||||
// If isStillEditing
|
|
||||||
// They clicked "edit" from the file page
|
|
||||||
// They haven't changed the channel/name after clicking edit
|
|
||||||
// Get the claim so they can edit without re-uploading a new file
|
|
||||||
return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName);
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectIsResolvingPublishUris = reselect.createSelector(selectState$8, selectResolvingUris, ({ uri, name }, resolvingUris) => {
|
|
||||||
if (uri) {
|
|
||||||
const isResolvingUri = resolvingUris.includes(uri);
|
|
||||||
const { isChannel } = parseURI(uri);
|
|
||||||
|
|
||||||
let isResolvingShortUri;
|
|
||||||
if (isChannel) {
|
|
||||||
const shortUri = buildURI({ contentName: name });
|
|
||||||
isResolvingShortUri = resolvingUris.includes(shortUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isResolvingUri || isResolvingShortUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectTakeOverAmount = reselect.createSelector(selectState$8, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => {
|
|
||||||
// We only care about the winning claim for the short uri
|
|
||||||
const shortUri = buildURI({ contentName: name });
|
|
||||||
const claimForShortUri = claimsByUri[shortUri];
|
|
||||||
|
|
||||||
if (!myClaimForUri && claimForShortUri) {
|
|
||||||
return claimForShortUri.effective_amount;
|
|
||||||
} else if (myClaimForUri && claimForShortUri) {
|
|
||||||
// https://github.com/lbryio/lbry/issues/1476
|
|
||||||
// We should check the current effective_amount on my claim to see how much additional lbc
|
|
||||||
// is needed to win the claim. Currently this is not possible during a takeover.
|
|
||||||
// With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim"
|
|
||||||
// For now just ignore supports. We will just show the winning claim's bid amount
|
|
||||||
return claimForShortUri.effective_amount || claimForShortUri.amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
const selectState$9 = state => state.tags || {};
|
const selectState$9 = state => state.tags || {};
|
||||||
|
@ -4888,6 +4856,7 @@ exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri;
|
||||||
exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel;
|
exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel;
|
||||||
exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris;
|
exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris;
|
||||||
exports.makeSelectPendingByUri = makeSelectPendingByUri;
|
exports.makeSelectPendingByUri = makeSelectPendingByUri;
|
||||||
|
exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
|
||||||
exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions;
|
exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions;
|
||||||
exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri;
|
exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri;
|
||||||
exports.makeSelectSearchUris = makeSelectSearchUris;
|
exports.makeSelectSearchUris = makeSelectSearchUris;
|
||||||
|
|
26
dist/flow-typed/Publish.js
vendored
26
dist/flow-typed/Publish.js
vendored
|
@ -17,7 +17,7 @@ declare type UpdatePublishFormData = {
|
||||||
channelId?: string,
|
channelId?: string,
|
||||||
name?: string,
|
name?: string,
|
||||||
nameError?: string,
|
nameError?: string,
|
||||||
bid?: number,
|
bid?: string,
|
||||||
bidError?: string,
|
bidError?: string,
|
||||||
otherLicenseDescription?: string,
|
otherLicenseDescription?: string,
|
||||||
licenseUrl?: string,
|
licenseUrl?: string,
|
||||||
|
@ -25,27 +25,3 @@ declare type UpdatePublishFormData = {
|
||||||
uri?: string,
|
uri?: string,
|
||||||
nsfw: boolean,
|
nsfw: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type PublishParams = {
|
|
||||||
name: ?string,
|
|
||||||
bid: ?number,
|
|
||||||
filePath?: string,
|
|
||||||
description: ?string,
|
|
||||||
language: string,
|
|
||||||
publishingLicense?: string,
|
|
||||||
publishingLicenseUrl?: string,
|
|
||||||
thumbnail: ?string,
|
|
||||||
channel: string,
|
|
||||||
channelId?: string,
|
|
||||||
title: string,
|
|
||||||
contentIsFree: boolean,
|
|
||||||
uri?: string,
|
|
||||||
license: ?string,
|
|
||||||
licenseUrl: ?string,
|
|
||||||
fee?: {
|
|
||||||
amount: string,
|
|
||||||
currency: string,
|
|
||||||
},
|
|
||||||
claim: StreamClaim,
|
|
||||||
nsfw: boolean,
|
|
||||||
};
|
|
||||||
|
|
26
flow-typed/Publish.js
vendored
26
flow-typed/Publish.js
vendored
|
@ -17,7 +17,7 @@ declare type UpdatePublishFormData = {
|
||||||
channelId?: string,
|
channelId?: string,
|
||||||
name?: string,
|
name?: string,
|
||||||
nameError?: string,
|
nameError?: string,
|
||||||
bid?: number,
|
bid?: string,
|
||||||
bidError?: string,
|
bidError?: string,
|
||||||
otherLicenseDescription?: string,
|
otherLicenseDescription?: string,
|
||||||
licenseUrl?: string,
|
licenseUrl?: string,
|
||||||
|
@ -25,27 +25,3 @@ declare type UpdatePublishFormData = {
|
||||||
uri?: string,
|
uri?: string,
|
||||||
nsfw: boolean,
|
nsfw: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type PublishParams = {
|
|
||||||
name: ?string,
|
|
||||||
bid: ?number,
|
|
||||||
filePath?: string,
|
|
||||||
description: ?string,
|
|
||||||
language: string,
|
|
||||||
publishingLicense?: string,
|
|
||||||
publishingLicenseUrl?: string,
|
|
||||||
thumbnail: ?string,
|
|
||||||
channel: string,
|
|
||||||
channelId?: string,
|
|
||||||
title: string,
|
|
||||||
contentIsFree: boolean,
|
|
||||||
uri?: string,
|
|
||||||
license: ?string,
|
|
||||||
licenseUrl: ?string,
|
|
||||||
fee?: {
|
|
||||||
amount: string,
|
|
||||||
currency: string,
|
|
||||||
},
|
|
||||||
claim: StreamClaim,
|
|
||||||
nsfw: boolean,
|
|
||||||
};
|
|
||||||
|
|
|
@ -221,6 +221,7 @@ export {
|
||||||
} from 'redux/selectors/file_info';
|
} from 'redux/selectors/file_info';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
makeSelectPublishFormValue,
|
||||||
selectPublishFormValues,
|
selectPublishFormValues,
|
||||||
selectIsStillEditing,
|
selectIsStillEditing,
|
||||||
selectMyClaimForUri,
|
selectMyClaimForUri,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import Lbry from 'lbry';
|
import Lbry from 'lbry';
|
||||||
import { normalizeURI, parseURI } from 'lbryURI';
|
import { normalizeURI } from 'lbryURI';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims';
|
import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims';
|
||||||
import { doFetchTransactions } from 'redux/actions/wallet';
|
import { doFetchTransactions } from 'redux/actions/wallet';
|
||||||
|
@ -348,7 +348,11 @@ export function doClaimSearch(options: { page_size?: number, page?: number } = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tags can be one or many (comma separated)
|
// tags can be one or many (comma separated)
|
||||||
export function doClaimSearchByTags(tags: Array<string>, amount: number = 10, options: { page?: number } = {}) {
|
export function doClaimSearchByTags(
|
||||||
|
tags: Array<string>,
|
||||||
|
amount: number = 10,
|
||||||
|
options: { page?: number } = {}
|
||||||
|
) {
|
||||||
return (dispatch: Dispatch) => {
|
return (dispatch: Dispatch) => {
|
||||||
const tagList = createNormalizedTagKey(tags);
|
const tagList = createNormalizedTagKey(tags);
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses';
|
import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
//import * as MODALS from 'constants/modal_types';
|
|
||||||
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
|
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
|
||||||
import Lbry from 'lbry';
|
import Lbry from 'lbry';
|
||||||
import { batchActions } from 'util/batchActions';
|
import { batchActions } from 'util/batchActions';
|
||||||
|
@ -13,7 +12,9 @@ import {
|
||||||
selectPendingById,
|
selectPendingById,
|
||||||
selectMyClaimsWithoutChannels,
|
selectMyClaimsWithoutChannels,
|
||||||
} from 'redux/selectors/claims';
|
} from 'redux/selectors/claims';
|
||||||
import { formatLbryUriForWeb } from 'util/uri';
|
import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
export const doResetThumbnailStatus = () => (dispatch: Dispatch) => {
|
export const doResetThumbnailStatus = () => (dispatch: Dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -54,13 +55,19 @@ export const doClearPublish = () => (dispatch: Dispatch) => {
|
||||||
return dispatch(doResetThumbnailStatus());
|
return dispatch(doResetThumbnailStatus());
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (dispatch: Dispatch) =>
|
export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (
|
||||||
|
dispatch: Dispatch
|
||||||
|
) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||||
data: { ...publishFormValue },
|
data: { ...publishFormValue },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, fsAdapter: any) => (dispatch: Dispatch) => {
|
export const doUploadThumbnail = (
|
||||||
|
filePath: string,
|
||||||
|
thumbnailBuffer: Uint8Array,
|
||||||
|
fsAdapter: any
|
||||||
|
) => (dispatch: Dispatch) => {
|
||||||
let thumbnail, fileExt, fileName, fileType;
|
let thumbnail, fileExt, fileName, fileType;
|
||||||
|
|
||||||
const makeid = () => {
|
const makeid = () => {
|
||||||
|
@ -84,7 +91,7 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array,
|
||||||
doError(error)
|
doError(error)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||||
|
@ -100,20 +107,23 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array,
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
const name = makeid();
|
const name = makeid();
|
||||||
data.append('name', name);
|
data.append('name', name);
|
||||||
|
// $FlowFixMe
|
||||||
data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName });
|
data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName });
|
||||||
|
|
||||||
return fetch('https://spee.ch/api/claim/publish', {
|
return fetch('https://spee.ch/api/claim/publish', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: data
|
body: data,
|
||||||
}).then(response => response.json())
|
})
|
||||||
.then(json => json.success
|
.then(response => response.json())
|
||||||
|
.then(json =>
|
||||||
|
json.success
|
||||||
? dispatch({
|
? dispatch({
|
||||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||||
data: {
|
data: {
|
||||||
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
||||||
thumbnail: `${json.data.url}${fileExt}`,
|
thumbnail: `${json.data.url}${fileExt}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: uploadError(json.message)
|
: uploadError(json.message)
|
||||||
)
|
)
|
||||||
.catch(err => uploadError(err.message));
|
.catch(err => uploadError(err.message));
|
||||||
|
@ -147,28 +157,31 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array,
|
||||||
.then(json =>
|
.then(json =>
|
||||||
json.success
|
json.success
|
||||||
? dispatch({
|
? dispatch({
|
||||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||||
data: {
|
data: {
|
||||||
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
||||||
thumbnail: `${json.data.url}${fileExt}`,
|
thumbnail: `${json.data.url}${fileExt}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: uploadError(json.message)
|
: uploadError(json.message)
|
||||||
)
|
)
|
||||||
.catch(err => uploadError(err.message));
|
.catch(err => uploadError(err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => (dispatch: Dispatch) => {
|
export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => (
|
||||||
const { name, amount, channel_name: channelName, value } = claim;
|
dispatch: Dispatch
|
||||||
|
) => {
|
||||||
|
const { name, amount, value } = claim;
|
||||||
|
const channelName =
|
||||||
|
(claim && claim.signing_channel && claim.signing_channel.normalized_name) || null;
|
||||||
const {
|
const {
|
||||||
author,
|
author,
|
||||||
description,
|
description,
|
||||||
// use same values as default state
|
// use same values as default state
|
||||||
// fee will be undefined for free content
|
// fee will be undefined for free content
|
||||||
fee = {
|
fee = {
|
||||||
amount: 0,
|
amount: '0',
|
||||||
currency: 'LBC',
|
currency: 'LBC',
|
||||||
},
|
},
|
||||||
languages,
|
languages,
|
||||||
|
@ -180,12 +193,11 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
|
||||||
|
|
||||||
const publishData: UpdatePublishFormData = {
|
const publishData: UpdatePublishFormData = {
|
||||||
name,
|
name,
|
||||||
channel: channelName,
|
|
||||||
bid: amount,
|
bid: amount,
|
||||||
contentIsFree: !fee.amount,
|
contentIsFree: fee.amount === '0',
|
||||||
author,
|
author,
|
||||||
description,
|
description,
|
||||||
fee: { amount: fee.amount, currency: fee.currency },
|
fee,
|
||||||
languages,
|
languages,
|
||||||
thumbnail: thumbnail ? thumbnail.url : null,
|
thumbnail: thumbnail ? thumbnail.url : null,
|
||||||
title,
|
title,
|
||||||
|
@ -195,7 +207,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
|
||||||
nsfw: isClaimNsfw(claim),
|
nsfw: isClaimNsfw(claim),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure custom liscence's are mapped properly
|
// Make sure custom licenses are mapped properly
|
||||||
// If the license isn't one of the standard licenses, map the custom license and description/url
|
// If the license isn't one of the standard licenses, map the custom license and description/url
|
||||||
if (!CC_LICENSES.some(({ value }) => value === license)) {
|
if (!CC_LICENSES.some(({ value }) => value === license)) {
|
||||||
if (!license || license === NONE || license === PUBLIC_DOMAIN) {
|
if (!license || license === NONE || license === PUBLIC_DOMAIN) {
|
||||||
|
@ -210,6 +222,9 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
|
||||||
} else {
|
} else {
|
||||||
publishData.licenseType = license;
|
publishData.licenseType = license;
|
||||||
}
|
}
|
||||||
|
if (channelName) {
|
||||||
|
publishData['channel'] = channelName;
|
||||||
|
}
|
||||||
|
|
||||||
if (fileInfo && fileInfo.download_path) {
|
if (fileInfo && fileInfo.download_path) {
|
||||||
try {
|
try {
|
||||||
|
@ -223,13 +238,20 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
|
||||||
dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
|
dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => {
|
export const doPublish = (success: Function, fail: Function) => (
|
||||||
|
dispatch: Dispatch,
|
||||||
|
getState: () => {}
|
||||||
|
) => {
|
||||||
dispatch({ type: ACTIONS.PUBLISH_START });
|
dispatch({ type: ACTIONS.PUBLISH_START });
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
const myClaimForUri = selectMyClaimForUri(state);
|
||||||
const myChannels = selectMyChannelClaims(state);
|
const myChannels = selectMyChannelClaims(state);
|
||||||
const myClaims = selectMyClaimsWithoutChannels(state);
|
const myClaims = selectMyClaimsWithoutChannels(state);
|
||||||
|
// get redux publish form
|
||||||
|
const publishData = selectPublishFormValues(state);
|
||||||
|
|
||||||
|
// destructure the data values
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
bid,
|
bid,
|
||||||
|
@ -238,15 +260,27 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat
|
||||||
language,
|
language,
|
||||||
license,
|
license,
|
||||||
licenseUrl,
|
licenseUrl,
|
||||||
|
licenseType,
|
||||||
|
otherLicenseDescription,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
channel,
|
channel,
|
||||||
title,
|
title,
|
||||||
contentIsFree,
|
contentIsFree,
|
||||||
fee,
|
fee,
|
||||||
uri,
|
uri,
|
||||||
nsfw,
|
tags,
|
||||||
claim,
|
locations,
|
||||||
} = params;
|
} = publishData;
|
||||||
|
|
||||||
|
let publishingLicense;
|
||||||
|
switch (licenseType) {
|
||||||
|
case COPYRIGHT:
|
||||||
|
case OTHER:
|
||||||
|
publishingLicense = otherLicenseDescription;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
publishingLicense = licenseType;
|
||||||
|
}
|
||||||
|
|
||||||
// get the claim id from the channel name, we will use that instead
|
// get the claim id from the channel name, we will use that instead
|
||||||
const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel);
|
const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel);
|
||||||
|
@ -254,31 +288,38 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat
|
||||||
|
|
||||||
const publishPayload: {
|
const publishPayload: {
|
||||||
name: ?string,
|
name: ?string,
|
||||||
|
bid: string,
|
||||||
|
description?: string,
|
||||||
channel_id?: string,
|
channel_id?: string,
|
||||||
bid: number,
|
|
||||||
file_path?: string,
|
file_path?: string,
|
||||||
tags: Array<string>,
|
|
||||||
locations?: Array<Location>,
|
|
||||||
license_url?: string,
|
license_url?: string,
|
||||||
|
license?: string,
|
||||||
thumbnail_url?: string,
|
thumbnail_url?: string,
|
||||||
release_time?: number,
|
release_time?: number,
|
||||||
fee_currency?: string,
|
fee_currency?: string,
|
||||||
fee_amount?: string,
|
fee_amount?: string,
|
||||||
|
languages?: Array<string>,
|
||||||
|
tags: Array<string>,
|
||||||
|
locations?: Array<any>,
|
||||||
} = {
|
} = {
|
||||||
name,
|
name,
|
||||||
bid: creditsToString(bid),
|
|
||||||
title,
|
title,
|
||||||
license,
|
|
||||||
languages: [language],
|
|
||||||
description,
|
description,
|
||||||
tags: (claim && claim.value.tags) || [],
|
locations: locations,
|
||||||
locations: claim && claim.value.locations,
|
bid: creditsToString(bid),
|
||||||
|
languages: [language],
|
||||||
|
tags: tags && tags.map(tag => tag.name),
|
||||||
|
thumbnail_url: thumbnail,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary solution to keep the same publish flow with the new tags api
|
// Temporary solution to keep the same publish flow with the new tags api
|
||||||
// Eventually we will allow users to enter their own tags on publish
|
// Eventually we will allow users to enter their own tags on publish
|
||||||
// `nsfw` will probably be removed
|
// `nsfw` will probably be removed
|
||||||
|
|
||||||
|
if (publishingLicense) {
|
||||||
|
publishPayload.license = publishingLicense;
|
||||||
|
}
|
||||||
|
|
||||||
if (licenseUrl) {
|
if (licenseUrl) {
|
||||||
publishPayload.license_url = licenseUrl;
|
publishPayload.license_url = licenseUrl;
|
||||||
}
|
}
|
||||||
|
@ -287,19 +328,13 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat
|
||||||
publishPayload.thumbnail_url = thumbnail;
|
publishPayload.thumbnail_url = thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (claim && claim.value.release_time) {
|
// Set release time to curret date. On edits, keep original release/transaction time as release_time
|
||||||
publishPayload.release_time = Number(claim.value.release_time);
|
if (myClaimForUri && myClaimForUri.value.release_time) {
|
||||||
}
|
publishPayload.release_time = Number(myClaimForUri.value.release_time);
|
||||||
|
} else if (myClaimForUri && myClaimForUri.timestamp) {
|
||||||
if (nsfw) {
|
publishPayload.release_time = Number(myClaimForUri.timestamp);
|
||||||
if (!publishPayload.tags.includes('mature')) {
|
|
||||||
publishPayload.tags.push('mature');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const indexToRemove = publishPayload.tags.indexOf('mature');
|
publishPayload.release_time = Number(Math.round(Date.now() / 1000));
|
||||||
if (indexToRemove > -1) {
|
|
||||||
publishPayload.tags.splice(indexToRemove, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelId) {
|
if (channelId) {
|
||||||
|
@ -315,47 +350,14 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat
|
||||||
// The sdk will figure it out
|
// The sdk will figure it out
|
||||||
if (filePath) publishPayload.file_path = filePath;
|
if (filePath) publishPayload.file_path = filePath;
|
||||||
|
|
||||||
const success = successResponse => {
|
return Lbry.publish(publishPayload).then(success, fail);
|
||||||
//analytics.apiLogPublish();
|
|
||||||
|
|
||||||
const pendingClaim = successResponse.outputs[0];
|
|
||||||
const actions = [];
|
|
||||||
|
|
||||||
actions.push({
|
|
||||||
type: ACTIONS.PUBLISH_SUCCESS,
|
|
||||||
});
|
|
||||||
|
|
||||||
//actions.push(doOpenModal(MODALS.PUBLISH, { uri }));
|
|
||||||
|
|
||||||
// We have to fake a temp claim until the new pending one is returned by claim_list_mine
|
|
||||||
// We can't rely on claim_list_mine because there might be some delay before the new claims are returned
|
|
||||||
// Doing this allows us to show the pending claim immediately, it will get overwritten by the real one
|
|
||||||
const isMatch = claim => claim.claim_id === pendingClaim.claim_id;
|
|
||||||
const isEdit = myClaims.some(isMatch);
|
|
||||||
const myNewClaims = isEdit
|
|
||||||
? myClaims.map(claim => (isMatch(claim) ? pendingClaim : claim))
|
|
||||||
: myClaims.concat(pendingClaim);
|
|
||||||
|
|
||||||
actions.push({
|
|
||||||
type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED,
|
|
||||||
data: {
|
|
||||||
claims: myNewClaims,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(batchActions(...actions));
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({ type: ACTIONS.PUBLISH_FAIL });
|
|
||||||
dispatch(doError(error.message));
|
|
||||||
};
|
|
||||||
|
|
||||||
return Lbry.publish(publishPayload).then(success, failure);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calls claim_list_mine until any pending publishes are confirmed
|
// Calls claim_list_mine until any pending publishes are confirmed
|
||||||
export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetState) => {
|
export const doCheckPendingPublishes = (onConfirmed: Function) => (
|
||||||
|
dispatch: Dispatch,
|
||||||
|
getState: GetState
|
||||||
|
) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const pendingById = selectPendingById(state);
|
const pendingById = selectPendingById(state);
|
||||||
|
|
||||||
|
@ -367,20 +369,13 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS
|
||||||
|
|
||||||
const checkFileList = () => {
|
const checkFileList = () => {
|
||||||
Lbry.claim_list().then(claims => {
|
Lbry.claim_list().then(claims => {
|
||||||
|
// $FlowFixMe
|
||||||
claims.forEach(claim => {
|
claims.forEach(claim => {
|
||||||
// If it's confirmed, check if it was pending previously
|
// If it's confirmed, check if it was pending previously
|
||||||
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
|
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
|
||||||
delete pendingById[claim.claim_id];
|
delete pendingById[claim.claim_id];
|
||||||
|
if (onConfirmed) {
|
||||||
// If it's confirmed, check if we should notify the user
|
onConfirmed(claim);
|
||||||
if (selectosNotificationsEnabled(getState())) {
|
|
||||||
const notif = new window.Notification('LBRY Publish Complete', {
|
|
||||||
body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`,
|
|
||||||
silent: false,
|
|
||||||
});
|
|
||||||
notif.onclick = () => {
|
|
||||||
dispatch(push(formatLbryUriForWeb(claim.permanent_url)));
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,6 +27,7 @@ type PublishState = {
|
||||||
bidError: ?string,
|
bidError: ?string,
|
||||||
otherLicenseDescription: string,
|
otherLicenseDescription: string,
|
||||||
licenseUrl: string,
|
licenseUrl: string,
|
||||||
|
tags: Array<string>
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultState: PublishState = {
|
const defaultState: PublishState = {
|
||||||
|
@ -53,6 +54,7 @@ const defaultState: PublishState = {
|
||||||
licenseType: 'None',
|
licenseType: 'None',
|
||||||
otherLicenseDescription: 'All rights reserved',
|
otherLicenseDescription: 'All rights reserved',
|
||||||
licenseUrl: '',
|
licenseUrl: '',
|
||||||
|
tags: [],
|
||||||
publishing: false,
|
publishing: false,
|
||||||
publishSuccess: false,
|
publishSuccess: false,
|
||||||
publishError: undefined,
|
publishError: undefined,
|
||||||
|
|
|
@ -17,6 +17,12 @@ export const selectPublishFormValues = createSelector(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const makeSelectPublishFormValue = item =>
|
||||||
|
createSelector(
|
||||||
|
selectState,
|
||||||
|
state => state[item]
|
||||||
|
);
|
||||||
|
|
||||||
// Is the current uri the same as the uri they clicked "edit" on
|
// Is the current uri the same as the uri they clicked "edit" on
|
||||||
export const selectIsStillEditing = createSelector(
|
export const selectIsStillEditing = createSelector(
|
||||||
selectPublishFormValues,
|
selectPublishFormValues,
|
||||||
|
@ -54,8 +60,8 @@ export const selectMyClaimForUri = createSelector(
|
||||||
return isStillEditing
|
return isStillEditing
|
||||||
? claimsById[editClaimId]
|
? claimsById[editClaimId]
|
||||||
: myClaims.find(claim =>
|
: myClaims.find(claim =>
|
||||||
!contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName
|
!contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue