Compare commits
35 commits
selectClai
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
0f930c4a7b | ||
|
32b5787071 | ||
|
129b0ea3fa | ||
|
e3bc848263 | ||
|
372e559cae | ||
|
49b9db5aae | ||
|
12a2ffc708 | ||
|
95fa26f836 | ||
|
dc264ec50c | ||
|
aeb1f533b5 | ||
|
d016d8057b | ||
|
0302a2f8d6 | ||
|
8fa92d872d | ||
|
e4d0662100 | ||
|
036aa59086 | ||
|
c76dfbde27 | ||
|
7cc9923ed9 | ||
|
60bd918d5e | ||
|
9ebfc927d0 | ||
|
54ca8c4320 | ||
|
bee9bf38dd | ||
|
aabae5ce59 | ||
|
a327385cdf | ||
|
64ce7aa99c | ||
|
34dfd384e4 | ||
|
707c60b813 | ||
|
8f66a2fe7c | ||
|
729a4831ad | ||
|
88370997b4 | ||
|
b93598b0ff | ||
|
4cbb9a35c3 | ||
|
04ce1df03d | ||
|
347fe25e85 | ||
|
e66698eadc | ||
|
0b505fb0f4 |
20 changed files with 683 additions and 390 deletions
436
dist/bundle.es.js
vendored
436
dist/bundle.es.js
vendored
|
@ -2,9 +2,12 @@
|
|||
|
||||
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;
|
||||
|
||||
|
@ -716,7 +719,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 = 'autoplay';
|
||||
const AUTOPLAY_MEDIA = 'autoplay';
|
||||
const AUTOPLAY_NEXT = 'autoplay_next';
|
||||
const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
|
||||
const AUTO_DOWNLOAD = 'auto_download';
|
||||
|
@ -732,6 +735,8 @@ 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';
|
||||
|
@ -765,7 +770,7 @@ var settings = /*#__PURE__*/Object.freeze({
|
|||
THEME: THEME,
|
||||
THEMES: THEMES,
|
||||
AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED,
|
||||
AUTOPLAY: AUTOPLAY,
|
||||
AUTOPLAY_MEDIA: AUTOPLAY_MEDIA,
|
||||
AUTOPLAY_NEXT: AUTOPLAY_NEXT,
|
||||
OS_NOTIFICATIONS_ENABLED: OS_NOTIFICATIONS_ENABLED,
|
||||
AUTO_DOWNLOAD: AUTO_DOWNLOAD,
|
||||
|
@ -781,6 +786,8 @@ 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,
|
||||
|
@ -1033,7 +1040,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, HIDE_BALANCE, HIDE_SPLASH_ANIMATION, FLOATING_PLAYER, DARK_MODE_TIMES, AUTOMATIC_DARK_MODE_ENABLED];
|
||||
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];
|
||||
|
||||
var shared_preferences = /*#__PURE__*/Object.freeze({
|
||||
SDK_SYNC_KEYS: SDK_SYNC_KEYS,
|
||||
|
@ -1190,6 +1197,7 @@ 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),
|
||||
|
@ -1472,7 +1480,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 = '([^:$#/]*)';
|
||||
|
@ -1480,6 +1488,11 @@ 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.
|
||||
|
@ -1581,11 +1594,11 @@ function parseURIModifier(modSeperator, modValue) {
|
|||
throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator }));
|
||||
}
|
||||
|
||||
if (modSeperator === '#') {
|
||||
if (modSeperator === MOD_CLAIM_ID_SEPARATOR || MOD_CLAIM_ID_SEPARATOR_OLD) {
|
||||
claimId = modValue;
|
||||
} else if (modSeperator === ':') {
|
||||
} else if (modSeperator === MOD_SEQUENCE_SEPARATOR) {
|
||||
claimSequence = modValue;
|
||||
} else if (modSeperator === '$') {
|
||||
} else if (modSeperator === MOD_BID_POSITION_SEPARATOR) {
|
||||
bidPosition = modValue;
|
||||
}
|
||||
}
|
||||
|
@ -1716,6 +1729,25 @@ 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
|
||||
|
@ -1839,11 +1871,12 @@ 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 } : {}, 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 } : {}, editedCollections ? { editedCollections } : {}, builtinCollections ? { builtinCollections } : {}, savedCollections ? { savedCollections } : {});
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -1861,6 +1894,7 @@ function doPopulateSharedUserState(sharedSettings) {
|
|||
app_welcome_version,
|
||||
sharing_3P,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
builtinCollections,
|
||||
savedCollections
|
||||
} = extractUserState(sharedSettings);
|
||||
|
@ -1876,6 +1910,7 @@ function doPopulateSharedUserState(sharedSettings) {
|
|||
welcomeVersion: app_welcome_version,
|
||||
allowAnalytics: sharing_3P,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
builtinCollections,
|
||||
savedCollections
|
||||
}
|
||||
|
@ -2370,7 +2405,13 @@ var _extends$3 = Object.assign || function (target) { for (var i = 1; i < argume
|
|||
|
||||
const selectState$1 = state => state.claims || {};
|
||||
|
||||
const selectClaimsById = reselect.createSelector(selectState$1, state => state.byId || {});
|
||||
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 selectClaimIdsByUri = reselect.createSelector(selectState$1, state => state.claimsByUri || {});
|
||||
|
||||
|
@ -2405,21 +2446,21 @@ const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectCla
|
|||
|
||||
const selectAllClaimsByChannel = reselect.createSelector(selectState$1, state => state.paginatedClaimsByChannel || {});
|
||||
|
||||
const selectPendingIds = reselect.createSelector(selectState$1, state => state.pendingIds || []);
|
||||
const selectPendingIds = reselect.createSelector(selectState$1, state => Object.keys(state.pendingById) || []);
|
||||
|
||||
const selectPendingClaims = reselect.createSelector(selectPendingIds, selectClaimsById, (pendingIds, byId) => pendingIds.map(id => byId[id]));
|
||||
const selectPendingClaims = reselect.createSelector(selectPendingClaimsById, pendingById => Object.values(pendingById));
|
||||
|
||||
const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => {
|
||||
const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingClaimsById, (idsByUri, pendingById) => {
|
||||
const claimId = idsByUri[normalizeURI(uri)];
|
||||
|
||||
if (claimId) {
|
||||
return pendingIds.some(i => i === claimId);
|
||||
return Boolean(pendingById[claimId]);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const makeSelectClaimIdIsPending = claimId => reselect.createSelector(selectPendingIds, pendingIds => {
|
||||
return pendingIds.some(i => i === claimId);
|
||||
const makeSelectClaimIdIsPending = claimId => reselect.createSelector(selectPendingClaimsById, pendingById => {
|
||||
return Boolean(pendingById[claimId]);
|
||||
});
|
||||
|
||||
const makeSelectClaimIdForUri = uri => reselect.createSelector(selectClaimIdsByUri, claimIds => claimIds[uri]);
|
||||
|
@ -2454,7 +2495,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: uri,
|
||||
repost_url: normalizeURI(uri),
|
||||
repost_channel_url: channelUrl,
|
||||
repost_bid_amount: claim && claim.meta && claim.meta.effective_amount
|
||||
});
|
||||
|
@ -2552,25 +2593,18 @@ 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);
|
||||
|
@ -2697,34 +2731,24 @@ const selectPlayingUri = reselect.createSelector(selectState$1, state => state.p
|
|||
|
||||
const selectChannelClaimCounts = reselect.createSelector(selectState$1, state => state.channelClaimCounts || {});
|
||||
|
||||
const makeSelectPendingClaimForUri = uri => reselect.createSelector(selectPendingIds, selectClaimsById, (pending, claims) => {
|
||||
let uriIsChannel;
|
||||
const makeSelectPendingClaimForUri = uri => reselect.createSelector(selectPendingClaimsById, pendingById => {
|
||||
let uriStreamName;
|
||||
let uriChannelName;
|
||||
try {
|
||||
({
|
||||
isChannel: uriIsChannel,
|
||||
streamName: uriStreamName,
|
||||
channelName: uriChannelName
|
||||
} = parseURI(uri));
|
||||
({ streamName: uriStreamName, channelName: uriChannelName } = parseURI(uri));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
const pendingClaims = pending.map(id => claims[id]);
|
||||
const pendingClaims = Object.values(pendingById);
|
||||
const matchingClaim = pendingClaims.find(claim => {
|
||||
const { streamName, channelName, isChannel } = parseURI(claim.permanent_url);
|
||||
if (isChannel) {
|
||||
return channelName === uriChannelName;
|
||||
} else {
|
||||
return streamName === uriStreamName;
|
||||
}
|
||||
return claim.normalized_name === uriChannelName || claim.normalized_name === uriStreamName;
|
||||
});
|
||||
return matchingClaim || null;
|
||||
});
|
||||
|
||||
const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]);
|
||||
const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[normalizeURI(uri)]);
|
||||
|
||||
const makeSelectTotalPagesForChannel = (uri, pageSize = 10) => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize));
|
||||
const makeSelectTotalPagesForChannel = (uri, pageSize = 10) => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[normalizeURI(uri)] / pageSize));
|
||||
|
||||
const makeSelectNsfwCountFromUris = uris => reselect.createSelector(selectClaimsByUri, claims => uris.reduce((acc, uri) => {
|
||||
const claim = claims[uri];
|
||||
|
@ -2734,21 +2758,6 @@ 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;
|
||||
|
@ -3642,7 +3651,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 = Object.fromEntries(Object.entries(pending).concat(Object.entries(resolved).filter(([key, val]) => myIds.includes(key) &&
|
||||
const myPublishedCollections = fromEntries(Object.entries(pending).concat(Object.entries(resolved).filter(([key, val]) => myIds.includes(key) &&
|
||||
// $FlowFixMe
|
||||
!pending[key])));
|
||||
// now add in edited:
|
||||
|
@ -3653,7 +3662,7 @@ const selectMyPublishedCollections = reselect.createSelector(selectResolvedColle
|
|||
});
|
||||
|
||||
const selectMyPublishedMixedCollections = reselect.createSelector(selectMyPublishedCollections, published => {
|
||||
const myCollections = Object.fromEntries(
|
||||
const myCollections = fromEntries(
|
||||
// $FlowFixMe
|
||||
Object.entries(published).filter(([key, collection]) => {
|
||||
// $FlowFixMe
|
||||
|
@ -3663,7 +3672,7 @@ const selectMyPublishedMixedCollections = reselect.createSelector(selectMyPublis
|
|||
});
|
||||
|
||||
const selectMyPublishedPlaylistCollections = reselect.createSelector(selectMyPublishedCollections, published => {
|
||||
const myCollections = Object.fromEntries(
|
||||
const myCollections = fromEntries(
|
||||
// $FlowFixMe
|
||||
Object.entries(published).filter(([key, collection]) => {
|
||||
// $FlowFixMe
|
||||
|
@ -3678,7 +3687,7 @@ const makeSelectMyPublishedCollectionForId = id => reselect.createSelector(selec
|
|||
// selectResolvedCollections,
|
||||
// selectSavedCollectionIds,
|
||||
// (resolved, myIds) => {
|
||||
// const mySavedCollections = Object.fromEntries(
|
||||
// const mySavedCollections = fromEntries(
|
||||
// Object.entries(resolved).filter(([key, val]) => myIds.includes(key))
|
||||
// );
|
||||
// return mySavedCollections;
|
||||
|
@ -3690,10 +3699,24 @@ 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] || rLists[id] || pLists[id];
|
||||
const collection = bLists[id] || uLists[id] || eLists[id] || pLists[id] || rLists[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);
|
||||
|
@ -3707,23 +3730,51 @@ const makeSelectClaimIdsForCollectionId = id => reselect.createSelector(makeSele
|
|||
return ids;
|
||||
});
|
||||
|
||||
const makeSelectIndexForUrlInCollection = (url, id) => reselect.createSelector(makeSelectUrlsForCollectionId(id), makeSelectClaimForUri(url), (urls, claim) => {
|
||||
const index = urls && urls.findIndex(u => u === url);
|
||||
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);
|
||||
if (index > -1) {
|
||||
return index;
|
||||
} else if (claim) {
|
||||
const index = urls && urls.findIndex(u => u === claim.permanent_url);
|
||||
const index = listUrls && listUrls.findIndex(u => u === claim.permanent_url);
|
||||
if (index > -1) return index;
|
||||
return claim;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const makeSelectNextUrlForCollectionAndUrl = (id, url) => reselect.createSelector(makeSelectIndexForUrlInCollection(url, id), selectClaimsByUri, makeSelectUrlsForCollectionId(id), (index, claims, urls) => {
|
||||
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;
|
||||
|
||||
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
|
||||
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'));
|
||||
let remainingUrls = listUrls.slice(index + 1);
|
||||
if (!remainingUrls.length && loopList) {
|
||||
remainingUrls = listUrls.slice(0);
|
||||
}
|
||||
const nextUrl = remainingUrls && remainingUrls[0];
|
||||
return nextUrl || null;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -3739,7 +3790,13 @@ const makeSelectCountForCollectionId = id => reselect.createSelector(makeSelectC
|
|||
if (collection.itemCount !== undefined) {
|
||||
return collection.itemCount;
|
||||
}
|
||||
return collection.items.length;
|
||||
let itemCount = 0;
|
||||
collection.items.map(item => {
|
||||
if (item) {
|
||||
itemCount += 1;
|
||||
}
|
||||
});
|
||||
return itemCount;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
@ -3748,6 +3805,9 @@ 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);
|
||||
|
@ -4086,7 +4146,7 @@ function doClearChannelErrors() {
|
|||
};
|
||||
}
|
||||
|
||||
function doCreateChannel(name, amount, optionalParams, cb) {
|
||||
function doCreateChannel(name, amount, optionalParams, onConfirm) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: CREATE_CHANNEL_STARTED
|
||||
|
@ -4140,7 +4200,7 @@ function doCreateChannel(name, amount, optionalParams, cb) {
|
|||
claims: [channelClaim]
|
||||
}
|
||||
});
|
||||
dispatch(doCheckPendingClaims(cb));
|
||||
dispatch(doCheckPendingClaims(onConfirm));
|
||||
return channelClaim;
|
||||
}).catch(error => {
|
||||
dispatch({
|
||||
|
@ -4442,11 +4502,15 @@ function doCollectionPublish(options, localId) {
|
|||
};
|
||||
}
|
||||
|
||||
function doCollectionPublishUpdate(options) {
|
||||
return dispatch => {
|
||||
function doCollectionPublishUpdate(options, isBackgroundUpdate) {
|
||||
return (dispatch, getState) => {
|
||||
// TODO: implement one click update
|
||||
|
||||
const updateParams = {
|
||||
const updateParams = isBackgroundUpdate ? {
|
||||
blocking: true,
|
||||
claim_id: options.claim_id,
|
||||
clear_claims: true
|
||||
} : {
|
||||
bid: creditsToString(options.bid),
|
||||
title: options.title,
|
||||
thumbnail_url: options.thumbnail_url,
|
||||
|
@ -4456,16 +4520,25 @@ function doCollectionPublishUpdate(options) {
|
|||
locations: [],
|
||||
blocking: true,
|
||||
claim_id: options.claim_id,
|
||||
clear_claims: true
|
||||
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;
|
||||
}
|
||||
|
||||
if (options.tags) {
|
||||
updateParams['tags'] = options.tags.map(tag => tag.name);
|
||||
}
|
||||
|
||||
if (options.claims) {
|
||||
updateParams['claims'] = options.claims;
|
||||
if (options.channel_id) {
|
||||
updateParams['channel_id'] = options.channel_id;
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
dispatch({
|
||||
type: COLLECTION_PUBLISH_UPDATE_STARTED
|
||||
|
@ -4490,7 +4563,6 @@ function doCollectionPublishUpdate(options) {
|
|||
}
|
||||
});
|
||||
dispatch(doCheckPendingClaims());
|
||||
dispatch(doFetchCollectionListMine(1, 10));
|
||||
return resolve(collectionClaim);
|
||||
}
|
||||
|
||||
|
@ -4570,48 +4642,63 @@ function doPurchaseList(page = 1, pageSize = PAGE_SIZE) {
|
|||
};
|
||||
}
|
||||
|
||||
const doCheckPendingClaims = onConfirmed => (dispatch, getState) => {
|
||||
let claimCheckInterval;
|
||||
|
||||
const checkClaimList = () => {
|
||||
const doCheckPendingClaims = onChannelConfirmed => (dispatch, getState) => {
|
||||
if (onChannelConfirmed) {
|
||||
onChannelConfirmCallback = onChannelConfirmed;
|
||||
}
|
||||
clearInterval(checkPendingInterval);
|
||||
const checkTxoList = () => {
|
||||
const state = getState();
|
||||
const pendingIdSet = new Set(selectPendingIds(state));
|
||||
const pendingById = Object.assign({}, selectPendingClaimsById(state));
|
||||
const pendingTxos = Object.values(pendingById).map(p => p.txid);
|
||||
// use collections
|
||||
const pendingCollections = selectPendingCollections(state);
|
||||
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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
});
|
||||
if (claimsToConfirm.length) {
|
||||
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: claimsToConfirm
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
return pendingIdSet.size;
|
||||
}).then(len => {
|
||||
if (!len) {
|
||||
clearInterval(claimCheckInterval);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
clearInterval(checkPendingInterval);
|
||||
}
|
||||
};
|
||||
|
||||
claimCheckInterval = setInterval(() => {
|
||||
checkClaimList();
|
||||
// do something with onConfirmed (typically get blocklist for channel)
|
||||
checkPendingInterval = setInterval(() => {
|
||||
checkTxoList();
|
||||
}, 30000);
|
||||
};
|
||||
|
||||
|
@ -4621,7 +4708,7 @@ const getTimestamp = () => {
|
|||
return Math.floor(Date.now() / 1000);
|
||||
};
|
||||
|
||||
const FETCH_BATCH_SIZE = 10;
|
||||
const FETCH_BATCH_SIZE = 50;
|
||||
|
||||
const doLocalCollectionCreate = (name, collectionItems, type, sourceId) => dispatch => {
|
||||
return dispatch({
|
||||
|
@ -4728,7 +4815,8 @@ const doFetchItemsInCollections = (resolveItemsOptions, resolveStartedCallback)
|
|||
batches[i] = lbryProxy.claim_search({
|
||||
claim_ids: claim.value.claims,
|
||||
page: i + 1,
|
||||
page_size: batchSize
|
||||
page_size: batchSize,
|
||||
no_totals: true
|
||||
});
|
||||
}
|
||||
const itemsInBatches = yield Promise.all(batches);
|
||||
|
@ -5545,7 +5633,7 @@ const doUpdatePublishForm = publishFormValue => dispatch => dispatch({
|
|||
data: _extends$7({}, publishFormValue)
|
||||
});
|
||||
|
||||
const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => {
|
||||
const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path, cb) => dispatch => {
|
||||
const downMessage = __('Thumbnail upload service may be down, try again later.');
|
||||
let thumbnail, fileExt, fileName, fileType;
|
||||
|
||||
|
@ -5579,13 +5667,17 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp
|
|||
method: 'POST',
|
||||
body: data
|
||||
}).then(res => res.text()).then(text => text.length ? JSON.parse(text) : {}).then(json => {
|
||||
return json.success ? dispatch({
|
||||
if (!json.success) return uploadError(json.message || downMessage);
|
||||
if (cb) {
|
||||
cb(json.data.serveUrl);
|
||||
}
|
||||
return dispatch({
|
||||
type: UPDATE_PUBLISH_FORM,
|
||||
data: {
|
||||
uploadThumbnailStatus: COMPLETE,
|
||||
thumbnail: json.data.serveUrl
|
||||
}
|
||||
}) : uploadError(json.message || downMessage);
|
||||
});
|
||||
}).catch(err => {
|
||||
let message = err.message;
|
||||
|
||||
|
@ -6001,7 +6093,7 @@ const defaultState = {
|
|||
fetchingMyChannels: false,
|
||||
fetchingMyCollections: false,
|
||||
abandoningById: {},
|
||||
pendingIds: [],
|
||||
pendingById: {},
|
||||
reflectingById: {},
|
||||
claimSearchError: false,
|
||||
claimSearchByQuery: {},
|
||||
|
@ -6035,7 +6127,7 @@ function handleClaimAction(state, action) {
|
|||
const byUri = Object.assign({}, state.claimsByUri);
|
||||
const byId = Object.assign({}, state.byId);
|
||||
const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
|
||||
const pendingIds = state.pendingIds;
|
||||
const pendingById = state.pendingById;
|
||||
let newResolvingUrls = new Set(state.resolvingUris);
|
||||
let myClaimIds = new Set(state.myClaims);
|
||||
|
||||
|
@ -6045,7 +6137,7 @@ function handleClaimAction(state, action) {
|
|||
const channel = channelFromResolve || stream && stream.signing_channel;
|
||||
|
||||
if (stream) {
|
||||
if (pendingIds.includes(stream.claim_id)) {
|
||||
if (pendingById[stream.claim_id]) {
|
||||
byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]);
|
||||
} else {
|
||||
byId[stream.claim_id] = stream;
|
||||
|
@ -6075,7 +6167,7 @@ function handleClaimAction(state, action) {
|
|||
channelClaimCounts[channel.canonical_url] = claimsInChannel;
|
||||
}
|
||||
|
||||
if (pendingIds.includes(channel.claim_id)) {
|
||||
if (pendingById[channel.claim_id]) {
|
||||
byId[channel.claim_id] = mergeClaims(channel, byId[channel.claim_id]);
|
||||
} else {
|
||||
byId[channel.claim_id] = channel;
|
||||
|
@ -6088,7 +6180,7 @@ function handleClaimAction(state, action) {
|
|||
}
|
||||
|
||||
if (collection) {
|
||||
if (pendingIds.includes(collection.claim_id)) {
|
||||
if (pendingById[collection.claim_id]) {
|
||||
byId[collection.claim_id] = mergeClaims(collection, byId[collection.claim_id]);
|
||||
} else {
|
||||
byId[collection.claim_id] = collection;
|
||||
|
@ -6105,7 +6197,7 @@ function handleClaimAction(state, action) {
|
|||
}
|
||||
|
||||
newResolvingUrls.delete(url);
|
||||
if (!stream && !channel && !collection && !pendingIds.includes(byUri[url])) {
|
||||
if (!stream && !channel && !collection && !pendingById[byUri[url]]) {
|
||||
byUri[url] = null;
|
||||
}
|
||||
});
|
||||
|
@ -6145,34 +6237,33 @@ reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, {
|
|||
});
|
||||
|
||||
reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
|
||||
const { result, resolve } = action.data;
|
||||
const { result } = 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 pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myClaimIds = new Set(state.myClaims);
|
||||
let urlsForCurrentPage = [];
|
||||
|
||||
const pendingIdSet = new Set(pendingIds);
|
||||
|
||||
claims.forEach(claim => {
|
||||
const { permanent_url: permanentUri, claim_id: claimId } = claim;
|
||||
const { permanent_url: permanentUri, claim_id: claimId, canonical_url: canonicalUri } = claim;
|
||||
if (claim.type && claim.type.match(/claim|update/)) {
|
||||
urlsForCurrentPage.push(permanentUri);
|
||||
if (claim.confirmations < 1) {
|
||||
pendingIdSet.add(claimId);
|
||||
} else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) {
|
||||
pendingIdSet.delete(claimId);
|
||||
}
|
||||
if (pendingIds.includes(claimId)) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaims(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
byUri[permanentUri] = claimId;
|
||||
byUri[canonicalUri] = claimId;
|
||||
myClaimIds.add(claimId);
|
||||
}
|
||||
});
|
||||
|
@ -6181,7 +6272,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
|
|||
isFetchingClaimListMine: false,
|
||||
myClaims: Array.from(myClaimIds),
|
||||
byId,
|
||||
pendingIds: Array.from(pendingIdSet),
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
myClaimsPageResults: urlsForCurrentPage,
|
||||
myClaimsPageNumber: page,
|
||||
|
@ -6193,9 +6284,8 @@ 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 pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myChannelClaims;
|
||||
const byId = Object.assign({}, state.byId);
|
||||
const byUri = Object.assign({}, state.claimsByUri);
|
||||
|
@ -6208,7 +6298,12 @@ 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 } = claim;
|
||||
const {
|
||||
canonical_url: canonicalUrl,
|
||||
permanent_url: permanentUrl,
|
||||
claim_id: claimId,
|
||||
confirmations
|
||||
} = claim;
|
||||
|
||||
byUri[canonicalUrl] = claimId;
|
||||
byUri[permanentUrl] = claimId;
|
||||
|
@ -6217,7 +6312,14 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
|
|||
|
||||
// $FlowFixMe
|
||||
myChannelClaims.add(claimId);
|
||||
if (!pendingIds.some(c => c === claimId)) {
|
||||
if (confirmations < 1) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaims(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
myClaimIds.add(claimId);
|
||||
|
@ -6226,6 +6328,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
|
|||
|
||||
return Object.assign({}, state, {
|
||||
byId,
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
channelClaimCounts,
|
||||
fetchingMyChannels: false,
|
||||
|
@ -6248,7 +6351,7 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
|
|||
const { claims } = action.data;
|
||||
const myClaims = state.myClaims || [];
|
||||
let myClaimIds = new Set(myClaims);
|
||||
const pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myCollectionClaimsSet = new Set([]);
|
||||
const byId = Object.assign({}, state.byId);
|
||||
const byUri = Object.assign({}, state.claimsByUri);
|
||||
|
@ -6256,7 +6359,12 @@ 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 } = claim;
|
||||
const {
|
||||
canonical_url: canonicalUrl,
|
||||
permanent_url: permanentUrl,
|
||||
claim_id: claimId,
|
||||
confirmations
|
||||
} = claim;
|
||||
|
||||
byUri[canonicalUrl] = claimId;
|
||||
byUri[permanentUrl] = claimId;
|
||||
|
@ -6264,7 +6372,14 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
|
|||
// $FlowFixMe
|
||||
myCollectionClaimsSet.add(claimId);
|
||||
// we don't want to overwrite a pending result with a resolve
|
||||
if (!pendingIds.some(c => c === claimId)) {
|
||||
if (confirmations < 1) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaims(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
myClaimIds.add(claimId);
|
||||
|
@ -6273,6 +6388,7 @@ reducers[FETCH_COLLECTION_LIST_COMPLETED] = (state, action) => {
|
|||
|
||||
return _extends$9({}, state, {
|
||||
byId,
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
fetchingMyCollections: false,
|
||||
myCollectionClaims: Array.from(myCollectionClaimsSet),
|
||||
|
@ -6358,9 +6474,8 @@ 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);
|
||||
|
||||
|
@ -6368,7 +6483,7 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => {
|
|||
pendingClaims.forEach(claim => {
|
||||
let newClaim;
|
||||
const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim;
|
||||
pendingIdSet.add(claimId);
|
||||
pendingById[claimId] = claim; // make sure we don't need to merge?
|
||||
const oldClaim = byId[claimId];
|
||||
if (oldClaim && oldClaim.canonical_url) {
|
||||
newClaim = mergeClaims(oldClaim, claim);
|
||||
|
@ -6388,21 +6503,22 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => {
|
|||
return Object.assign({}, state, {
|
||||
myClaims: Array.from(myClaimIds),
|
||||
byId,
|
||||
pendingById,
|
||||
myChannelClaims: Array.from(myChannelClaims),
|
||||
claimsByUri: byUri,
|
||||
pendingIds: Array.from(pendingIdSet)
|
||||
claimsByUri: byUri
|
||||
});
|
||||
};
|
||||
|
||||
reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => {
|
||||
const { claims: confirmedClaims } = action.data;
|
||||
const {
|
||||
claims: confirmedClaims,
|
||||
pending: pendingClaims
|
||||
} = 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 { permanent_url: permanentUri, claim_id: claimId, type } = claim;
|
||||
const { claim_id: claimId, type } = claim;
|
||||
let newClaim = claim;
|
||||
const oldClaim = byId[claimId];
|
||||
if (oldClaim && oldClaim.canonical_url) {
|
||||
|
@ -6410,11 +6526,10 @@ reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => {
|
|||
}
|
||||
if (type && type.match(/claim|update|channel/)) {
|
||||
byId[claimId] = newClaim;
|
||||
pendingIdSet.delete(claimId);
|
||||
}
|
||||
});
|
||||
return Object.assign({}, state, {
|
||||
pendingIds: Array.from(pendingIdSet),
|
||||
pendingById: pendingClaims,
|
||||
byId,
|
||||
claimsByUri: byUri
|
||||
});
|
||||
|
@ -7657,8 +7772,15 @@ const collectionsReducer = handleActions({
|
|||
|
||||
[COLLECTION_PENDING]: (state, action) => {
|
||||
const { localId, claimId } = action.data;
|
||||
const { edited: editList, unpublished: unpublishedList, pending: pendingList } = state;
|
||||
const {
|
||||
resolved: resolvedList,
|
||||
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);
|
||||
|
||||
|
@ -7668,7 +7790,7 @@ const collectionsReducer = handleActions({
|
|||
delete newUnpublishedList[localId];
|
||||
} else {
|
||||
// edit update
|
||||
newPendingList[claimId] = Object.assign({}, newEditList[claimId]);
|
||||
newPendingList[claimId] = Object.assign({}, newEditList[claimId] || newResolvedList[claimId]);
|
||||
delete newEditList[claimId];
|
||||
}
|
||||
|
||||
|
@ -7720,8 +7842,14 @@ const collectionsReducer = handleActions({
|
|||
}));
|
||||
},
|
||||
[USER_STATE_POPULATE]: (state, action) => {
|
||||
const { builtinCollections, savedCollections, unpublishedCollections } = action.data;
|
||||
const {
|
||||
builtinCollections,
|
||||
savedCollections,
|
||||
unpublishedCollections,
|
||||
editedCollections
|
||||
} = action.data;
|
||||
return _extends$e({}, state, {
|
||||
edited: editedCollections || state.edited,
|
||||
unpublished: unpublishedCollections || state.unpublished,
|
||||
builtin: builtinCollections || state.builtin,
|
||||
saved: savedCollections || state.saved
|
||||
|
@ -7921,6 +8049,7 @@ exports.formatFullPrice = formatFullPrice;
|
|||
exports.isClaimNsfw = isClaimNsfw;
|
||||
exports.isNameValid = isNameValid;
|
||||
exports.isURIClaimable = isURIClaimable;
|
||||
exports.isURIEqual = isURIEqual;
|
||||
exports.isURIValid = isURIValid;
|
||||
exports.makeSelectAbandoningClaimById = makeSelectAbandoningClaimById;
|
||||
exports.makeSelectAmountForUri = makeSelectAmountForUri;
|
||||
|
@ -7937,8 +8066,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;
|
||||
|
@ -7972,13 +8101,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;
|
||||
|
@ -8138,5 +8267,6 @@ exports.selectWalletState = selectWalletState;
|
|||
exports.selectWalletUnlockPending = selectWalletUnlockPending;
|
||||
exports.selectWalletUnlockResult = selectWalletUnlockResult;
|
||||
exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded;
|
||||
exports.splitBySeparator = splitBySeparator;
|
||||
exports.toQueryString = toQueryString;
|
||||
exports.walletReducer = walletReducer;
|
||||
|
|
3
dist/flow-typed/Lbry.js
vendored
3
dist/flow-typed/Lbry.js
vendored
|
@ -75,7 +75,7 @@ declare type BalanceResponse = {
|
|||
|
||||
declare type ResolveResponse = {
|
||||
// Keys are the url(s) passed to resolve
|
||||
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number },
|
||||
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, collection?: CollectionClaim, claimsInChannel?: number },
|
||||
};
|
||||
|
||||
declare type GetResponse = FileListItem & { error?: string };
|
||||
|
@ -351,6 +351,7 @@ 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>,
|
||||
|
|
5
dist/flow-typed/npm/from-entries.js
vendored
Normal file
5
dist/flow-typed/npm/from-entries.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
// @flow
|
||||
|
||||
declare module '@ungap/from-entries' {
|
||||
declare module.exports: any;
|
||||
}
|
3
flow-typed/Lbry.js
vendored
3
flow-typed/Lbry.js
vendored
|
@ -75,7 +75,7 @@ declare type BalanceResponse = {
|
|||
|
||||
declare type ResolveResponse = {
|
||||
// Keys are the url(s) passed to resolve
|
||||
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number },
|
||||
[string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, collection?: CollectionClaim, claimsInChannel?: number },
|
||||
};
|
||||
|
||||
declare type GetResponse = FileListItem & { error?: string };
|
||||
|
@ -351,6 +351,7 @@ 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>,
|
||||
|
|
5
flow-typed/npm/from-entries.js
vendored
Normal file
5
flow-typed/npm/from-entries.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
// @flow
|
||||
|
||||
declare module '@ungap/from-entries' {
|
||||
declare module.exports: any;
|
||||
}
|
|
@ -29,6 +29,7 @@
|
|||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ungap/from-entries": "^0.2.1",
|
||||
"proxy-polyfill": "0.1.6",
|
||||
"reselect": "^3.0.0",
|
||||
"uuid": "^8.3.1"
|
||||
|
|
|
@ -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 = 'autoplay';
|
||||
export const AUTOPLAY_MEDIA = 'autoplay';
|
||||
export const AUTOPLAY_NEXT = 'autoplay_next';
|
||||
export const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
|
||||
export const AUTO_DOWNLOAD = 'auto_download';
|
||||
|
@ -39,6 +39,8 @@ 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';
|
||||
|
|
|
@ -21,10 +21,12 @@ export const CLIENT_SYNC_KEYS = [
|
|||
SETTINGS.INSTANT_PURCHASE_ENABLED,
|
||||
SETTINGS.INSTANT_PURCHASE_MAX,
|
||||
SETTINGS.THEME,
|
||||
SETTINGS.AUTOPLAY,
|
||||
SETTINGS.AUTOPLAY_MEDIA,
|
||||
SETTINGS.AUTOPLAY_NEXT,
|
||||
SETTINGS.HIDE_BALANCE,
|
||||
SETTINGS.HIDE_SPLASH_ANIMATION,
|
||||
SETTINGS.FLOATING_PLAYER,
|
||||
SETTINGS.DARK_MODE_TIMES,
|
||||
SETTINGS.AUTOMATIC_DARK_MODE_ENABLED,
|
||||
SETTINGS.LANGUAGE,
|
||||
];
|
||||
|
|
|
@ -52,6 +52,8 @@ export {
|
|||
isURIClaimable,
|
||||
isNameValid,
|
||||
convertToShareLink,
|
||||
splitBySeparator,
|
||||
isURIEqual,
|
||||
} from 'lbryURI';
|
||||
|
||||
// middlware
|
||||
|
@ -174,12 +176,14 @@ export {
|
|||
makeSelectMyPublishedCollectionForId,
|
||||
makeSelectUnpublishedCollectionForId,
|
||||
makeSelectCollectionForId,
|
||||
makeSelectClaimUrlInCollection,
|
||||
makeSelectUrlsForCollectionId,
|
||||
makeSelectClaimIdsForCollectionId,
|
||||
makeSelectNameForCollectionId,
|
||||
makeSelectCountForCollectionId,
|
||||
makeSelectIsResolvingCollectionForId,
|
||||
makeSelectIndexForUrlInCollection,
|
||||
makeSelectPreviousUrlForCollectionAndUrl,
|
||||
makeSelectNextUrlForCollectionAndUrl,
|
||||
makeSelectCollectionForIdHasClaimUrl,
|
||||
} from 'redux/selectors/collections';
|
||||
|
@ -209,7 +213,6 @@ export {
|
|||
makeSelectTotalItemsForChannel,
|
||||
makeSelectTotalPagesForChannel,
|
||||
makeSelectNsfwCountFromUris,
|
||||
makeSelectNsfwCountForChannel,
|
||||
makeSelectOmittedCountForChannel,
|
||||
makeSelectClaimIsNsfw,
|
||||
makeSelectChannelForClaimUri,
|
||||
|
@ -217,7 +220,6 @@ export {
|
|||
makeSelectMyChannelPermUrlForName,
|
||||
makeSelectClaimIsPending,
|
||||
makeSelectReflectingClaimForUri,
|
||||
makeSelectClaimsInChannelForCurrentPageState,
|
||||
makeSelectShortUrlForUri,
|
||||
makeSelectCanonicalUrlForUri,
|
||||
makeSelectPermanentUrlForUri,
|
||||
|
|
|
@ -117,6 +117,7 @@ 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),
|
||||
|
|
|
@ -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,6 +12,11 @@ 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.
|
||||
|
@ -144,11 +149,11 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) {
|
|||
throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator }));
|
||||
}
|
||||
|
||||
if (modSeperator === '#') {
|
||||
if (modSeperator === MOD_CLAIM_ID_SEPARATOR || MOD_CLAIM_ID_SEPARATOR_OLD) {
|
||||
claimId = modValue;
|
||||
} else if (modSeperator === ':') {
|
||||
} else if (modSeperator === MOD_SEQUENCE_SEPARATOR) {
|
||||
claimSequence = modValue;
|
||||
} else if (modSeperator === '$') {
|
||||
} else if (modSeperator === MOD_BID_POSITION_SEPARATOR) {
|
||||
bidPosition = modValue;
|
||||
}
|
||||
}
|
||||
|
@ -320,3 +325,22 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
selectClaimsByUri,
|
||||
selectMyChannelClaims,
|
||||
selectPendingIds,
|
||||
selectPendingClaimsById,
|
||||
} from 'redux/selectors/claims';
|
||||
|
||||
import { doFetchTxoPage } from 'redux/actions/wallet';
|
||||
|
@ -20,6 +21,7 @@ import { createNormalizedClaimSearchKey } from 'util/claim';
|
|||
import { PAGE_SIZE } from 'constants/claim';
|
||||
import {
|
||||
selectPendingCollections,
|
||||
makeSelectClaimIdsForCollectionId,
|
||||
} from 'redux/selectors/collections';
|
||||
import {
|
||||
doFetchItemsInCollection,
|
||||
|
@ -27,6 +29,9 @@ import {
|
|||
doCollectionDelete,
|
||||
} from 'redux/actions/collections';
|
||||
|
||||
let onChannelConfirmCallback;
|
||||
let checkPendingInterval;
|
||||
|
||||
export function doResolveUris(
|
||||
uris: Array<string>,
|
||||
returnCachedClaims: boolean = false,
|
||||
|
@ -402,7 +407,7 @@ export function doClearChannelErrors() {
|
|||
};
|
||||
}
|
||||
|
||||
export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) {
|
||||
export function doCreateChannel(name: string, amount: number, optionalParams: any, onConfirm: any) {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({
|
||||
type: ACTIONS.CREATE_CHANNEL_STARTED,
|
||||
|
@ -469,7 +474,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an
|
|||
claims: [channelClaim],
|
||||
},
|
||||
});
|
||||
dispatch(doCheckPendingClaims(cb));
|
||||
dispatch(doCheckPendingClaims(onConfirm));
|
||||
return channelClaim;
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -826,7 +831,8 @@ export function doCollectionPublish(
|
|||
};
|
||||
}
|
||||
|
||||
export function doCollectionPublishUpdate(options: {
|
||||
export function doCollectionPublishUpdate(
|
||||
options: {
|
||||
bid?: string,
|
||||
blocking?: true,
|
||||
title?: string,
|
||||
|
@ -836,8 +842,11 @@ export function doCollectionPublishUpdate(options: {
|
|||
tags?: Array<Tag>,
|
||||
languages?: Array<string>,
|
||||
claims?: Array<string>,
|
||||
}) {
|
||||
return (dispatch: Dispatch): Promise<any> => {
|
||||
channel_id?: string,
|
||||
},
|
||||
isBackgroundUpdate?: boolean
|
||||
) {
|
||||
return (dispatch: Dispatch, getState: GetState): Promise<any> => {
|
||||
// TODO: implement one click update
|
||||
|
||||
const updateParams: {
|
||||
|
@ -845,13 +854,21 @@ export function doCollectionPublishUpdate(options: {
|
|||
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,
|
||||
|
@ -862,15 +879,24 @@ export function doCollectionPublishUpdate(options: {
|
|||
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;
|
||||
}
|
||||
|
||||
if (options.tags) {
|
||||
updateParams['tags'] = options.tags.map(tag => tag.name);
|
||||
}
|
||||
|
||||
if (options.claims) {
|
||||
updateParams['claims'] = options.claims;
|
||||
if (options.channel_id) {
|
||||
updateParams['channel_id'] = options.channel_id;
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
dispatch({
|
||||
type: ACTIONS.COLLECTION_PUBLISH_UPDATE_STARTED,
|
||||
|
@ -895,7 +921,6 @@ export function doCollectionPublishUpdate(options: {
|
|||
},
|
||||
});
|
||||
dispatch(doCheckPendingClaims());
|
||||
dispatch(doFetchCollectionListMine(1, 10));
|
||||
return resolve(collectionClaim);
|
||||
}
|
||||
|
||||
|
@ -975,52 +1000,71 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) {
|
|||
};
|
||||
}
|
||||
|
||||
export const doCheckPendingClaims = (onConfirmed: Function) => (
|
||||
export const doCheckPendingClaims = (onChannelConfirmed: Function) => (
|
||||
dispatch: Dispatch,
|
||||
getState: GetState
|
||||
) => {
|
||||
let claimCheckInterval;
|
||||
|
||||
const checkClaimList = () => {
|
||||
if (onChannelConfirmed) {
|
||||
onChannelConfirmCallback = onChannelConfirmed;
|
||||
}
|
||||
clearInterval(checkPendingInterval);
|
||||
const checkTxoList = () => {
|
||||
const state = getState();
|
||||
const pendingIdSet = new Set(selectPendingIds(state));
|
||||
const pendingById = Object.assign({}, selectPendingClaimsById(state));
|
||||
const pendingTxos = (Object.values(pendingById): any).map(p => p.txid);
|
||||
// use collections
|
||||
const pendingCollections = selectPendingCollections(state);
|
||||
Lbry.claim_list({ page: 1, page_size: 10 })
|
||||
if (pendingTxos.length) {
|
||||
Lbry.txo_list({ txid: pendingTxos })
|
||||
.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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
});
|
||||
if (claimsToConfirm.length) {
|
||||
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: claimsToConfirm,
|
||||
claims: claims,
|
||||
pending: pendingById,
|
||||
},
|
||||
});
|
||||
}
|
||||
return pendingIdSet.size;
|
||||
if (collectionIds.length) {
|
||||
dispatch(
|
||||
doFetchItemsInCollections({
|
||||
collectionIds,
|
||||
})
|
||||
.then(len => {
|
||||
if (!len) {
|
||||
clearInterval(claimCheckInterval);
|
||||
);
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
claimCheckInterval = setInterval(() => {
|
||||
checkClaimList();
|
||||
// do something with onConfirmed (typically get blocklist for channel)
|
||||
checkPendingInterval = setInterval(() => {
|
||||
checkTxoList();
|
||||
}, 30000);
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ const getTimestamp = () => {
|
|||
return Math.floor(Date.now() / 1000);
|
||||
};
|
||||
|
||||
const FETCH_BATCH_SIZE = 10;
|
||||
const FETCH_BATCH_SIZE = 50;
|
||||
|
||||
export const doLocalCollectionCreate = (
|
||||
name: string,
|
||||
|
@ -165,6 +165,7 @@ export const doFetchItemsInCollections = (
|
|||
claim_ids: claim.value.claims,
|
||||
page: i + 1,
|
||||
page_size: batchSize,
|
||||
no_totals: true,
|
||||
});
|
||||
}
|
||||
const itemsInBatches = await Promise.all(batches);
|
||||
|
|
|
@ -69,7 +69,8 @@ export const doUploadThumbnail = (
|
|||
thumbnailBlob?: File,
|
||||
fsAdapter?: any,
|
||||
fs?: any,
|
||||
path?: any
|
||||
path?: any,
|
||||
cb?: (string) => void
|
||||
) => (dispatch: Dispatch) => {
|
||||
const downMessage = __('Thumbnail upload service may be down, try again later.');
|
||||
let thumbnail, fileExt, fileName, fileType;
|
||||
|
@ -112,15 +113,17 @@ export const doUploadThumbnail = (
|
|||
.then(res => res.text())
|
||||
.then(text => (text.length ? JSON.parse(text) : {}))
|
||||
.then(json => {
|
||||
return json.success
|
||||
? dispatch({
|
||||
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,
|
||||
},
|
||||
})
|
||||
: uploadError(json.message || downMessage);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
let message = err.message;
|
||||
|
|
|
@ -14,6 +14,7 @@ type SharedData = {
|
|||
app_welcome_version?: number,
|
||||
sharing_3P?: boolean,
|
||||
unpublishedCollections: CollectionGroup,
|
||||
editedCollections: CollectionGroup,
|
||||
builtinCollections: CollectionGroup,
|
||||
savedCollections: Array<string>,
|
||||
},
|
||||
|
@ -31,6 +32,7 @@ function extractUserState(rawObj: SharedData) {
|
|||
app_welcome_version,
|
||||
sharing_3P,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
builtinCollections,
|
||||
savedCollections,
|
||||
} = rawObj.value;
|
||||
|
@ -45,6 +47,7 @@ function extractUserState(rawObj: SharedData) {
|
|||
...(app_welcome_version ? { app_welcome_version } : {}),
|
||||
...(sharing_3P ? { sharing_3P } : {}),
|
||||
...(unpublishedCollections ? { unpublishedCollections } : {}),
|
||||
...(editedCollections ? { editedCollections } : {}),
|
||||
...(builtinCollections ? { builtinCollections } : {}),
|
||||
...(savedCollections ? { savedCollections } : {}),
|
||||
};
|
||||
|
@ -65,6 +68,7 @@ export function doPopulateSharedUserState(sharedSettings: any) {
|
|||
app_welcome_version,
|
||||
sharing_3P,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
builtinCollections,
|
||||
savedCollections,
|
||||
} = extractUserState(sharedSettings);
|
||||
|
@ -80,6 +84,7 @@ export function doPopulateSharedUserState(sharedSettings: any) {
|
|||
welcomeVersion: app_welcome_version,
|
||||
allowAnalytics: sharing_3P,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
builtinCollections,
|
||||
savedCollections,
|
||||
},
|
||||
|
|
|
@ -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: {},
|
||||
pendingIds: [],
|
||||
pendingById: {},
|
||||
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 pendingIds = state.pendingIds;
|
||||
const pendingById = state.pendingById;
|
||||
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 (pendingIds.includes(stream.claim_id)) {
|
||||
if (pendingById[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 (pendingIds.includes(channel.claim_id)) {
|
||||
if (pendingById[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 (pendingIds.includes(collection.claim_id)) {
|
||||
if (pendingById[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 && !pendingIds.includes(byUri[url])) {
|
||||
if (!stream && !channel && !collection && !pendingById[byUri[url]]) {
|
||||
byUri[url] = null;
|
||||
}
|
||||
});
|
||||
|
@ -230,34 +230,33 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State =>
|
|||
});
|
||||
|
||||
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => {
|
||||
const { result, resolve }: { result: ClaimListResponse, resolve: boolean } = action.data;
|
||||
const { result }: { result: ClaimListResponse } = 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 pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myClaimIds = new Set(state.myClaims);
|
||||
let urlsForCurrentPage = [];
|
||||
|
||||
const pendingIdSet = new Set(pendingIds);
|
||||
|
||||
claims.forEach((claim: Claim) => {
|
||||
const { permanent_url: permanentUri, claim_id: claimId } = claim;
|
||||
const { permanent_url: permanentUri, claim_id: claimId, canonical_url: canonicalUri } = claim;
|
||||
if (claim.type && claim.type.match(/claim|update/)) {
|
||||
urlsForCurrentPage.push(permanentUri);
|
||||
if (claim.confirmations < 1) {
|
||||
pendingIdSet.add(claimId);
|
||||
} else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) {
|
||||
pendingIdSet.delete(claimId);
|
||||
}
|
||||
if (pendingIds.includes(claimId)) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaim(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
byUri[permanentUri] = claimId;
|
||||
byUri[canonicalUri] = claimId;
|
||||
myClaimIds.add(claimId);
|
||||
}
|
||||
});
|
||||
|
@ -266,7 +265,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any):
|
|||
isFetchingClaimListMine: false,
|
||||
myClaims: Array.from(myClaimIds),
|
||||
byId,
|
||||
pendingIds: Array.from(pendingIdSet),
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
myClaimsPageResults: urlsForCurrentPage,
|
||||
myClaimsPageNumber: page,
|
||||
|
@ -279,9 +278,8 @@ 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 pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myChannelClaims;
|
||||
const byId = Object.assign({}, state.byId);
|
||||
const byUri = Object.assign({}, state.claimsByUri);
|
||||
|
@ -295,7 +293,12 @@ 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 } = claim;
|
||||
const {
|
||||
canonical_url: canonicalUrl,
|
||||
permanent_url: permanentUrl,
|
||||
claim_id: claimId,
|
||||
confirmations,
|
||||
} = claim;
|
||||
|
||||
byUri[canonicalUrl] = claimId;
|
||||
byUri[permanentUrl] = claimId;
|
||||
|
@ -304,7 +307,14 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
|
|||
|
||||
// $FlowFixMe
|
||||
myChannelClaims.add(claimId);
|
||||
if (!pendingIds.some(c => c === claimId)) {
|
||||
if (confirmations < 1) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaim(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
myClaimIds.add(claimId);
|
||||
|
@ -313,6 +323,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
|
|||
|
||||
return Object.assign({}, state, {
|
||||
byId,
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
channelClaimCounts,
|
||||
fetchingMyChannels: false,
|
||||
|
@ -336,7 +347,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 pendingIds = state.pendingIds || [];
|
||||
const pendingById = Object.assign({}, state.pendingById);
|
||||
let myCollectionClaimsSet = new Set([]);
|
||||
const byId = Object.assign({}, state.byId);
|
||||
const byUri = Object.assign({}, state.claimsByUri);
|
||||
|
@ -345,7 +356,12 @@ 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 } = claim;
|
||||
const {
|
||||
canonical_url: canonicalUrl,
|
||||
permanent_url: permanentUrl,
|
||||
claim_id: claimId,
|
||||
confirmations,
|
||||
} = claim;
|
||||
|
||||
byUri[canonicalUrl] = claimId;
|
||||
byUri[permanentUrl] = claimId;
|
||||
|
@ -353,7 +369,14 @@ 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 (!pendingIds.some(c => c === claimId)) {
|
||||
if (confirmations < 1) {
|
||||
pendingById[claimId] = claim;
|
||||
if (byId[claimId]) {
|
||||
byId[claimId] = mergeClaim(claim, byId[claimId]);
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
} else {
|
||||
byId[claimId] = claim;
|
||||
}
|
||||
myClaimIds.add(claimId);
|
||||
|
@ -363,6 +386,7 @@ reducers[ACTIONS.FETCH_COLLECTION_LIST_COMPLETED] = (state: State, action: any):
|
|||
return {
|
||||
...state,
|
||||
byId,
|
||||
pendingById,
|
||||
claimsByUri: byUri,
|
||||
fetchingMyCollections: false,
|
||||
myCollectionClaims: Array.from(myCollectionClaimsSet),
|
||||
|
@ -455,9 +479,8 @@ 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);
|
||||
|
||||
|
@ -465,7 +488,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;
|
||||
pendingIdSet.add(claimId);
|
||||
pendingById[claimId] = claim; // make sure we don't need to merge?
|
||||
const oldClaim = byId[claimId];
|
||||
if (oldClaim && oldClaim.canonical_url) {
|
||||
newClaim = mergeClaim(oldClaim, claim);
|
||||
|
@ -485,21 +508,22 @@ 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 }: { claims: Array<Claim> } = action.data;
|
||||
const {
|
||||
claims: confirmedClaims,
|
||||
pending: pendingClaims,
|
||||
}: { claims: Array<Claim>, pending: { [string]: 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 { permanent_url: permanentUri, claim_id: claimId, type } = claim;
|
||||
const { claim_id: claimId, type } = claim;
|
||||
let newClaim = claim;
|
||||
const oldClaim = byId[claimId];
|
||||
if (oldClaim && oldClaim.canonical_url) {
|
||||
|
@ -507,11 +531,10 @@ 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, {
|
||||
pendingIds: Array.from(pendingIdSet),
|
||||
pendingById: pendingClaims,
|
||||
byId,
|
||||
claimsByUri: byUri,
|
||||
});
|
||||
|
|
|
@ -90,8 +90,15 @@ const collectionsReducer = handleActions(
|
|||
|
||||
[ACTIONS.COLLECTION_PENDING]: (state, action) => {
|
||||
const { localId, claimId } = action.data;
|
||||
const { edited: editList, unpublished: unpublishedList, pending: pendingList } = state;
|
||||
const {
|
||||
resolved: resolvedList,
|
||||
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);
|
||||
|
||||
|
@ -101,7 +108,10 @@ const collectionsReducer = handleActions(
|
|||
delete newUnpublishedList[localId];
|
||||
} else {
|
||||
// edit update
|
||||
newPendingList[claimId] = Object.assign({}, newEditList[claimId]);
|
||||
newPendingList[claimId] = Object.assign(
|
||||
{},
|
||||
newEditList[claimId] || newResolvedList[claimId]
|
||||
);
|
||||
delete newEditList[claimId];
|
||||
}
|
||||
|
||||
|
@ -158,9 +168,15 @@ const collectionsReducer = handleActions(
|
|||
});
|
||||
},
|
||||
[ACTIONS.USER_STATE_POPULATE]: (state, action) => {
|
||||
const { builtinCollections, savedCollections, unpublishedCollections } = action.data;
|
||||
const {
|
||||
builtinCollections,
|
||||
savedCollections,
|
||||
unpublishedCollections,
|
||||
editedCollections,
|
||||
} = action.data;
|
||||
return {
|
||||
...state,
|
||||
edited: editedCollections || state.edited,
|
||||
unpublished: unpublishedCollections || state.unpublished,
|
||||
builtin: builtinCollections || state.builtin,
|
||||
saved: savedCollections || state.saved,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { normalizeURI, buildURI, parseURI } from 'lbryURI';
|
||||
import { normalizeURI, parseURI } from 'lbryURI';
|
||||
import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
|
||||
import { createSelector } from 'reselect';
|
||||
import { isClaimNsfw, filterClaims } from 'util/claim';
|
||||
|
@ -7,11 +7,24 @@ import * as CLAIM from 'constants/claim';
|
|||
|
||||
const selectState = state => state.claims || {};
|
||||
|
||||
export const selectClaimsById = createSelector(
|
||||
export const selectById = 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 || {}
|
||||
|
@ -72,33 +85,33 @@ export const selectAllClaimsByChannel = createSelector(
|
|||
|
||||
export const selectPendingIds = createSelector(
|
||||
selectState,
|
||||
state => state.pendingIds || []
|
||||
state => Object.keys(state.pendingById) || []
|
||||
);
|
||||
|
||||
export const selectPendingClaims = createSelector(
|
||||
selectPendingIds,
|
||||
selectClaimsById,
|
||||
(pendingIds, byId) => pendingIds.map(id => byId[id])
|
||||
selectPendingClaimsById,
|
||||
pendingById => Object.values(pendingById)
|
||||
);
|
||||
|
||||
export const makeSelectClaimIsPending = (uri: string) =>
|
||||
createSelector(
|
||||
selectClaimIdsByUri,
|
||||
selectPendingIds,
|
||||
(idsByUri, pendingIds) => {
|
||||
selectPendingClaimsById,
|
||||
(idsByUri, pendingById) => {
|
||||
const claimId = idsByUri[normalizeURI(uri)];
|
||||
|
||||
if (claimId) {
|
||||
return pendingIds.some(i => i === claimId);
|
||||
return Boolean(pendingById[claimId]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectClaimIdIsPending = (claimId: string) => createSelector(
|
||||
selectPendingIds,
|
||||
(pendingIds) => {
|
||||
return pendingIds.some(i => i === claimId);
|
||||
export const makeSelectClaimIdIsPending = (claimId: string) =>
|
||||
createSelector(
|
||||
selectPendingClaimsById,
|
||||
pendingById => {
|
||||
return Boolean(pendingById[claimId]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -152,7 +165,7 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true)
|
|||
|
||||
return {
|
||||
...repostedClaim,
|
||||
repost_url: uri,
|
||||
repost_url: normalizeURI(uri),
|
||||
repost_channel_url: channelUrl,
|
||||
repost_bid_amount: claim && claim.meta && claim.meta.effective_amount,
|
||||
};
|
||||
|
@ -325,6 +338,7 @@ export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) =>
|
|||
}
|
||||
);
|
||||
|
||||
// THIS IS LEFT OVER FROM ONE TAB CHANNEL_CONTENT
|
||||
export const makeSelectTotalClaimsInChannelSearch = (uri: string) =>
|
||||
createSelector(
|
||||
selectClaimsById,
|
||||
|
@ -335,6 +349,7 @@ export const makeSelectTotalClaimsInChannelSearch = (uri: string) =>
|
|||
}
|
||||
);
|
||||
|
||||
// THIS IS LEFT OVER FROM ONE_TAB CHANNEL CONTENT
|
||||
export const makeSelectTotalPagesInChannelSearch = (uri: string) =>
|
||||
createSelector(
|
||||
selectClaimsById,
|
||||
|
@ -345,21 +360,6 @@ 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,7 +500,9 @@ 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(
|
||||
|
@ -608,31 +610,18 @@ export const selectChannelClaimCounts = createSelector(
|
|||
|
||||
export const makeSelectPendingClaimForUri = (uri: string) =>
|
||||
createSelector(
|
||||
selectPendingIds,
|
||||
selectClaimsById,
|
||||
(pending, claims) => {
|
||||
let validUri;
|
||||
let uriIsChannel;
|
||||
selectPendingClaimsById,
|
||||
pendingById => {
|
||||
let uriStreamName;
|
||||
let uriChannelName;
|
||||
try {
|
||||
({
|
||||
isChannel: uriIsChannel,
|
||||
streamName: uriStreamName,
|
||||
channelName: uriChannelName,
|
||||
} = parseURI(uri));
|
||||
validUri = true;
|
||||
({ streamName: uriStreamName, channelName: uriChannelName } = parseURI(uri));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
const pendingClaims = (Object.values(pendingById): any);
|
||||
const matchingClaim = pendingClaims.find((claim: GenericClaim) => {
|
||||
return claim.normalized_name === uriChannelName || claim.normalized_name === uriStreamName;
|
||||
});
|
||||
return matchingClaim || null;
|
||||
}
|
||||
|
@ -641,13 +630,13 @@ export const makeSelectPendingClaimForUri = (uri: string) =>
|
|||
export const makeSelectTotalItemsForChannel = (uri: string) =>
|
||||
createSelector(
|
||||
selectChannelClaimCounts,
|
||||
byUri => byUri && byUri[uri]
|
||||
byUri => byUri && byUri[normalizeURI(uri)]
|
||||
);
|
||||
|
||||
export const makeSelectTotalPagesForChannel = (uri: string, pageSize: number = 10) =>
|
||||
createSelector(
|
||||
selectChannelClaimCounts,
|
||||
byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize)
|
||||
byUri => byUri && byUri[uri] && Math.ceil(byUri[normalizeURI(uri)] / pageSize)
|
||||
);
|
||||
|
||||
export const makeSelectNsfwCountFromUris = (uris: Array<string>) =>
|
||||
|
@ -663,27 +652,6 @@ 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),
|
||||
|
@ -763,14 +731,6 @@ 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 || {}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @flow
|
||||
import fromEntries from '@ungap/from-entries';
|
||||
import { createSelector } from 'reselect';
|
||||
import {
|
||||
selectMyCollectionIds,
|
||||
|
@ -79,7 +80,7 @@ export const selectMyPublishedCollections = createSelector(
|
|||
selectMyCollectionIds,
|
||||
(resolved, pending, edited, myIds) => {
|
||||
// all resolved in myIds, plus those in pending and edited
|
||||
const myPublishedCollections = Object.fromEntries(
|
||||
const myPublishedCollections = fromEntries(
|
||||
Object.entries(pending).concat(
|
||||
Object.entries(resolved).filter(
|
||||
([key, val]) =>
|
||||
|
@ -100,7 +101,7 @@ export const selectMyPublishedCollections = createSelector(
|
|||
export const selectMyPublishedMixedCollections = createSelector(
|
||||
selectMyPublishedCollections,
|
||||
published => {
|
||||
const myCollections = Object.fromEntries(
|
||||
const myCollections = fromEntries(
|
||||
// $FlowFixMe
|
||||
Object.entries(published).filter(([key, collection]) => {
|
||||
// $FlowFixMe
|
||||
|
@ -114,7 +115,7 @@ export const selectMyPublishedMixedCollections = createSelector(
|
|||
export const selectMyPublishedPlaylistCollections = createSelector(
|
||||
selectMyPublishedCollections,
|
||||
published => {
|
||||
const myCollections = Object.fromEntries(
|
||||
const myCollections = fromEntries(
|
||||
// $FlowFixMe
|
||||
Object.entries(published).filter(([key, collection]) => {
|
||||
// $FlowFixMe
|
||||
|
@ -135,7 +136,7 @@ export const makeSelectMyPublishedCollectionForId = (id: string) =>
|
|||
// selectResolvedCollections,
|
||||
// selectSavedCollectionIds,
|
||||
// (resolved, myIds) => {
|
||||
// const mySavedCollections = Object.fromEntries(
|
||||
// const mySavedCollections = fromEntries(
|
||||
// Object.entries(resolved).filter(([key, val]) => myIds.includes(key))
|
||||
// );
|
||||
// return mySavedCollections;
|
||||
|
@ -158,11 +159,33 @@ export const makeSelectCollectionForId = (id: string) =>
|
|||
selectMyEditedCollections,
|
||||
selectPendingCollections,
|
||||
(bLists, rLists, uLists, eLists, pLists) => {
|
||||
const collection = bLists[id] || uLists[id] || eLists[id] || rLists[id] || pLists[id];
|
||||
const collection = bLists[id] || uLists[id] || eLists[id] || pLists[id] || rLists[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),
|
||||
|
@ -190,14 +213,18 @@ export const makeSelectClaimIdsForCollectionId = (id: string) =>
|
|||
|
||||
export const makeSelectIndexForUrlInCollection = (url: string, id: string) =>
|
||||
createSelector(
|
||||
state => state.content.shuffleList,
|
||||
makeSelectUrlsForCollectionId(id),
|
||||
makeSelectClaimForUri(url),
|
||||
(urls, claim) => {
|
||||
const index = urls && urls.findIndex(u => u === url);
|
||||
(shuffleState, urls, claim) => {
|
||||
const shuffleUrls = shuffleState && shuffleState.collectionId === id && shuffleState.newUrls;
|
||||
const listUrls = shuffleUrls || urls;
|
||||
|
||||
const index = listUrls && listUrls.findIndex(u => u === url);
|
||||
if (index > -1) {
|
||||
return index;
|
||||
} else if (claim) {
|
||||
const index = urls && urls.findIndex(u => u === claim.permanent_url);
|
||||
const index = listUrls && listUrls.findIndex(u => u === claim.permanent_url);
|
||||
if (index > -1) return index;
|
||||
return claim;
|
||||
}
|
||||
|
@ -205,20 +232,49 @@ 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),
|
||||
(index, claims, urls) => {
|
||||
(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
|
||||
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')
|
||||
);
|
||||
let remainingUrls = listUrls.slice(index + 1);
|
||||
if (!remainingUrls.length && loopList) {
|
||||
remainingUrls = listUrls.slice(0);
|
||||
}
|
||||
const nextUrl = remainingUrls && remainingUrls[0];
|
||||
return nextUrl || null;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -242,7 +298,13 @@ export const makeSelectCountForCollectionId = (id: string) =>
|
|||
if (collection.itemCount !== undefined) {
|
||||
return collection.itemCount;
|
||||
}
|
||||
return collection.items.length;
|
||||
let itemCount = 0;
|
||||
collection.items.map(item => {
|
||||
if (item) {
|
||||
itemCount += 1;
|
||||
}
|
||||
});
|
||||
return itemCount;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1411,6 +1411,11 @@
|
|||
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"
|
||||
|
|
Loading…
Reference in a new issue