Compare commits

..

1 commit

Author SHA1 Message Date
zeppi
acb7a3b0d8 selectClaimIdIsPending 2021-06-23 10:43:17 -04:00
20 changed files with 389 additions and 682 deletions

450
dist/bundle.es.js vendored
View file

@ -2,12 +2,9 @@
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
require('proxy-polyfill');
var uuid = require('uuid');
var reselect = require('reselect');
var fromEntries = _interopDefault(require('@ungap/from-entries'));
const MINIMUM_PUBLISH_BID = 0.00000001;
@ -719,7 +716,7 @@ const INSTANT_PURCHASE_MAX = 'instant_purchase_max';
const THEME = 'theme';
const THEMES = 'themes';
const AUTOMATIC_DARK_MODE_ENABLED = 'automatic_dark_mode_enabled';
const AUTOPLAY_MEDIA = 'autoplay';
const AUTOPLAY = 'autoplay';
const AUTOPLAY_NEXT = 'autoplay_next';
const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
const AUTO_DOWNLOAD = 'auto_download';
@ -735,8 +732,6 @@ const ENABLE_PUBLISH_PREVIEW = 'enable-publish-preview';
const TILE_LAYOUT = 'tile_layout';
const VIDEO_THEATER_MODE = 'video_theater_mode';
const VIDEO_PLAYBACK_RATE = 'video_playback_rate';
const CUSTOM_COMMENTS_SERVER_ENABLED = 'custom_comments_server_enabled';
const CUSTOM_COMMENTS_SERVER_URL = 'custom_comments_server_url';
// mobile settings
const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled';
@ -770,7 +765,7 @@ var settings = /*#__PURE__*/Object.freeze({
THEME: THEME,
THEMES: THEMES,
AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED,
AUTOPLAY_MEDIA: AUTOPLAY_MEDIA,
AUTOPLAY: AUTOPLAY,
AUTOPLAY_NEXT: AUTOPLAY_NEXT,
OS_NOTIFICATIONS_ENABLED: OS_NOTIFICATIONS_ENABLED,
AUTO_DOWNLOAD: AUTO_DOWNLOAD,
@ -786,8 +781,6 @@ var settings = /*#__PURE__*/Object.freeze({
TILE_LAYOUT: TILE_LAYOUT,
VIDEO_THEATER_MODE: VIDEO_THEATER_MODE,
VIDEO_PLAYBACK_RATE: VIDEO_PLAYBACK_RATE,
CUSTOM_COMMENTS_SERVER_ENABLED: CUSTOM_COMMENTS_SERVER_ENABLED,
CUSTOM_COMMENTS_SERVER_URL: CUSTOM_COMMENTS_SERVER_URL,
BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED,
FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED,
KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING,
@ -1040,7 +1033,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({
const SDK_SYNC_KEYS = [LBRYUM_SERVERS, SHARE_USAGE_DATA];
// CLIENT
const CLIENT_SYNC_KEYS = [SHOW_MATURE, HIDE_REPOSTS, SHOW_ANONYMOUS, INSTANT_PURCHASE_ENABLED, INSTANT_PURCHASE_MAX, THEME, AUTOPLAY_MEDIA, AUTOPLAY_NEXT, HIDE_BALANCE, HIDE_SPLASH_ANIMATION, FLOATING_PLAYER, DARK_MODE_TIMES, AUTOMATIC_DARK_MODE_ENABLED, LANGUAGE];
const CLIENT_SYNC_KEYS = [SHOW_MATURE, HIDE_REPOSTS, SHOW_ANONYMOUS, INSTANT_PURCHASE_ENABLED, INSTANT_PURCHASE_MAX, THEME, AUTOPLAY, HIDE_BALANCE, HIDE_SPLASH_ANIMATION, FLOATING_PLAYER, DARK_MODE_TIMES, AUTOMATIC_DARK_MODE_ENABLED];
var shared_preferences = /*#__PURE__*/Object.freeze({
SDK_SYNC_KEYS: SDK_SYNC_KEYS,
@ -1197,7 +1190,6 @@ const Lbry = {
utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params),
support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params),
purchase_list: (params = {}) => daemonCallWithResult('purchase_list', params),
txo_list: (params = {}) => daemonCallWithResult('txo_list', params),
sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params),
sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params),
@ -1480,7 +1472,7 @@ const channelNameMinLength = 1;
const claimIdMaxLength = 40;
// see https://spec.lbry.com/#urls
const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u;
const regexInvalidURI = /[ =&#:$@%?;/\\"<>%\{\}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u;
const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/;
const regexPartProtocol = '^((?:lbry://)?)';
const regexPartStreamOrChannelName = '([^:$#/]*)';
@ -1488,11 +1480,6 @@ const regexPartModifierSeparator = '([:$#]?)([^/]*)';
const queryStringBreaker = '^([\\S]+)([?][\\S]*)';
const separateQuerystring = new RegExp(queryStringBreaker);
const MOD_SEQUENCE_SEPARATOR = '*';
const MOD_CLAIM_ID_SEPARATOR_OLD = '#';
const MOD_CLAIM_ID_SEPARATOR = ':';
const MOD_BID_POSITION_SEPARATOR = '$';
/**
* Parses a LBRY name into its component parts. Throws errors with user-friendly
* messages for invalid names.
@ -1594,11 +1581,11 @@ function parseURIModifier(modSeperator, modValue) {
throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator }));
}
if (modSeperator === MOD_CLAIM_ID_SEPARATOR || MOD_CLAIM_ID_SEPARATOR_OLD) {
if (modSeperator === '#') {
claimId = modValue;
} else if (modSeperator === MOD_SEQUENCE_SEPARATOR) {
} else if (modSeperator === ':') {
claimSequence = modValue;
} else if (modSeperator === MOD_BID_POSITION_SEPARATOR) {
} else if (modSeperator === '$') {
bidPosition = modValue;
}
}
@ -1729,25 +1716,6 @@ function convertToShareLink(URL) {
}, true, 'https://open.lbry.com/');
}
function splitBySeparator(uri) {
const protocolLength = 7;
return uri.startsWith('lbry://') ? uri.slice(protocolLength).split(/[#:*]/) : uri.split(/#:\*\$/);
}
function isURIEqual(uriA, uriB) {
const parseA = parseURI(normalizeURI(uriA));
const parseB = parseURI(normalizeURI(uriB));
if (parseA.isChannel) {
if (parseB.isChannel && parseA.channelClaimId === parseB.channelClaimId) {
return true;
}
} else if (parseA.streamClaimId === parseB.streamClaimId) {
return true;
} else {
return false;
}
}
/* eslint-disable */
// underscore's deep equal function
// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189
@ -1871,12 +1839,11 @@ function extractUserState(rawObj) {
app_welcome_version,
sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections
} = rawObj.value;
return _extends$1({}, subscriptions ? { subscriptions } : {}, following ? { following } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, coin_swap_codes ? { coin_swap_codes } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}, unpublishedCollections ? { unpublishedCollections } : {}, editedCollections ? { editedCollections } : {}, builtinCollections ? { builtinCollections } : {}, savedCollections ? { savedCollections } : {});
return _extends$1({}, subscriptions ? { subscriptions } : {}, following ? { following } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, coin_swap_codes ? { coin_swap_codes } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}, unpublishedCollections ? { unpublishedCollections } : {}, builtinCollections ? { builtinCollections } : {}, savedCollections ? { savedCollections } : {});
}
return {};
@ -1894,7 +1861,6 @@ function doPopulateSharedUserState(sharedSettings) {
app_welcome_version,
sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections
} = extractUserState(sharedSettings);
@ -1910,7 +1876,6 @@ function doPopulateSharedUserState(sharedSettings) {
welcomeVersion: app_welcome_version,
allowAnalytics: sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections
}
@ -2405,13 +2370,7 @@ var _extends$3 = Object.assign || function (target) { for (var i = 1; i < argume
const selectState$1 = state => state.claims || {};
const selectById = reselect.createSelector(selectState$1, state => state.byId || {});
const selectPendingClaimsById = reselect.createSelector(selectState$1, state => state.pendingById || {});
const selectClaimsById = reselect.createSelector(selectById, selectPendingClaimsById, (byId, pendingById) => {
return Object.assign(byId, pendingById); // do I need merged to keep metadata?
});
const selectClaimsById = reselect.createSelector(selectState$1, state => state.byId || {});
const selectClaimIdsByUri = reselect.createSelector(selectState$1, state => state.claimsByUri || {});
@ -2446,21 +2405,21 @@ const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectCla
const selectAllClaimsByChannel = reselect.createSelector(selectState$1, state => state.paginatedClaimsByChannel || {});
const selectPendingIds = reselect.createSelector(selectState$1, state => Object.keys(state.pendingById) || []);
const selectPendingIds = reselect.createSelector(selectState$1, state => state.pendingIds || []);
const selectPendingClaims = reselect.createSelector(selectPendingClaimsById, pendingById => Object.values(pendingById));
const selectPendingClaims = reselect.createSelector(selectPendingIds, selectClaimsById, (pendingIds, byId) => pendingIds.map(id => byId[id]));
const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingClaimsById, (idsByUri, pendingById) => {
const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => {
const claimId = idsByUri[normalizeURI(uri)];
if (claimId) {
return Boolean(pendingById[claimId]);
return pendingIds.some(i => i === claimId);
}
return false;
});
const makeSelectClaimIdIsPending = claimId => reselect.createSelector(selectPendingClaimsById, pendingById => {
return Boolean(pendingById[claimId]);
const makeSelectClaimIdIsPending = claimId => reselect.createSelector(selectPendingIds, pendingIds => {
return pendingIds.some(i => i === claimId);
});
const makeSelectClaimIdForUri = uri => reselect.createSelector(selectClaimIdsByUri, claimIds => claimIds[uri]);
@ -2495,7 +2454,7 @@ const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelec
const channelUrl = claim.signing_channel && (claim.signing_channel.canonical_url || claim.signing_channel.permanent_url);
return _extends$3({}, repostedClaim, {
repost_url: normalizeURI(uri),
repost_url: uri,
repost_channel_url: channelUrl,
repost_bid_amount: claim && claim.meta && claim.meta.effective_amount
});
@ -2593,18 +2552,25 @@ const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector(
return claimIds.map(claimId => byId[claimId]);
});
// THIS IS LEFT OVER FROM ONE TAB CHANNEL_CONTENT
const makeSelectTotalClaimsInChannelSearch = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => {
const byChannel = allClaims[uri] || {};
return byChannel['itemCount'];
});
// THIS IS LEFT OVER FROM ONE_TAB CHANNEL CONTENT
const makeSelectTotalPagesInChannelSearch = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => {
const byChannel = allClaims[uri] || {};
return byChannel['pageCount'];
});
const makeSelectClaimsInChannelForCurrentPageState = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, (byId, allClaims, page) => {
const byChannel = allClaims[uri] || {};
const claimIds = byChannel[page || 1];
if (!claimIds) return claimIds;
return claimIds.map(claimId => byId[claimId]);
});
const makeSelectMetadataForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => {
const metadata = claim && claim.value;
return metadata || (claim === undefined ? undefined : null);
@ -2731,24 +2697,34 @@ const selectPlayingUri = reselect.createSelector(selectState$1, state => state.p
const selectChannelClaimCounts = reselect.createSelector(selectState$1, state => state.channelClaimCounts || {});
const makeSelectPendingClaimForUri = uri => reselect.createSelector(selectPendingClaimsById, pendingById => {
const makeSelectPendingClaimForUri = uri => reselect.createSelector(selectPendingIds, selectClaimsById, (pending, claims) => {
let uriIsChannel;
let uriStreamName;
let uriChannelName;
try {
({ streamName: uriStreamName, channelName: uriChannelName } = parseURI(uri));
({
isChannel: uriIsChannel,
streamName: uriStreamName,
channelName: uriChannelName
} = parseURI(uri));
} catch (e) {
return null;
}
const pendingClaims = Object.values(pendingById);
const pendingClaims = pending.map(id => claims[id]);
const matchingClaim = pendingClaims.find(claim => {
return claim.normalized_name === uriChannelName || claim.normalized_name === uriStreamName;
const { streamName, channelName, isChannel } = parseURI(claim.permanent_url);
if (isChannel) {
return channelName === uriChannelName;
} else {
return streamName === uriStreamName;
}
});
return matchingClaim || null;
});
const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[normalizeURI(uri)]);
const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]);
const makeSelectTotalPagesForChannel = (uri, pageSize = 10) => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[normalizeURI(uri)] / pageSize));
const makeSelectTotalPagesForChannel = (uri, pageSize = 10) => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize));
const makeSelectNsfwCountFromUris = uris => reselect.createSelector(selectClaimsByUri, claims => uris.reduce((acc, uri) => {
const claim = claims[uri];
@ -2758,6 +2734,21 @@ const makeSelectNsfwCountFromUris = uris => reselect.createSelector(selectClaims
return acc;
}, 0));
const makeSelectNsfwCountForChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, (byId, allClaims, page) => {
const byChannel = allClaims[uri] || {};
const claimIds = byChannel[page || 1];
if (!claimIds) return 0;
return claimIds.reduce((acc, claimId) => {
const claim = byId[claimId];
if (isClaimNsfw(claim)) {
return acc + 1;
}
return acc;
}, 0);
});
const makeSelectOmittedCountForChannel = uri => reselect.createSelector(makeSelectTotalItemsForChannel(uri), makeSelectTotalClaimsInChannelSearch(uri), (claimsInChannel, claimsInSearch) => {
if (claimsInChannel && typeof claimsInSearch === 'number' && claimsInSearch >= 0) {
return claimsInChannel - claimsInSearch;
@ -3651,7 +3642,7 @@ const makeSelectCollectionIsMine = id => reselect.createSelector(selectMyCollect
const selectMyPublishedCollections = reselect.createSelector(selectResolvedCollections, selectPendingCollections, selectMyEditedCollections, selectMyCollectionIds, (resolved, pending, edited, myIds) => {
// all resolved in myIds, plus those in pending and edited
const myPublishedCollections = fromEntries(Object.entries(pending).concat(Object.entries(resolved).filter(([key, val]) => myIds.includes(key) &&
const myPublishedCollections = Object.fromEntries(Object.entries(pending).concat(Object.entries(resolved).filter(([key, val]) => myIds.includes(key) &&
// $FlowFixMe
!pending[key])));
// now add in edited:
@ -3662,7 +3653,7 @@ const selectMyPublishedCollections = reselect.createSelector(selectResolvedColle
});
const selectMyPublishedMixedCollections = reselect.createSelector(selectMyPublishedCollections, published => {
const myCollections = fromEntries(
const myCollections = Object.fromEntries(
// $FlowFixMe
Object.entries(published).filter(([key, collection]) => {
// $FlowFixMe
@ -3672,7 +3663,7 @@ const selectMyPublishedMixedCollections = reselect.createSelector(selectMyPublis
});
const selectMyPublishedPlaylistCollections = reselect.createSelector(selectMyPublishedCollections, published => {
const myCollections = fromEntries(
const myCollections = Object.fromEntries(
// $FlowFixMe
Object.entries(published).filter(([key, collection]) => {
// $FlowFixMe
@ -3687,7 +3678,7 @@ const makeSelectMyPublishedCollectionForId = id => reselect.createSelector(selec
// selectResolvedCollections,
// selectSavedCollectionIds,
// (resolved, myIds) => {
// const mySavedCollections = fromEntries(
// const mySavedCollections = Object.fromEntries(
// Object.entries(resolved).filter(([key, val]) => myIds.includes(key))
// );
// return mySavedCollections;
@ -3699,24 +3690,10 @@ const makeSelectIsResolvingCollectionForId = id => reselect.createSelector(selec
});
const makeSelectCollectionForId = id => reselect.createSelector(selectBuiltinCollections, selectResolvedCollections, selectMyUnpublishedCollections, selectMyEditedCollections, selectPendingCollections, (bLists, rLists, uLists, eLists, pLists) => {
const collection = bLists[id] || uLists[id] || eLists[id] || pLists[id] || rLists[id];
const collection = bLists[id] || uLists[id] || eLists[id] || rLists[id] || pLists[id];
return collection;
});
const makeSelectClaimUrlInCollection = url => reselect.createSelector(selectBuiltinCollections, selectMyPublishedCollections, selectMyUnpublishedCollections, selectMyEditedCollections, selectPendingCollections, (bLists, myRLists, uLists, eLists, pLists) => {
const collections = [bLists, uLists, eLists, myRLists, pLists];
const itemsInCollections = [];
collections.map(list => {
Object.entries(list).forEach(([key, value]) => {
// $FlowFixMe
value.items.map(item => {
itemsInCollections.push(item);
});
});
});
return itemsInCollections.includes(url);
});
const makeSelectCollectionForIdHasClaimUrl = (id, url) => reselect.createSelector(makeSelectCollectionForId(id), collection => collection && collection.items.includes(url));
const makeSelectUrlsForCollectionId = id => reselect.createSelector(makeSelectCollectionForId(id), collection => collection && collection.items);
@ -3730,51 +3707,23 @@ const makeSelectClaimIdsForCollectionId = id => reselect.createSelector(makeSele
return ids;
});
const makeSelectIndexForUrlInCollection = (url, id) => reselect.createSelector(state => state.content.shuffleList, makeSelectUrlsForCollectionId(id), makeSelectClaimForUri(url), (shuffleState, urls, claim) => {
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
const listUrls = shuffleUrls || urls;
const index = listUrls && listUrls.findIndex(u => u === url);
const makeSelectIndexForUrlInCollection = (url, id) => reselect.createSelector(makeSelectUrlsForCollectionId(id), makeSelectClaimForUri(url), (urls, claim) => {
const index = urls && urls.findIndex(u => u === url);
if (index > -1) {
return index;
} else if (claim) {
const index = listUrls && listUrls.findIndex(u => u === claim.permanent_url);
const index = urls && urls.findIndex(u => u === claim.permanent_url);
if (index > -1) return index;
return claim;
}
return null;
});
const makeSelectPreviousUrlForCollectionAndUrl = (id, url) => reselect.createSelector(state => state.content.shuffleList, state => state.content.loopList, makeSelectIndexForUrlInCollection(url, id), makeSelectUrlsForCollectionId(id), (shuffleState, loopState, index, urls) => {
const loopList = loopState && loopState.collectionId === id && loopState.loop;
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
const makeSelectNextUrlForCollectionAndUrl = (id, url) => reselect.createSelector(makeSelectIndexForUrlInCollection(url, id), selectClaimsByUri, makeSelectUrlsForCollectionId(id), (index, claims, urls) => {
if (index > -1) {
const listUrls = shuffleUrls || urls;
let nextUrl;
if (index === 0 && loopList) {
nextUrl = listUrls[listUrls.length - 1];
} else {
nextUrl = listUrls[index - 1];
}
return nextUrl || null;
} else {
return null;
}
});
const makeSelectNextUrlForCollectionAndUrl = (id, url) => reselect.createSelector(state => state.content.shuffleList, state => state.content.loopList, makeSelectIndexForUrlInCollection(url, id), makeSelectUrlsForCollectionId(id), (shuffleState, loopState, index, urls) => {
const loopList = loopState && loopState.collectionId === id && loopState.loop;
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
if (index > -1) {
const listUrls = shuffleUrls || urls;
// We'll get the next playble url
let remainingUrls = listUrls.slice(index + 1);
if (!remainingUrls.length && loopList) {
remainingUrls = listUrls.slice(0);
}
const nextUrl = remainingUrls && remainingUrls[0];
const remainingUrls = urls.slice(index + 1);
const nextUrl = remainingUrls.find(u => claims[u].value.stream_type && (claims[u].value.stream_type === 'video' || claims[u].value.stream_type === 'audio'));
return nextUrl || null;
} else {
return null;
@ -3790,13 +3739,7 @@ const makeSelectCountForCollectionId = id => reselect.createSelector(makeSelectC
if (collection.itemCount !== undefined) {
return collection.itemCount;
}
let itemCount = 0;
collection.items.map(item => {
if (item) {
itemCount += 1;
}
});
return itemCount;
return collection.items.length;
}
return null;
});
@ -3805,9 +3748,6 @@ var _extends$5 = Object.assign || function (target) { for (var i = 1; i < argume
function _asyncToGenerator$1(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
let onChannelConfirmCallback;
let checkPendingInterval;
function doResolveUris(uris, returnCachedClaims = false, resolveReposts = true) {
return (dispatch, getState) => {
const normalizedUris = uris.map(normalizeURI);
@ -4146,7 +4086,7 @@ function doClearChannelErrors() {
};
}
function doCreateChannel(name, amount, optionalParams, onConfirm) {
function doCreateChannel(name, amount, optionalParams, cb) {
return dispatch => {
dispatch({
type: CREATE_CHANNEL_STARTED
@ -4200,7 +4140,7 @@ function doCreateChannel(name, amount, optionalParams, onConfirm) {
claims: [channelClaim]
}
});
dispatch(doCheckPendingClaims(onConfirm));
dispatch(doCheckPendingClaims(cb));
return channelClaim;
}).catch(error => {
dispatch({
@ -4502,15 +4442,11 @@ function doCollectionPublish(options, localId) {
};
}
function doCollectionPublishUpdate(options, isBackgroundUpdate) {
return (dispatch, getState) => {
function doCollectionPublishUpdate(options) {
return dispatch => {
// TODO: implement one click update
const updateParams = isBackgroundUpdate ? {
blocking: true,
claim_id: options.claim_id,
clear_claims: true
} : {
const updateParams = {
bid: creditsToString(options.bid),
title: options.title,
thumbnail_url: options.thumbnail_url,
@ -4520,25 +4456,16 @@ function doCollectionPublishUpdate(options, isBackgroundUpdate) {
locations: [],
blocking: true,
claim_id: options.claim_id,
clear_claims: true,
replace: true
clear_claims: true
};
if (isBackgroundUpdate && updateParams.claim_id) {
const state = getState();
updateParams['claims'] = makeSelectClaimIdsForCollectionId(updateParams.claim_id)(state);
} else if (options.claims) {
updateParams['claims'] = options.claims;
}
if (options.tags) {
updateParams['tags'] = options.tags.map(tag => tag.name);
}
if (options.channel_id) {
updateParams['channel_id'] = options.channel_id;
if (options.claims) {
updateParams['claims'] = options.claims;
}
return new Promise(resolve => {
dispatch({
type: COLLECTION_PUBLISH_UPDATE_STARTED
@ -4563,6 +4490,7 @@ function doCollectionPublishUpdate(options, isBackgroundUpdate) {
}
});
dispatch(doCheckPendingClaims());
dispatch(doFetchCollectionListMine(1, 10));
return resolve(collectionClaim);
}
@ -4642,63 +4570,48 @@ function doPurchaseList(page = 1, pageSize = PAGE_SIZE) {
};
}
const doCheckPendingClaims = onChannelConfirmed => (dispatch, getState) => {
if (onChannelConfirmed) {
onChannelConfirmCallback = onChannelConfirmed;
}
clearInterval(checkPendingInterval);
const checkTxoList = () => {
const doCheckPendingClaims = onConfirmed => (dispatch, getState) => {
let claimCheckInterval;
const checkClaimList = () => {
const state = getState();
const pendingById = Object.assign({}, selectPendingClaimsById(state));
const pendingTxos = Object.values(pendingById).map(p => p.txid);
// use collections
const pendingIdSet = new Set(selectPendingIds(state));
const pendingCollections = selectPendingCollections(state);
if (pendingTxos.length) {
lbryProxy.txo_list({ txid: pendingTxos }).then(result => {
const txos = result.items;
const idsToConfirm = [];
txos.forEach(txo => {
if (txo.claim_id && txo.confirmations > 0) {
idsToConfirm.push(txo.claim_id);
delete pendingById[txo.claim_id];
lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => {
const claims = result.items;
const claimsToConfirm = [];
claims.forEach(claim => {
const { claim_id: claimId } = claim;
if (claim.confirmations > 0 && pendingIdSet.has(claimId)) {
pendingIdSet.delete(claimId);
if (Object.keys(pendingCollections).includes(claim.claim_id)) {
dispatch(doFetchItemsInCollection({ collectionId: claim.claim_id }));
dispatch(doCollectionDelete(claim.claim_id, 'pending'));
}
claimsToConfirm.push(claim);
if (onConfirmed) {
onConfirmed(claim);
}
});
return { idsToConfirm, pendingById };
}).then(results => {
const { idsToConfirm, pendingById } = results;
if (idsToConfirm.length) {
return lbryProxy.claim_list({ claim_id: idsToConfirm, resolve: true }).then(results => {
const claims = results.items;
const collectionIds = claims.filter(c => c.value_type === 'collection').map(c => c.claim_id);
dispatch({
type: UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claims,
pending: pendingById
}
});
if (collectionIds.length) {
dispatch(doFetchItemsInCollections({
collectionIds
}));
}
const channelClaims = claims.filter(claim => claim.value_type === 'channel');
if (channelClaims.length && onChannelConfirmCallback) {
channelClaims.forEach(claim => onChannelConfirmCallback(claim));
}
if (Object.keys(pendingById).length === 0) {
clearInterval(checkPendingInterval);
}
});
}
});
} else {
clearInterval(checkPendingInterval);
}
if (claimsToConfirm.length) {
dispatch({
type: UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claimsToConfirm
}
});
}
return pendingIdSet.size;
}).then(len => {
if (!len) {
clearInterval(claimCheckInterval);
}
});
};
// do something with onConfirmed (typically get blocklist for channel)
checkPendingInterval = setInterval(() => {
checkTxoList();
claimCheckInterval = setInterval(() => {
checkClaimList();
}, 30000);
};
@ -4708,7 +4621,7 @@ const getTimestamp = () => {
return Math.floor(Date.now() / 1000);
};
const FETCH_BATCH_SIZE = 50;
const FETCH_BATCH_SIZE = 10;
const doLocalCollectionCreate = (name, collectionItems, type, sourceId) => dispatch => {
return dispatch({
@ -4815,8 +4728,7 @@ const doFetchItemsInCollections = (resolveItemsOptions, resolveStartedCallback)
batches[i] = lbryProxy.claim_search({
claim_ids: claim.value.claims,
page: i + 1,
page_size: batchSize,
no_totals: true
page_size: batchSize
});
}
const itemsInBatches = yield Promise.all(batches);
@ -5633,7 +5545,7 @@ const doUpdatePublishForm = publishFormValue => dispatch => dispatch({
data: _extends$7({}, publishFormValue)
});
const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path, cb) => dispatch => {
const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => {
const downMessage = __('Thumbnail upload service may be down, try again later.');
let thumbnail, fileExt, fileName, fileType;
@ -5667,17 +5579,13 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path, cb) =>
method: 'POST',
body: data
}).then(res => res.text()).then(text => text.length ? JSON.parse(text) : {}).then(json => {
if (!json.success) return uploadError(json.message || downMessage);
if (cb) {
cb(json.data.serveUrl);
}
return dispatch({
return json.success ? dispatch({
type: UPDATE_PUBLISH_FORM,
data: {
uploadThumbnailStatus: COMPLETE,
thumbnail: json.data.serveUrl
}
});
}) : uploadError(json.message || downMessage);
}).catch(err => {
let message = err.message;
@ -6093,7 +6001,7 @@ const defaultState = {
fetchingMyChannels: false,
fetchingMyCollections: false,
abandoningById: {},
pendingById: {},
pendingIds: [],
reflectingById: {},
claimSearchError: false,
claimSearchByQuery: {},
@ -6127,7 +6035,7 @@ function handleClaimAction(state, action) {
const byUri = Object.assign({}, state.claimsByUri);
const byId = Object.assign({}, state.byId);
const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
const pendingById = state.pendingById;
const pendingIds = state.pendingIds;
let newResolvingUrls = new Set(state.resolvingUris);
let myClaimIds = new Set(state.myClaims);
@ -6137,7 +6045,7 @@ function handleClaimAction(state, action) {
const channel = channelFromResolve || stream && stream.signing_channel;
if (stream) {
if (pendingById[stream.claim_id]) {
if (pendingIds.includes(stream.claim_id)) {
byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]);
} else {
byId[stream.claim_id] = stream;
@ -6167,7 +6075,7 @@ function handleClaimAction(state, action) {
channelClaimCounts[channel.canonical_url] = claimsInChannel;
}
if (pendingById[channel.claim_id]) {
if (pendingIds.includes(channel.claim_id)) {
byId[channel.claim_id] = mergeClaims(channel, byId[channel.claim_id]);
} else {
byId[channel.claim_id] = channel;
@ -6180,7 +6088,7 @@ function handleClaimAction(state, action) {
}
if (collection) {
if (pendingById[collection.claim_id]) {
if (pendingIds.includes(collection.claim_id)) {
byId[collection.claim_id] = mergeClaims(collection, byId[collection.claim_id]);
} else {
byId[collection.claim_id] = collection;
@ -6197,7 +6105,7 @@ function handleClaimAction(state, action) {
}
newResolvingUrls.delete(url);
if (!stream && !channel && !collection && !pendingById[byUri[url]]) {
if (!stream && !channel && !collection && !pendingIds.includes(byUri[url])) {
byUri[url] = null;
}
});
@ -6237,33 +6145,34 @@ reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, {
});
reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
const { result } = action.data;
const { result, resolve } = action.data;
const claims = result.items;
const page = result.page;
const totalItems = result.total_items;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myClaimIds = new Set(state.myClaims);
let urlsForCurrentPage = [];
const pendingIdSet = new Set(pendingIds);
claims.forEach(claim => {
const { permanent_url: permanentUri, claim_id: claimId, canonical_url: canonicalUri } = claim;
const { permanent_url: permanentUri, claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) {
urlsForCurrentPage.push(permanentUri);
if (claim.confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaims(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
pendingIdSet.add(claimId);
} else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) {
pendingIdSet.delete(claimId);
}
if (pendingIds.includes(claimId)) {
byId[claimId] = mergeClaims(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
byUri[permanentUri] = claimId;
byUri[canonicalUri] = claimId;
myClaimIds.add(claimId);
}
});
@ -6272,7 +6181,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
isFetchingClaimListMine: false,
myClaims: Array.from(myClaimIds),
byId,
pendingById,
pendingIds: Array.from(pendingIdSet),
claimsByUri: byUri,
myClaimsPageResults: urlsForCurrentPage,
myClaimsPageNumber: page,
@ -6284,8 +6193,9 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch
reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
const { claims } = action.data;
const myClaims = state.myClaims || [];
let myClaimIds = new Set(state.myClaims);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myChannelClaims;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
@ -6298,12 +6208,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
myChannelClaims = new Set(state.myChannelClaims);
claims.forEach(claim => {
const { claims_in_channel: claimsInChannel } = claim.meta;
const {
canonical_url: canonicalUrl,
permanent_url: permanentUrl,
claim_id: claimId,
confirmations
} = claim;
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim;
byUri[canonicalUrl] = claimId;
byUri[permanentUrl] = claimId;
@ -6312,14 +6217,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
// $FlowFixMe
myChannelClaims.add(claimId);
if (confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaims(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
} else {
if (!pendingIds.some(c => c === claimId)) {
byId[claimId] = claim;
}
myClaimIds.add(claimId);
@ -6328,7 +6226,6 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
return Object.assign({}, state, {
byId,
pendingById,
claimsByUri: byUri,
channelClaimCounts,
fetchingMyChannels: false,
@ -6351,7 +6248,7 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
const { claims } = action.data;
const myClaims = state.myClaims || [];
let myClaimIds = new Set(myClaims);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myCollectionClaimsSet = new Set([]);
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
@ -6359,12 +6256,7 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
if (claims.length) {
myCollectionClaimsSet = new Set(state.myCollectionClaims);
claims.forEach(claim => {
const {
canonical_url: canonicalUrl,
permanent_url: permanentUrl,
claim_id: claimId,
confirmations
} = claim;
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim;
byUri[canonicalUrl] = claimId;
byUri[permanentUrl] = claimId;
@ -6372,14 +6264,7 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
// $FlowFixMe
myCollectionClaimsSet.add(claimId);
// we don't want to overwrite a pending result with a resolve
if (confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaims(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
} else {
if (!pendingIds.some(c => c === claimId)) {
byId[claimId] = claim;
}
myClaimIds.add(claimId);
@ -6388,7 +6273,6 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
return _extends$9({}, state, {
byId,
pendingById,
claimsByUri: byUri,
fetchingMyCollections: false,
myCollectionClaims: Array.from(myCollectionClaimsSet),
@ -6474,8 +6358,9 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => {
reducers[UPDATE_PENDING_CLAIMS] = (state, action) => {
const { claims: pendingClaims } = action.data;
const byId = Object.assign({}, state.byId);
const pendingById = Object.assign({}, state.pendingById);
const byUri = Object.assign({}, state.claimsByUri);
const pendingIds = state.pendingIds;
const pendingIdSet = new Set(pendingIds);
let myClaimIds = new Set(state.myClaims);
const myChannelClaims = new Set(state.myChannelClaims);
@ -6483,7 +6368,7 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => {
pendingClaims.forEach(claim => {
let newClaim;
const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim;
pendingById[claimId] = claim; // make sure we don't need to merge?
pendingIdSet.add(claimId);
const oldClaim = byId[claimId];
if (oldClaim && oldClaim.canonical_url) {
newClaim = mergeClaims(oldClaim, claim);
@ -6503,22 +6388,21 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => {
return Object.assign({}, state, {
myClaims: Array.from(myClaimIds),
byId,
pendingById,
myChannelClaims: Array.from(myChannelClaims),
claimsByUri: byUri
claimsByUri: byUri,
pendingIds: Array.from(pendingIdSet)
});
};
reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => {
const {
claims: confirmedClaims,
pending: pendingClaims
} = action.data;
const { claims: confirmedClaims } = action.data;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
//
const pendingIds = state.pendingIds;
const pendingIdSet = new Set(pendingIds);
confirmedClaims.forEach(claim => {
const { claim_id: claimId, type } = claim;
const { permanent_url: permanentUri, claim_id: claimId, type } = claim;
let newClaim = claim;
const oldClaim = byId[claimId];
if (oldClaim && oldClaim.canonical_url) {
@ -6526,10 +6410,11 @@ reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => {
}
if (type && type.match(/claim|update|channel/)) {
byId[claimId] = newClaim;
pendingIdSet.delete(claimId);
}
});
return Object.assign({}, state, {
pendingById: pendingClaims,
pendingIds: Array.from(pendingIdSet),
byId,
claimsByUri: byUri
});
@ -7772,15 +7657,8 @@ const collectionsReducer = handleActions({
[COLLECTION_PENDING]: (state, action) => {
const { localId, claimId } = action.data;
const {
resolved: resolvedList,
edited: editList,
unpublished: unpublishedList,
pending: pendingList
} = state;
const { edited: editList, unpublished: unpublishedList, pending: pendingList } = state;
const newEditList = Object.assign({}, editList);
const newResolvedList = Object.assign({}, resolvedList);
const newUnpublishedList = Object.assign({}, unpublishedList);
const newPendingList = Object.assign({}, pendingList);
@ -7790,7 +7668,7 @@ const collectionsReducer = handleActions({
delete newUnpublishedList[localId];
} else {
// edit update
newPendingList[claimId] = Object.assign({}, newEditList[claimId] || newResolvedList[claimId]);
newPendingList[claimId] = Object.assign({}, newEditList[claimId]);
delete newEditList[claimId];
}
@ -7842,14 +7720,8 @@ const collectionsReducer = handleActions({
}));
},
[USER_STATE_POPULATE]: (state, action) => {
const {
builtinCollections,
savedCollections,
unpublishedCollections,
editedCollections
} = action.data;
const { builtinCollections, savedCollections, unpublishedCollections } = action.data;
return _extends$e({}, state, {
edited: editedCollections || state.edited,
unpublished: unpublishedCollections || state.unpublished,
builtin: builtinCollections || state.builtin,
saved: savedCollections || state.saved
@ -8049,7 +7921,6 @@ exports.formatFullPrice = formatFullPrice;
exports.isClaimNsfw = isClaimNsfw;
exports.isNameValid = isNameValid;
exports.isURIClaimable = isURIClaimable;
exports.isURIEqual = isURIEqual;
exports.isURIValid = isURIValid;
exports.makeSelectAbandoningClaimById = makeSelectAbandoningClaimById;
exports.makeSelectAmountForUri = makeSelectAmountForUri;
@ -8066,8 +7937,8 @@ exports.makeSelectClaimIsMine = makeSelectClaimIsMine;
exports.makeSelectClaimIsNsfw = makeSelectClaimIsNsfw;
exports.makeSelectClaimIsPending = makeSelectClaimIsPending;
exports.makeSelectClaimIsStreamPlaceholder = makeSelectClaimIsStreamPlaceholder;
exports.makeSelectClaimUrlInCollection = makeSelectClaimUrlInCollection;
exports.makeSelectClaimWasPurchased = makeSelectClaimWasPurchased;
exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState;
exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage;
exports.makeSelectCollectionForId = makeSelectCollectionForId;
exports.makeSelectCollectionForIdHasClaimUrl = makeSelectCollectionForIdHasClaimUrl;
@ -8101,13 +7972,13 @@ exports.makeSelectMyPurchasesForPage = makeSelectMyPurchasesForPage;
exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage;
exports.makeSelectNameForCollectionId = makeSelectNameForCollectionId;
exports.makeSelectNextUrlForCollectionAndUrl = makeSelectNextUrlForCollectionAndUrl;
exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel;
exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris;
exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel;
exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri;
exports.makeSelectPendingClaimForUri = makeSelectPendingClaimForUri;
exports.makeSelectPendingCollectionForId = makeSelectPendingCollectionForId;
exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri;
exports.makeSelectPreviousUrlForCollectionAndUrl = makeSelectPreviousUrlForCollectionAndUrl;
exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
exports.makeSelectPublishedCollectionForId = makeSelectPublishedCollectionForId;
exports.makeSelectReflectingClaimForUri = makeSelectReflectingClaimForUri;
@ -8267,6 +8138,5 @@ exports.selectWalletState = selectWalletState;
exports.selectWalletUnlockPending = selectWalletUnlockPending;
exports.selectWalletUnlockResult = selectWalletUnlockResult;
exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded;
exports.splitBySeparator = splitBySeparator;
exports.toQueryString = toQueryString;
exports.walletReducer = walletReducer;

View file

@ -75,7 +75,7 @@ declare type BalanceResponse = {
declare type ResolveResponse = {
// Keys are the url(s) passed to resolve
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, collection?: CollectionClaim, claimsInChannel?: number },
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number },
};
declare type GetResponse = FileListItem & { error?: string };
@ -351,7 +351,6 @@ declare type LbryTypes = {
address_unused: (params: {}) => Promise<string>, // New address
address_list: (params: {}) => Promise<string>,
transaction_list: (params: {}) => Promise<TxListResponse>,
txo_list: (params: {}) => Promise<any>,
// Sync
sync_hash: (params: {}) => Promise<string>,

View file

@ -1,5 +0,0 @@
// @flow
declare module '@ungap/from-entries' {
declare module.exports: any;
}

3
flow-typed/Lbry.js vendored
View file

@ -75,7 +75,7 @@ declare type BalanceResponse = {
declare type ResolveResponse = {
// Keys are the url(s) passed to resolve
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, collection?: CollectionClaim, claimsInChannel?: number },
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number },
};
declare type GetResponse = FileListItem & { error?: string };
@ -351,7 +351,6 @@ declare type LbryTypes = {
address_unused: (params: {}) => Promise<string>, // New address
address_list: (params: {}) => Promise<string>,
transaction_list: (params: {}) => Promise<TxListResponse>,
txo_list: (params: {}) => Promise<any>,
// Sync
sync_hash: (params: {}) => Promise<string>,

View file

@ -1,5 +0,0 @@
// @flow
declare module '@ungap/from-entries' {
declare module.exports: any;
}

View file

@ -29,7 +29,6 @@
"test": "jest"
},
"dependencies": {
"@ungap/from-entries": "^0.2.1",
"proxy-polyfill": "0.1.6",
"reselect": "^3.0.0",
"uuid": "^8.3.1"

View file

@ -23,7 +23,7 @@ export const INSTANT_PURCHASE_MAX = 'instant_purchase_max';
export const THEME = 'theme';
export const THEMES = 'themes';
export const AUTOMATIC_DARK_MODE_ENABLED = 'automatic_dark_mode_enabled';
export const AUTOPLAY_MEDIA = 'autoplay';
export const AUTOPLAY = 'autoplay';
export const AUTOPLAY_NEXT = 'autoplay_next';
export const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
export const AUTO_DOWNLOAD = 'auto_download';
@ -39,8 +39,6 @@ export const ENABLE_PUBLISH_PREVIEW = 'enable-publish-preview';
export const TILE_LAYOUT = 'tile_layout';
export const VIDEO_THEATER_MODE = 'video_theater_mode';
export const VIDEO_PLAYBACK_RATE = 'video_playback_rate';
export const CUSTOM_COMMENTS_SERVER_ENABLED = 'custom_comments_server_enabled';
export const CUSTOM_COMMENTS_SERVER_URL = 'custom_comments_server_url';
// mobile settings
export const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled';

View file

@ -21,12 +21,10 @@ export const CLIENT_SYNC_KEYS = [
SETTINGS.INSTANT_PURCHASE_ENABLED,
SETTINGS.INSTANT_PURCHASE_MAX,
SETTINGS.THEME,
SETTINGS.AUTOPLAY_MEDIA,
SETTINGS.AUTOPLAY_NEXT,
SETTINGS.AUTOPLAY,
SETTINGS.HIDE_BALANCE,
SETTINGS.HIDE_SPLASH_ANIMATION,
SETTINGS.FLOATING_PLAYER,
SETTINGS.DARK_MODE_TIMES,
SETTINGS.AUTOMATIC_DARK_MODE_ENABLED,
SETTINGS.LANGUAGE,
];

View file

@ -52,8 +52,6 @@ export {
isURIClaimable,
isNameValid,
convertToShareLink,
splitBySeparator,
isURIEqual,
} from 'lbryURI';
// middlware
@ -176,14 +174,12 @@ export {
makeSelectMyPublishedCollectionForId,
makeSelectUnpublishedCollectionForId,
makeSelectCollectionForId,
makeSelectClaimUrlInCollection,
makeSelectUrlsForCollectionId,
makeSelectClaimIdsForCollectionId,
makeSelectNameForCollectionId,
makeSelectCountForCollectionId,
makeSelectIsResolvingCollectionForId,
makeSelectIndexForUrlInCollection,
makeSelectPreviousUrlForCollectionAndUrl,
makeSelectNextUrlForCollectionAndUrl,
makeSelectCollectionForIdHasClaimUrl,
} from 'redux/selectors/collections';
@ -213,6 +209,7 @@ export {
makeSelectTotalItemsForChannel,
makeSelectTotalPagesForChannel,
makeSelectNsfwCountFromUris,
makeSelectNsfwCountForChannel,
makeSelectOmittedCountForChannel,
makeSelectClaimIsNsfw,
makeSelectChannelForClaimUri,
@ -220,6 +217,7 @@ export {
makeSelectMyChannelPermUrlForName,
makeSelectClaimIsPending,
makeSelectReflectingClaimForUri,
makeSelectClaimsInChannelForCurrentPageState,
makeSelectShortUrlForUri,
makeSelectCanonicalUrlForUri,
makeSelectPermanentUrlForUri,

View file

@ -117,7 +117,6 @@ const Lbry: LbryTypes = {
utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params),
support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params),
purchase_list: (params = {}) => daemonCallWithResult('purchase_list', params),
txo_list: (params = {}) => daemonCallWithResult('txo_list', params),
sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params),
sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params),

View file

@ -4,7 +4,7 @@ const channelNameMinLength = 1;
const claimIdMaxLength = 40;
// see https://spec.lbry.com/#urls
export const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u;
export const regexInvalidURI = /[ =&#:$@%?;/\\"<>%\{\}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u;
export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/;
const regexPartProtocol = '^((?:lbry://)?)';
const regexPartStreamOrChannelName = '([^:$#/]*)';
@ -12,11 +12,6 @@ const regexPartModifierSeparator = '([:$#]?)([^/]*)';
const queryStringBreaker = '^([\\S]+)([?][\\S]*)';
const separateQuerystring = new RegExp(queryStringBreaker);
const MOD_SEQUENCE_SEPARATOR = '*';
const MOD_CLAIM_ID_SEPARATOR_OLD = '#';
const MOD_CLAIM_ID_SEPARATOR = ':';
const MOD_BID_POSITION_SEPARATOR = '$';
/**
* Parses a LBRY name into its component parts. Throws errors with user-friendly
* messages for invalid names.
@ -149,11 +144,11 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) {
throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator }));
}
if (modSeperator === MOD_CLAIM_ID_SEPARATOR || MOD_CLAIM_ID_SEPARATOR_OLD) {
if (modSeperator === '#') {
claimId = modValue;
} else if (modSeperator === MOD_SEQUENCE_SEPARATOR) {
} else if (modSeperator === ':') {
claimSequence = modValue;
} else if (modSeperator === MOD_BID_POSITION_SEPARATOR) {
} else if (modSeperator === '$') {
bidPosition = modValue;
}
}
@ -325,22 +320,3 @@ export function convertToShareLink(URL: string) {
'https://open.lbry.com/'
);
}
export function splitBySeparator(uri: string) {
const protocolLength = 7;
return uri.startsWith('lbry://') ? uri.slice(protocolLength).split(/[#:*]/) : uri.split(/#:\*\$/);
}
export function isURIEqual(uriA: string, uriB: string) {
const parseA = parseURI(normalizeURI(uriA));
const parseB = parseURI(normalizeURI(uriB));
if (parseA.isChannel) {
if (parseB.isChannel && parseA.channelClaimId === parseB.channelClaimId) {
return true;
}
} else if (parseA.streamClaimId === parseB.streamClaimId) {
return true;
} else {
return false;
}
}

View file

@ -10,7 +10,6 @@ import {
selectClaimsByUri,
selectMyChannelClaims,
selectPendingIds,
selectPendingClaimsById,
} from 'redux/selectors/claims';
import { doFetchTxoPage } from 'redux/actions/wallet';
@ -21,7 +20,6 @@ import { createNormalizedClaimSearchKey } from 'util/claim';
import { PAGE_SIZE } from 'constants/claim';
import {
selectPendingCollections,
makeSelectClaimIdsForCollectionId,
} from 'redux/selectors/collections';
import {
doFetchItemsInCollection,
@ -29,9 +27,6 @@ import {
doCollectionDelete,
} from 'redux/actions/collections';
let onChannelConfirmCallback;
let checkPendingInterval;
export function doResolveUris(
uris: Array<string>,
returnCachedClaims: boolean = false,
@ -407,7 +402,7 @@ export function doClearChannelErrors() {
};
}
export function doCreateChannel(name: string, amount: number, optionalParams: any, onConfirm: any) {
export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) {
return (dispatch: Dispatch) => {
dispatch({
type: ACTIONS.CREATE_CHANNEL_STARTED,
@ -474,7 +469,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an
claims: [channelClaim],
},
});
dispatch(doCheckPendingClaims(onConfirm));
dispatch(doCheckPendingClaims(cb));
return channelClaim;
})
.catch(error => {
@ -831,22 +826,18 @@ export function doCollectionPublish(
};
}
export function doCollectionPublishUpdate(
options: {
bid?: string,
blocking?: true,
title?: string,
thumbnail_url?: string,
description?: string,
claim_id: string,
tags?: Array<Tag>,
languages?: Array<string>,
claims?: Array<string>,
channel_id?: string,
},
isBackgroundUpdate?: boolean
) {
return (dispatch: Dispatch, getState: GetState): Promise<any> => {
export function doCollectionPublishUpdate(options: {
bid?: string,
blocking?: true,
title?: string,
thumbnail_url?: string,
description?: string,
claim_id: string,
tags?: Array<Tag>,
languages?: Array<string>,
claims?: Array<string>,
}) {
return (dispatch: Dispatch): Promise<any> => {
// TODO: implement one click update
const updateParams: {
@ -854,49 +845,32 @@ export function doCollectionPublishUpdate(
blocking?: true,
title?: string,
thumbnail_url?: string,
channel_id?: string,
description?: string,
claim_id: string,
tags?: Array<string>,
languages?: Array<string>,
claims?: Array<string>,
clear_claims: boolean,
replace?: boolean,
} = isBackgroundUpdate
? {
blocking: true,
claim_id: options.claim_id,
clear_claims: true,
}
: {
bid: creditsToString(options.bid),
title: options.title,
thumbnail_url: options.thumbnail_url,
description: options.description,
tags: [],
languages: options.languages || [],
locations: [],
blocking: true,
claim_id: options.claim_id,
clear_claims: true,
replace: true,
};
if (isBackgroundUpdate && updateParams.claim_id) {
const state = getState();
updateParams['claims'] = makeSelectClaimIdsForCollectionId(updateParams.claim_id)(state);
} else if (options.claims) {
updateParams['claims'] = options.claims;
}
} = {
bid: creditsToString(options.bid),
title: options.title,
thumbnail_url: options.thumbnail_url,
description: options.description,
tags: [],
languages: options.languages || [],
locations: [],
blocking: true,
claim_id: options.claim_id,
clear_claims: true,
};
if (options.tags) {
updateParams['tags'] = options.tags.map(tag => tag.name);
}
if (options.channel_id) {
updateParams['channel_id'] = options.channel_id;
if (options.claims) {
updateParams['claims'] = options.claims;
}
return new Promise(resolve => {
dispatch({
type: ACTIONS.COLLECTION_PUBLISH_UPDATE_STARTED,
@ -921,6 +895,7 @@ export function doCollectionPublishUpdate(
},
});
dispatch(doCheckPendingClaims());
dispatch(doFetchCollectionListMine(1, 10));
return resolve(collectionClaim);
}
@ -1000,71 +975,52 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) {
};
}
export const doCheckPendingClaims = (onChannelConfirmed: Function) => (
export const doCheckPendingClaims = (onConfirmed: Function) => (
dispatch: Dispatch,
getState: GetState
) => {
if (onChannelConfirmed) {
onChannelConfirmCallback = onChannelConfirmed;
}
clearInterval(checkPendingInterval);
const checkTxoList = () => {
let claimCheckInterval;
const checkClaimList = () => {
const state = getState();
const pendingById = Object.assign({}, selectPendingClaimsById(state));
const pendingTxos = (Object.values(pendingById): any).map(p => p.txid);
// use collections
const pendingIdSet = new Set(selectPendingIds(state));
const pendingCollections = selectPendingCollections(state);
if (pendingTxos.length) {
Lbry.txo_list({ txid: pendingTxos })
.then(result => {
const txos = result.items;
const idsToConfirm = [];
txos.forEach(txo => {
if (txo.claim_id && txo.confirmations > 0) {
idsToConfirm.push(txo.claim_id);
delete pendingById[txo.claim_id];
Lbry.claim_list({ page: 1, page_size: 10 })
.then(result => {
const claims = result.items;
const claimsToConfirm = [];
claims.forEach(claim => {
const { claim_id: claimId } = claim;
if (claim.confirmations > 0 && pendingIdSet.has(claimId)) {
pendingIdSet.delete(claimId);
if (Object.keys(pendingCollections).includes(claim.claim_id)) {
dispatch(doFetchItemsInCollection({ collectionId: claim.claim_id }));
dispatch(doCollectionDelete(claim.claim_id, 'pending'));
}
claimsToConfirm.push(claim);
if (onConfirmed) {
onConfirmed(claim);
}
});
return { idsToConfirm, pendingById };
})
.then(results => {
const { idsToConfirm, pendingById } = results;
if (idsToConfirm.length) {
return Lbry.claim_list({ claim_id: idsToConfirm, resolve: true }).then(results => {
const claims = results.items;
const collectionIds = claims
.filter(c => c.value_type === 'collection')
.map(c => c.claim_id);
dispatch({
type: ACTIONS.UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claims,
pending: pendingById,
},
});
if (collectionIds.length) {
dispatch(
doFetchItemsInCollections({
collectionIds,
})
);
}
const channelClaims = claims.filter(claim => claim.value_type === 'channel');
if (channelClaims.length && onChannelConfirmCallback) {
channelClaims.forEach(claim => onChannelConfirmCallback(claim));
}
if (Object.keys(pendingById).length === 0) {
clearInterval(checkPendingInterval);
}
});
}
});
} else {
clearInterval(checkPendingInterval);
}
if (claimsToConfirm.length) {
dispatch({
type: ACTIONS.UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claimsToConfirm,
},
});
}
return pendingIdSet.size;
})
.then(len => {
if (!len) {
clearInterval(claimCheckInterval);
}
});
};
// do something with onConfirmed (typically get blocklist for channel)
checkPendingInterval = setInterval(() => {
checkTxoList();
claimCheckInterval = setInterval(() => {
checkClaimList();
}, 30000);
};

View file

@ -18,7 +18,7 @@ const getTimestamp = () => {
return Math.floor(Date.now() / 1000);
};
const FETCH_BATCH_SIZE = 50;
const FETCH_BATCH_SIZE = 10;
export const doLocalCollectionCreate = (
name: string,
@ -93,7 +93,7 @@ export const doFetchItemsInCollections = (
pageSize?: number,
},
resolveStartedCallback?: () => void
) => async(dispatch: Dispatch, getState: GetState) => {
) => async (dispatch: Dispatch, getState: GetState) => {
/*
1) make sure all the collection claims are loaded into claims reducer, search/resolve if necessary.
2) get the item claims for each
@ -165,7 +165,6 @@ export const doFetchItemsInCollections = (
claim_ids: claim.value.claims,
page: i + 1,
page_size: batchSize,
no_totals: true,
});
}
const itemsInBatches = await Promise.all(batches);
@ -319,7 +318,7 @@ export const doFetchItemsInCollection = (
return doFetchItemsInCollections(newOptions, cb);
};
export const doCollectionEdit = (collectionId: string, params: CollectionEditParams) => async(
export const doCollectionEdit = (collectionId: string, params: CollectionEditParams) => async (
dispatch: Dispatch,
getState: GetState
) => {

View file

@ -69,8 +69,7 @@ export const doUploadThumbnail = (
thumbnailBlob?: File,
fsAdapter?: any,
fs?: any,
path?: any,
cb?: (string) => void
path?: any
) => (dispatch: Dispatch) => {
const downMessage = __('Thumbnail upload service may be down, try again later.');
let thumbnail, fileExt, fileName, fileType;
@ -113,17 +112,15 @@ export const doUploadThumbnail = (
.then(res => res.text())
.then(text => (text.length ? JSON.parse(text) : {}))
.then(json => {
if (!json.success) return uploadError(json.message || downMessage);
if (cb) {
cb(json.data.serveUrl);
}
return dispatch({
type: ACTIONS.UPDATE_PUBLISH_FORM,
data: {
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
thumbnail: json.data.serveUrl,
},
});
return json.success
? dispatch({
type: ACTIONS.UPDATE_PUBLISH_FORM,
data: {
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
thumbnail: json.data.serveUrl,
},
})
: uploadError(json.message || downMessage);
})
.catch(err => {
let message = err.message;

View file

@ -14,7 +14,6 @@ type SharedData = {
app_welcome_version?: number,
sharing_3P?: boolean,
unpublishedCollections: CollectionGroup,
editedCollections: CollectionGroup,
builtinCollections: CollectionGroup,
savedCollections: Array<string>,
},
@ -32,7 +31,6 @@ function extractUserState(rawObj: SharedData) {
app_welcome_version,
sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections,
} = rawObj.value;
@ -47,7 +45,6 @@ function extractUserState(rawObj: SharedData) {
...(app_welcome_version ? { app_welcome_version } : {}),
...(sharing_3P ? { sharing_3P } : {}),
...(unpublishedCollections ? { unpublishedCollections } : {}),
...(editedCollections ? { editedCollections } : {}),
...(builtinCollections ? { builtinCollections } : {}),
...(savedCollections ? { savedCollections } : {}),
};
@ -68,7 +65,6 @@ export function doPopulateSharedUserState(sharedSettings: any) {
app_welcome_version,
sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections,
} = extractUserState(sharedSettings);
@ -84,7 +80,6 @@ export function doPopulateSharedUserState(sharedSettings: any) {
welcomeVersion: app_welcome_version,
allowAnalytics: sharing_3P,
unpublishedCollections,
editedCollections,
builtinCollections,
savedCollections,
},

View file

@ -17,8 +17,8 @@ type State = {
channelClaimCounts: { [string]: number },
claimsByUri: { [string]: string },
byId: { [string]: Claim },
pendingById: { [string]: Claim }, // keep pending claims
resolvingUris: Array<string>,
pendingIds: Array<string>,
reflectingById: { [string]: ReflectingUpdate },
myClaims: ?Array<string>,
myChannelClaims: ?Array<string>,
@ -83,7 +83,7 @@ const defaultState = {
fetchingMyChannels: false,
fetchingMyCollections: false,
abandoningById: {},
pendingById: {},
pendingIds: [],
reflectingById: {},
claimSearchError: false,
claimSearchByQuery: {},
@ -117,7 +117,7 @@ function handleClaimAction(state: State, action: any): State {
const byUri = Object.assign({}, state.claimsByUri);
const byId = Object.assign({}, state.byId);
const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
const pendingById = state.pendingById;
const pendingIds = state.pendingIds;
let newResolvingUrls = new Set(state.resolvingUris);
let myClaimIds = new Set(state.myClaims);
@ -127,7 +127,7 @@ function handleClaimAction(state: State, action: any): State {
const channel = channelFromResolve || (stream && stream.signing_channel);
if (stream) {
if (pendingById[stream.claim_id]) {
if (pendingIds.includes(stream.claim_id)) {
byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]);
} else {
byId[stream.claim_id] = stream;
@ -157,7 +157,7 @@ function handleClaimAction(state: State, action: any): State {
channelClaimCounts[channel.canonical_url] = claimsInChannel;
}
if (pendingById[channel.claim_id]) {
if (pendingIds.includes(channel.claim_id)) {
byId[channel.claim_id] = mergeClaim(channel, byId[channel.claim_id]);
} else {
byId[channel.claim_id] = channel;
@ -170,7 +170,7 @@ function handleClaimAction(state: State, action: any): State {
}
if (collection) {
if (pendingById[collection.claim_id]) {
if (pendingIds.includes(collection.claim_id)) {
byId[collection.claim_id] = mergeClaim(collection, byId[collection.claim_id]);
} else {
byId[collection.claim_id] = collection;
@ -187,7 +187,7 @@ function handleClaimAction(state: State, action: any): State {
}
newResolvingUrls.delete(url);
if (!stream && !channel && !collection && !pendingById[byUri[url]]) {
if (!stream && !channel && !collection && !pendingIds.includes(byUri[url])) {
byUri[url] = null;
}
});
@ -230,33 +230,34 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State =>
});
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => {
const { result }: { result: ClaimListResponse } = action.data;
const { result, resolve }: { result: ClaimListResponse, resolve: boolean } = action.data;
const claims = result.items;
const page = result.page;
const totalItems = result.total_items;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myClaimIds = new Set(state.myClaims);
let urlsForCurrentPage = [];
const pendingIdSet = new Set(pendingIds);
claims.forEach((claim: Claim) => {
const { permanent_url: permanentUri, claim_id: claimId, canonical_url: canonicalUri } = claim;
const { permanent_url: permanentUri, claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) {
urlsForCurrentPage.push(permanentUri);
if (claim.confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaim(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
pendingIdSet.add(claimId);
} else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) {
pendingIdSet.delete(claimId);
}
if (pendingIds.includes(claimId)) {
byId[claimId] = mergeClaim(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
byUri[permanentUri] = claimId;
byUri[canonicalUri] = claimId;
myClaimIds.add(claimId);
}
});
@ -265,7 +266,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any):
isFetchingClaimListMine: false,
myClaims: Array.from(myClaimIds),
byId,
pendingById,
pendingIds: Array.from(pendingIdSet),
claimsByUri: byUri,
myClaimsPageResults: urlsForCurrentPage,
myClaimsPageNumber: page,
@ -278,8 +279,9 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State =>
reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => {
const { claims }: { claims: Array<ChannelClaim> } = action.data;
const myClaims = state.myClaims || [];
let myClaimIds = new Set(state.myClaims);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myChannelClaims;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
@ -293,12 +295,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
claims.forEach(claim => {
const { meta } = claim;
const { claims_in_channel: claimsInChannel } = claim.meta;
const {
canonical_url: canonicalUrl,
permanent_url: permanentUrl,
claim_id: claimId,
confirmations,
} = claim;
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim;
byUri[canonicalUrl] = claimId;
byUri[permanentUrl] = claimId;
@ -307,14 +304,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
// $FlowFixMe
myChannelClaims.add(claimId);
if (confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaim(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
} else {
if (!pendingIds.some(c => c === claimId)) {
byId[claimId] = claim;
}
myClaimIds.add(claimId);
@ -323,7 +313,6 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
return Object.assign({}, state, {
byId,
pendingById,
claimsByUri: byUri,
channelClaimCounts,
fetchingMyChannels: false,
@ -347,7 +336,7 @@ reducers[ACTIONS.FETCH_COLLECTION_LIST_COMPLETED] = (state: State, action: any):
const { claims }: { claims: Array<CollectionClaim> } = action.data;
const myClaims = state.myClaims || [];
let myClaimIds = new Set(myClaims);
const pendingById = Object.assign({}, state.pendingById);
const pendingIds = state.pendingIds || [];
let myCollectionClaimsSet = new Set([]);
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
@ -356,12 +345,7 @@ reducers[ACTIONS.FETCH_COLLECTION_LIST_COMPLETED] = (state: State, action: any):
myCollectionClaimsSet = new Set(state.myCollectionClaims);
claims.forEach(claim => {
const { meta } = claim;
const {
canonical_url: canonicalUrl,
permanent_url: permanentUrl,
claim_id: claimId,
confirmations,
} = claim;
const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim;
byUri[canonicalUrl] = claimId;
byUri[permanentUrl] = claimId;
@ -369,14 +353,7 @@ reducers[ACTIONS.FETCH_COLLECTION_LIST_COMPLETED] = (state: State, action: any):
// $FlowFixMe
myCollectionClaimsSet.add(claimId);
// we don't want to overwrite a pending result with a resolve
if (confirmations < 1) {
pendingById[claimId] = claim;
if (byId[claimId]) {
byId[claimId] = mergeClaim(claim, byId[claimId]);
} else {
byId[claimId] = claim;
}
} else {
if (!pendingIds.some(c => c === claimId)) {
byId[claimId] = claim;
}
myClaimIds.add(claimId);
@ -386,7 +363,6 @@ reducers[ACTIONS.FETCH_COLLECTION_LIST_COMPLETED] = (state: State, action: any):
return {
...state,
byId,
pendingById,
claimsByUri: byUri,
fetchingMyCollections: false,
myCollectionClaims: Array.from(myCollectionClaimsSet),
@ -479,8 +455,9 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State =>
reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => {
const { claims: pendingClaims }: { claims: Array<Claim> } = action.data;
const byId = Object.assign({}, state.byId);
const pendingById = Object.assign({}, state.pendingById);
const byUri = Object.assign({}, state.claimsByUri);
const pendingIds = state.pendingIds;
const pendingIdSet = new Set(pendingIds);
let myClaimIds = new Set(state.myClaims);
const myChannelClaims = new Set(state.myChannelClaims);
@ -488,7 +465,7 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State =>
pendingClaims.forEach((claim: Claim) => {
let newClaim;
const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim;
pendingById[claimId] = claim; // make sure we don't need to merge?
pendingIdSet.add(claimId);
const oldClaim = byId[claimId];
if (oldClaim && oldClaim.canonical_url) {
newClaim = mergeClaim(oldClaim, claim);
@ -508,22 +485,21 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State =>
return Object.assign({}, state, {
myClaims: Array.from(myClaimIds),
byId,
pendingById,
myChannelClaims: Array.from(myChannelClaims),
claimsByUri: byUri,
pendingIds: Array.from(pendingIdSet),
});
};
reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => {
const {
claims: confirmedClaims,
pending: pendingClaims,
}: { claims: Array<Claim>, pending: { [string]: Claim } } = action.data;
const { claims: confirmedClaims }: { claims: Array<Claim> } = action.data;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
//
const pendingIds = state.pendingIds;
const pendingIdSet = new Set(pendingIds);
confirmedClaims.forEach((claim: GenericClaim) => {
const { claim_id: claimId, type } = claim;
const { permanent_url: permanentUri, claim_id: claimId, type } = claim;
let newClaim = claim;
const oldClaim = byId[claimId];
if (oldClaim && oldClaim.canonical_url) {
@ -531,10 +507,11 @@ reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State =
}
if (type && type.match(/claim|update|channel/)) {
byId[claimId] = newClaim;
pendingIdSet.delete(claimId);
}
});
return Object.assign({}, state, {
pendingById: pendingClaims,
pendingIds: Array.from(pendingIdSet),
byId,
claimsByUri: byUri,
});

View file

@ -90,15 +90,8 @@ const collectionsReducer = handleActions(
[ACTIONS.COLLECTION_PENDING]: (state, action) => {
const { localId, claimId } = action.data;
const {
resolved: resolvedList,
edited: editList,
unpublished: unpublishedList,
pending: pendingList,
} = state;
const { edited: editList, unpublished: unpublishedList, pending: pendingList } = state;
const newEditList = Object.assign({}, editList);
const newResolvedList = Object.assign({}, resolvedList);
const newUnpublishedList = Object.assign({}, unpublishedList);
const newPendingList = Object.assign({}, pendingList);
@ -108,10 +101,7 @@ const collectionsReducer = handleActions(
delete newUnpublishedList[localId];
} else {
// edit update
newPendingList[claimId] = Object.assign(
{},
newEditList[claimId] || newResolvedList[claimId]
);
newPendingList[claimId] = Object.assign({}, newEditList[claimId]);
delete newEditList[claimId];
}
@ -168,15 +158,9 @@ const collectionsReducer = handleActions(
});
},
[ACTIONS.USER_STATE_POPULATE]: (state, action) => {
const {
builtinCollections,
savedCollections,
unpublishedCollections,
editedCollections,
} = action.data;
const { builtinCollections, savedCollections, unpublishedCollections } = action.data;
return {
...state,
edited: editedCollections || state.edited,
unpublished: unpublishedCollections || state.unpublished,
builtin: builtinCollections || state.builtin,
saved: savedCollections || state.saved,

View file

@ -1,5 +1,5 @@
// @flow
import { normalizeURI, parseURI } from 'lbryURI';
import { normalizeURI, buildURI, parseURI } from 'lbryURI';
import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
import { createSelector } from 'reselect';
import { isClaimNsfw, filterClaims } from 'util/claim';
@ -7,24 +7,11 @@ import * as CLAIM from 'constants/claim';
const selectState = state => state.claims || {};
export const selectById = createSelector(
export const selectClaimsById = createSelector(
selectState,
state => state.byId || {}
);
export const selectPendingClaimsById = createSelector(
selectState,
state => state.pendingById || {}
);
export const selectClaimsById = createSelector(
selectById,
selectPendingClaimsById,
(byId, pendingById) => {
return Object.assign(byId, pendingById); // do I need merged to keep metadata?
}
);
export const selectClaimIdsByUri = createSelector(
selectState,
state => state.claimsByUri || {}
@ -85,35 +72,35 @@ export const selectAllClaimsByChannel = createSelector(
export const selectPendingIds = createSelector(
selectState,
state => Object.keys(state.pendingById) || []
state => state.pendingIds || []
);
export const selectPendingClaims = createSelector(
selectPendingClaimsById,
pendingById => Object.values(pendingById)
selectPendingIds,
selectClaimsById,
(pendingIds, byId) => pendingIds.map(id => byId[id])
);
export const makeSelectClaimIsPending = (uri: string) =>
createSelector(
selectClaimIdsByUri,
selectPendingClaimsById,
(idsByUri, pendingById) => {
selectPendingIds,
(idsByUri, pendingIds) => {
const claimId = idsByUri[normalizeURI(uri)];
if (claimId) {
return Boolean(pendingById[claimId]);
return pendingIds.some(i => i === claimId);
}
return false;
}
);
export const makeSelectClaimIdIsPending = (claimId: string) =>
createSelector(
selectPendingClaimsById,
pendingById => {
return Boolean(pendingById[claimId]);
}
);
export const makeSelectClaimIdIsPending = (claimId: string) => createSelector(
selectPendingIds,
(pendingIds) => {
return pendingIds.some(i => i === claimId);
}
);
export const makeSelectClaimIdForUri = (uri: string) =>
createSelector(
@ -165,7 +152,7 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true)
return {
...repostedClaim,
repost_url: normalizeURI(uri),
repost_url: uri,
repost_channel_url: channelUrl,
repost_bid_amount: claim && claim.meta && claim.meta.effective_amount,
};
@ -338,7 +325,6 @@ export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) =>
}
);
// THIS IS LEFT OVER FROM ONE TAB CHANNEL_CONTENT
export const makeSelectTotalClaimsInChannelSearch = (uri: string) =>
createSelector(
selectClaimsById,
@ -349,7 +335,6 @@ export const makeSelectTotalClaimsInChannelSearch = (uri: string) =>
}
);
// THIS IS LEFT OVER FROM ONE_TAB CHANNEL CONTENT
export const makeSelectTotalPagesInChannelSearch = (uri: string) =>
createSelector(
selectClaimsById,
@ -360,6 +345,21 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) =>
}
);
export const makeSelectClaimsInChannelForCurrentPageState = (uri: string) =>
createSelector(
selectClaimsById,
selectAllClaimsByChannel,
selectCurrentChannelPage,
(byId, allClaims, page) => {
const byChannel = allClaims[uri] || {};
const claimIds = byChannel[page || 1];
if (!claimIds) return claimIds;
return claimIds.map(claimId => byId[claimId]);
}
);
export const makeSelectMetadataForUri = (uri: string) =>
createSelector(
makeSelectClaimForUri(uri),
@ -500,9 +500,7 @@ export const selectMyClaims = createSelector(
export const selectMyClaimsWithoutChannels = createSelector(
selectMyClaims,
myClaims =>
myClaims
.filter(claim => claim && !claim.name.match(/^@/))
.sort((a, b) => a.timestamp - b.timestamp)
myClaims.filter(claim => claim && !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)
);
export const selectMyClaimUrisWithoutChannels = createSelector(
@ -610,18 +608,31 @@ export const selectChannelClaimCounts = createSelector(
export const makeSelectPendingClaimForUri = (uri: string) =>
createSelector(
selectPendingClaimsById,
pendingById => {
selectPendingIds,
selectClaimsById,
(pending, claims) => {
let validUri;
let uriIsChannel;
let uriStreamName;
let uriChannelName;
try {
({ streamName: uriStreamName, channelName: uriChannelName } = parseURI(uri));
({
isChannel: uriIsChannel,
streamName: uriStreamName,
channelName: uriChannelName,
} = parseURI(uri));
validUri = true;
} catch (e) {
return null;
}
const pendingClaims = (Object.values(pendingById): any);
const matchingClaim = pendingClaims.find((claim: GenericClaim) => {
return claim.normalized_name === uriChannelName || claim.normalized_name === uriStreamName;
const pendingClaims = pending.map(id => claims[id]);
const matchingClaim = pendingClaims.find(claim => {
const { streamName, channelName, isChannel } = parseURI(claim.permanent_url);
if (isChannel) {
return channelName === uriChannelName;
} else {
return streamName === uriStreamName;
}
});
return matchingClaim || null;
}
@ -630,13 +641,13 @@ export const makeSelectPendingClaimForUri = (uri: string) =>
export const makeSelectTotalItemsForChannel = (uri: string) =>
createSelector(
selectChannelClaimCounts,
byUri => byUri && byUri[normalizeURI(uri)]
byUri => byUri && byUri[uri]
);
export const makeSelectTotalPagesForChannel = (uri: string, pageSize: number = 10) =>
createSelector(
selectChannelClaimCounts,
byUri => byUri && byUri[uri] && Math.ceil(byUri[normalizeURI(uri)] / pageSize)
byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize)
);
export const makeSelectNsfwCountFromUris = (uris: Array<string>) =>
@ -652,6 +663,27 @@ export const makeSelectNsfwCountFromUris = (uris: Array<string>) =>
}, 0)
);
export const makeSelectNsfwCountForChannel = (uri: string) =>
createSelector(
selectClaimsById,
selectAllClaimsByChannel,
selectCurrentChannelPage,
(byId, allClaims, page) => {
const byChannel = allClaims[uri] || {};
const claimIds = byChannel[page || 1];
if (!claimIds) return 0;
return claimIds.reduce((acc, claimId) => {
const claim = byId[claimId];
if (isClaimNsfw(claim)) {
return acc + 1;
}
return acc;
}, 0);
}
);
export const makeSelectOmittedCountForChannel = (uri: string) =>
createSelector(
makeSelectTotalItemsForChannel(uri),
@ -731,6 +763,14 @@ export const makeSelectTagsForUri = (uri: string) =>
}
);
export const makeSelectChannelTagsForUri = (uri: string) =>
createSelector(
makeSelectMetadataForUri(uri),
(metadata: ?GenericMetadata) => {
return (metadata && metadata.tags) || [];
}
);
export const selectFetchingClaimSearchByQuery = createSelector(
selectState,
state => state.fetchingClaimSearchByQuery || {}

View file

@ -1,5 +1,4 @@
// @flow
import fromEntries from '@ungap/from-entries';
import { createSelector } from 'reselect';
import {
selectMyCollectionIds,
@ -80,7 +79,7 @@ export const selectMyPublishedCollections = createSelector(
selectMyCollectionIds,
(resolved, pending, edited, myIds) => {
// all resolved in myIds, plus those in pending and edited
const myPublishedCollections = fromEntries(
const myPublishedCollections = Object.fromEntries(
Object.entries(pending).concat(
Object.entries(resolved).filter(
([key, val]) =>
@ -101,7 +100,7 @@ export const selectMyPublishedCollections = createSelector(
export const selectMyPublishedMixedCollections = createSelector(
selectMyPublishedCollections,
published => {
const myCollections = fromEntries(
const myCollections = Object.fromEntries(
// $FlowFixMe
Object.entries(published).filter(([key, collection]) => {
// $FlowFixMe
@ -115,7 +114,7 @@ export const selectMyPublishedMixedCollections = createSelector(
export const selectMyPublishedPlaylistCollections = createSelector(
selectMyPublishedCollections,
published => {
const myCollections = fromEntries(
const myCollections = Object.fromEntries(
// $FlowFixMe
Object.entries(published).filter(([key, collection]) => {
// $FlowFixMe
@ -136,7 +135,7 @@ export const makeSelectMyPublishedCollectionForId = (id: string) =>
// selectResolvedCollections,
// selectSavedCollectionIds,
// (resolved, myIds) => {
// const mySavedCollections = fromEntries(
// const mySavedCollections = Object.fromEntries(
// Object.entries(resolved).filter(([key, val]) => myIds.includes(key))
// );
// return mySavedCollections;
@ -159,33 +158,11 @@ export const makeSelectCollectionForId = (id: string) =>
selectMyEditedCollections,
selectPendingCollections,
(bLists, rLists, uLists, eLists, pLists) => {
const collection = bLists[id] || uLists[id] || eLists[id] || pLists[id] || rLists[id];
const collection = bLists[id] || uLists[id] || eLists[id] || rLists[id] || pLists[id];
return collection;
}
);
export const makeSelectClaimUrlInCollection = (url: string) =>
createSelector(
selectBuiltinCollections,
selectMyPublishedCollections,
selectMyUnpublishedCollections,
selectMyEditedCollections,
selectPendingCollections,
(bLists, myRLists, uLists, eLists, pLists) => {
const collections = [bLists, uLists, eLists, myRLists, pLists];
const itemsInCollections = [];
collections.map(list => {
Object.entries(list).forEach(([key, value]) => {
// $FlowFixMe
value.items.map(item => {
itemsInCollections.push(item);
});
});
});
return itemsInCollections.includes(url);
}
);
export const makeSelectCollectionForIdHasClaimUrl = (id: string, url: string) =>
createSelector(
makeSelectCollectionForId(id),
@ -213,18 +190,14 @@ export const makeSelectClaimIdsForCollectionId = (id: string) =>
export const makeSelectIndexForUrlInCollection = (url: string, id: string) =>
createSelector(
state => state.content.shuffleList,
makeSelectUrlsForCollectionId(id),
makeSelectClaimForUri(url),
(shuffleState, urls, claim) => {
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
const listUrls = shuffleUrls || urls;
const index = listUrls && listUrls.findIndex(u => u === url);
(urls, claim) => {
const index = urls && urls.findIndex(u => u === url);
if (index > -1) {
return index;
} else if (claim) {
const index = listUrls && listUrls.findIndex(u => u === claim.permanent_url);
const index = urls && urls.findIndex(u => u === claim.permanent_url);
if (index > -1) return index;
return claim;
}
@ -232,49 +205,20 @@ export const makeSelectIndexForUrlInCollection = (url: string, id: string) =>
}
);
export const makeSelectPreviousUrlForCollectionAndUrl = (id: string, url: string) =>
createSelector(
state => state.content.shuffleList,
state => state.content.loopList,
makeSelectIndexForUrlInCollection(url, id),
makeSelectUrlsForCollectionId(id),
(shuffleState, loopState, index, urls) => {
const loopList = loopState && loopState.collectionId === id && loopState.loop;
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
if (index > -1) {
const listUrls = shuffleUrls || urls;
let nextUrl;
if (index === 0 && loopList) {
nextUrl = listUrls[listUrls.length - 1];
} else {
nextUrl = listUrls[index - 1];
}
return nextUrl || null;
} else {
return null;
}
}
);
export const makeSelectNextUrlForCollectionAndUrl = (id: string, url: string) =>
createSelector(
state => state.content.shuffleList,
state => state.content.loopList,
makeSelectIndexForUrlInCollection(url, id),
selectClaimsByUri,
makeSelectUrlsForCollectionId(id),
(shuffleState, loopState, index, urls) => {
const loopList = loopState && loopState.collectionId === id && loopState.loop;
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
(index, claims, urls) => {
if (index > -1) {
const listUrls = shuffleUrls || urls;
// We'll get the next playble url
let remainingUrls = listUrls.slice(index + 1);
if (!remainingUrls.length && loopList) {
remainingUrls = listUrls.slice(0);
}
const nextUrl = remainingUrls && remainingUrls[0];
const remainingUrls = urls.slice(index + 1);
const nextUrl = remainingUrls.find(
u =>
claims[u].value.stream_type &&
(claims[u].value.stream_type === 'video' || claims[u].value.stream_type === 'audio')
);
return nextUrl || null;
} else {
return null;
@ -298,13 +242,7 @@ export const makeSelectCountForCollectionId = (id: string) =>
if (collection.itemCount !== undefined) {
return collection.itemCount;
}
let itemCount = 0;
collection.items.map(item => {
if (item) {
itemCount += 1;
}
});
return itemCount;
return collection.items.length;
}
return null;
}

View file

@ -1411,11 +1411,6 @@
dependencies:
"@types/yargs-parser" "*"
"@ungap/from-entries@^0.2.1":
version "0.2.1"
resolved "https://registry.yarnpkg.com/@ungap/from-entries/-/from-entries-0.2.1.tgz#7e86196b8b2e99d73106a8f25c2a068326346354"
integrity sha512-CAqefTFAfnUPwYqsWHXpOxHaq1Zo5UQ3m9Zm2p09LggGe57rqHoBn3c++xcoomzXKynAUuiBMDUCQvKMnXjUpA==
abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"