commit
d87e594fe9
22 changed files with 1801 additions and 1115 deletions
|
@ -25,6 +25,8 @@
|
||||||
"import/no-commonjs": "warn",
|
"import/no-commonjs": "warn",
|
||||||
"import/no-amd": "warn",
|
"import/no-amd": "warn",
|
||||||
"import/prefer-default-export": "ignore",
|
"import/prefer-default-export": "ignore",
|
||||||
"func-names": ["warn", "as-needed"]
|
"flowtype/generic-spacing": 0,
|
||||||
|
"func-names": ["warn", "as-needed"],
|
||||||
|
"no-plusplus": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
569
dist/bundle.es.js
vendored
569
dist/bundle.es.js
vendored
|
@ -213,6 +213,13 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => {
|
||||||
auth_token: token,
|
auth_token: token,
|
||||||
...params
|
...params
|
||||||
};
|
};
|
||||||
|
Object.keys(fullParams).forEach(key => {
|
||||||
|
const value = fullParams[key];
|
||||||
|
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
fullParams[key] = JSON.stringify(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
const qs = querystring.stringify(fullParams);
|
const qs = querystring.stringify(fullParams);
|
||||||
let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`;
|
let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`;
|
||||||
let options = {
|
let options = {
|
||||||
|
@ -371,7 +378,7 @@ Lbryio.setOverride = (methodName, newMethod) => {
|
||||||
const rewards = {};
|
const rewards = {};
|
||||||
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
|
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
|
||||||
rewards.TYPE_NEW_USER = 'new_user';
|
rewards.TYPE_NEW_USER = 'new_user';
|
||||||
rewards.TYPE_CONFIRM_EMAIL = 'verified_email';
|
rewards.TYPE_CONFIRM_EMAIL = 'email_provided';
|
||||||
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
|
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
|
||||||
rewards.TYPE_FIRST_STREAM = 'first_stream';
|
rewards.TYPE_FIRST_STREAM = 'first_stream';
|
||||||
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
|
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
|
||||||
|
@ -628,6 +635,273 @@ var subscriptions = handleActions({
|
||||||
})
|
})
|
||||||
}, defaultState);
|
}, defaultState);
|
||||||
|
|
||||||
|
function swapKeyAndValue(dict) {
|
||||||
|
const ret = {}; // eslint-disable-next-line no-restricted-syntax
|
||||||
|
|
||||||
|
for (const key in dict) {
|
||||||
|
if (dict.hasOwnProperty(key)) {
|
||||||
|
ret[dict[key]] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectState = state => state.subscriptions || {}; // Returns the list of channel uris a user is subscribed to
|
||||||
|
|
||||||
|
|
||||||
|
const selectSubscriptions = reselect.createSelector(selectState, state => state.subscriptions); // Fetching list of users subscriptions
|
||||||
|
|
||||||
|
const selectIsFetchingSubscriptions = reselect.createSelector(selectState, state => state.loading); // The current view mode on the subscriptions page
|
||||||
|
|
||||||
|
const selectViewMode = reselect.createSelector(selectState, state => state.viewMode); // Suggested subscriptions from internal apis
|
||||||
|
|
||||||
|
const selectSuggested = reselect.createSelector(selectState, state => state.suggested);
|
||||||
|
const selectIsFetchingSuggested = reselect.createSelector(selectState, state => state.loadingSuggested);
|
||||||
|
const selectSuggestedChannels = reselect.createSelector(selectSubscriptions, selectSuggested, (userSubscriptions, suggested) => {
|
||||||
|
if (!suggested) {
|
||||||
|
return null;
|
||||||
|
} // Swap the key/value because we will use the uri for everything, this just makes it easier
|
||||||
|
// suggested is returned from the api with the form:
|
||||||
|
// {
|
||||||
|
// featured: { "Channel label": uri, ... },
|
||||||
|
// top_subscribed: { "@channel": uri, ... }
|
||||||
|
// top_bid: { "@channel": uri, ... }
|
||||||
|
// }
|
||||||
|
// To properly compare the suggested subscriptions from our current subscribed channels
|
||||||
|
// We only care about the uri, not the label
|
||||||
|
// We also only care about top_subscribed and featured
|
||||||
|
// top_bid could just be porn or a channel with no content
|
||||||
|
|
||||||
|
|
||||||
|
const topSubscribedSuggestions = swapKeyAndValue(suggested[SUGGESTED_TOP_SUBSCRIBED]);
|
||||||
|
const featuredSuggestions = swapKeyAndValue(suggested[SUGGESTED_FEATURED]); // Make sure there are no duplicates
|
||||||
|
// If a uri isn't already in the suggested object, add it
|
||||||
|
|
||||||
|
const suggestedChannels = { ...topSubscribedSuggestions
|
||||||
|
};
|
||||||
|
Object.keys(featuredSuggestions).forEach(uri => {
|
||||||
|
if (!suggestedChannels[uri]) {
|
||||||
|
const channelLabel = featuredSuggestions[uri];
|
||||||
|
suggestedChannels[uri] = channelLabel;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userSubscriptions.forEach(({
|
||||||
|
uri
|
||||||
|
}) => {
|
||||||
|
// Note to passer bys:
|
||||||
|
// Maybe we should just remove the `lbry://` prefix from subscription uris
|
||||||
|
// Most places don't store them like that
|
||||||
|
const subscribedUri = uri.slice('lbry://'.length);
|
||||||
|
|
||||||
|
if (suggestedChannels[subscribedUri]) {
|
||||||
|
delete suggestedChannels[subscribedUri];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return Object.keys(suggestedChannels).map(uri => ({
|
||||||
|
uri,
|
||||||
|
label: suggestedChannels[uri]
|
||||||
|
})).slice(0, 5);
|
||||||
|
});
|
||||||
|
const selectFirstRunCompleted = reselect.createSelector(selectState, state => state.firstRunCompleted);
|
||||||
|
const selectShowSuggestedSubs = reselect.createSelector(selectState, state => state.showSuggestedSubs); // Fetching any claims that are a part of a users subscriptions
|
||||||
|
|
||||||
|
const selectSubscriptionsBeingFetched = reselect.createSelector(selectSubscriptions, lbryRedux.selectAllFetchingChannelClaims, (subscriptions, fetchingChannelClaims) => {
|
||||||
|
const fetchingSubscriptionMap = {};
|
||||||
|
subscriptions.forEach(sub => {
|
||||||
|
const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
|
||||||
|
|
||||||
|
if (isFetching) {
|
||||||
|
fetchingSubscriptionMap[sub.uri] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return fetchingSubscriptionMap;
|
||||||
|
});
|
||||||
|
const selectUnreadByChannel = reselect.createSelector(selectState, state => state.unread); // Returns the current total of unread subscriptions
|
||||||
|
|
||||||
|
const selectUnreadAmount = reselect.createSelector(selectUnreadByChannel, unreadByChannel => {
|
||||||
|
const unreadChannels = Object.keys(unreadByChannel);
|
||||||
|
let badges = 0;
|
||||||
|
|
||||||
|
if (!unreadChannels.length) {
|
||||||
|
return badges;
|
||||||
|
}
|
||||||
|
|
||||||
|
unreadChannels.forEach(channel => {
|
||||||
|
badges += unreadByChannel[channel].uris.length;
|
||||||
|
});
|
||||||
|
return badges;
|
||||||
|
}); // Returns the uris with channels as an array with the channel with the newest content first
|
||||||
|
// If you just want the `unread` state, use selectUnread
|
||||||
|
|
||||||
|
const selectUnreadSubscriptions = reselect.createSelector(selectUnreadAmount, selectUnreadByChannel, lbryRedux.selectClaimsByUri, (unreadAmount, unreadByChannel, claimsByUri) => {
|
||||||
|
// determine which channel has the newest content
|
||||||
|
const unreadList = [];
|
||||||
|
|
||||||
|
if (!unreadAmount) {
|
||||||
|
return unreadList;
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelUriList = Object.keys(unreadByChannel); // There is only one channel with unread notifications
|
||||||
|
|
||||||
|
if (unreadAmount === 1) {
|
||||||
|
channelUriList.forEach(channel => {
|
||||||
|
const unreadChannel = {
|
||||||
|
channel,
|
||||||
|
uris: unreadByChannel[channel].uris
|
||||||
|
};
|
||||||
|
unreadList.push(unreadChannel);
|
||||||
|
});
|
||||||
|
return unreadList;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelUriList.sort((channel1, channel2) => {
|
||||||
|
const latestUriFromChannel1 = unreadByChannel[channel1].uris[0];
|
||||||
|
const latestClaimFromChannel1 = claimsByUri[latestUriFromChannel1] || {};
|
||||||
|
const latestUriFromChannel2 = unreadByChannel[channel2].uris[0];
|
||||||
|
const latestClaimFromChannel2 = claimsByUri[latestUriFromChannel2] || {};
|
||||||
|
const latestHeightFromChannel1 = latestClaimFromChannel1.height || 0;
|
||||||
|
const latestHeightFromChannel2 = latestClaimFromChannel2.height || 0;
|
||||||
|
|
||||||
|
if (latestHeightFromChannel1 !== latestHeightFromChannel2) {
|
||||||
|
return latestHeightFromChannel2 - latestHeightFromChannel1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}).forEach(channel => {
|
||||||
|
const unreadSubscription = unreadByChannel[channel];
|
||||||
|
const unreadChannel = {
|
||||||
|
channel,
|
||||||
|
uris: unreadSubscription.uris
|
||||||
|
};
|
||||||
|
unreadList.push(unreadChannel);
|
||||||
|
});
|
||||||
|
return unreadList;
|
||||||
|
}); // Returns all unread subscriptions for a uri passed in
|
||||||
|
|
||||||
|
const makeSelectUnreadByChannel = uri => reselect.createSelector(selectUnreadByChannel, unread => unread[uri]); // Returns the first page of claims for every channel a user is subscribed to
|
||||||
|
|
||||||
|
const selectSubscriptionClaims = reselect.createSelector(lbryRedux.selectAllClaimsByChannel, lbryRedux.selectClaimsById, selectSubscriptions, selectUnreadByChannel, (channelIds, allClaims, savedSubscriptions, unreadByChannel) => {
|
||||||
|
// no claims loaded yet
|
||||||
|
if (!Object.keys(channelIds).length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetchedSubscriptions = [];
|
||||||
|
savedSubscriptions.forEach(subscription => {
|
||||||
|
let channelClaims = []; // if subscribed channel has content
|
||||||
|
|
||||||
|
if (channelIds[subscription.uri] && channelIds[subscription.uri]['1']) {
|
||||||
|
// This will need to be more robust, we will want to be able to load more than the first page
|
||||||
|
// Strip out any ids that will be shown as notifications
|
||||||
|
const pageOneChannelIds = channelIds[subscription.uri]['1']; // we have the channel ids and the corresponding claims
|
||||||
|
// loop over the list of ids and grab the claim
|
||||||
|
|
||||||
|
pageOneChannelIds.forEach(id => {
|
||||||
|
const grabbedClaim = allClaims[id];
|
||||||
|
|
||||||
|
if (unreadByChannel[subscription.uri] && unreadByChannel[subscription.uri].uris.some(uri => uri.includes(id))) {
|
||||||
|
grabbedClaim.isNew = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelClaims = channelClaims.concat([grabbedClaim]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchedSubscriptions = fetchedSubscriptions.concat(channelClaims);
|
||||||
|
});
|
||||||
|
return fetchedSubscriptions;
|
||||||
|
}); // Returns true if a user is subscribed to the channel associated with the uri passed in
|
||||||
|
// Accepts content or channel uris
|
||||||
|
|
||||||
|
const makeSelectIsSubscribed = uri => reselect.createSelector(selectSubscriptions, lbryRedux.makeSelectChannelForClaimUri(uri, true), (subscriptions, channelUri) => {
|
||||||
|
if (channelUri) {
|
||||||
|
return subscriptions.some(sub => sub.uri === channelUri);
|
||||||
|
} // If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
isChannel
|
||||||
|
} = lbryRedux.parseURI(uri);
|
||||||
|
|
||||||
|
if (isChannel) {
|
||||||
|
const uriWithPrefix = uri.startsWith('lbry://') ? uri : `lbry://${uri}`;
|
||||||
|
return subscriptions.some(sub => sub.uri === uriWithPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
const makeSelectIsNew = uri => reselect.createSelector(makeSelectIsSubscribed(uri), lbryRedux.makeSelectChannelForClaimUri(uri), selectUnreadByChannel, (isSubscribed, channel, unreadByChannel) => {
|
||||||
|
if (!isSubscribed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unreadForChannel = unreadByChannel[`lbry://${channel}`];
|
||||||
|
|
||||||
|
if (unreadForChannel) {
|
||||||
|
return unreadForChannel.uris.includes(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // If they are subscribed, check to see if this uri is in the list of unreads
|
||||||
|
});
|
||||||
|
const selectEnabledChannelNotifications = reselect.createSelector(selectState, state => state.enabledChannelNotifications);
|
||||||
|
|
||||||
|
const persistShape = {
|
||||||
|
version: '0',
|
||||||
|
shared: {}
|
||||||
|
};
|
||||||
|
function userStateSyncMiddleware() {
|
||||||
|
return ({
|
||||||
|
getState
|
||||||
|
}) => next => action => {
|
||||||
|
if (action.type === CHANNEL_SUBSCRIBE || action.type === CHANNEL_UNSUBSCRIBE || action.type === lbryRedux.ACTIONS.TOGGLE_TAG_FOLLOW) {
|
||||||
|
const newShape = { ...persistShape
|
||||||
|
};
|
||||||
|
const state = getState();
|
||||||
|
const subscriptions = selectSubscriptions(state).map(({
|
||||||
|
uri
|
||||||
|
}) => uri);
|
||||||
|
const tags = lbryRedux.selectFollowedTags(state);
|
||||||
|
newShape.shared.subscriptions = subscriptions;
|
||||||
|
newShape.shared.tags = tags;
|
||||||
|
const {
|
||||||
|
uri
|
||||||
|
} = action.data;
|
||||||
|
|
||||||
|
if (action.type === CHANNEL_SUBSCRIBE) {
|
||||||
|
const newSubscriptions = subscriptions.slice();
|
||||||
|
newSubscriptions.push(uri);
|
||||||
|
newShape.shared.subscriptions = newSubscriptions;
|
||||||
|
} else if (action.type === CHANNEL_UNSUBSCRIBE) {
|
||||||
|
let newSubscriptions = subscriptions.slice();
|
||||||
|
newSubscriptions = newSubscriptions.filter(subscribedUri => subscribedUri !== uri);
|
||||||
|
newShape.shared.subscriptions = newSubscriptions;
|
||||||
|
} else {
|
||||||
|
const toggledTag = action.data.name;
|
||||||
|
const followedTags = lbryRedux.selectFollowedTags(state).map(({
|
||||||
|
name
|
||||||
|
}) => name);
|
||||||
|
const isFollowing = lbryRedux.makeSelectIsFollowingTag(toggledTag)(state);
|
||||||
|
let newTags = followedTags.slice();
|
||||||
|
|
||||||
|
if (isFollowing) {
|
||||||
|
newTags = newTags.filter(followedTag => followedTag.name !== toggledTag);
|
||||||
|
} else {
|
||||||
|
newTags.push(toggledTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
newShape.shared.tags = newTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lbryio.call('user_settings', 'set', {
|
||||||
|
settings: newShape
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(action);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function doGenerateAuthToken(installationId) {
|
function doGenerateAuthToken(installationId) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -658,25 +932,25 @@ function doGenerateAuthToken(installationId) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectState = state => state.rewards || {};
|
const selectState$1 = state => state.rewards || {};
|
||||||
|
|
||||||
const selectUnclaimedRewardsByType = reselect.createSelector(selectState, state => state.unclaimedRewardsByType);
|
const selectUnclaimedRewardsByType = reselect.createSelector(selectState$1, state => state.unclaimedRewardsByType);
|
||||||
const selectClaimedRewardsById = reselect.createSelector(selectState, state => state.claimedRewardsById);
|
const selectClaimedRewardsById = reselect.createSelector(selectState$1, state => state.claimedRewardsById);
|
||||||
const selectClaimedRewards = reselect.createSelector(selectClaimedRewardsById, byId => Object.values(byId) || []);
|
const selectClaimedRewards = reselect.createSelector(selectClaimedRewardsById, byId => Object.values(byId) || []);
|
||||||
const selectClaimedRewardsByTransactionId = reselect.createSelector(selectClaimedRewards, rewards => rewards.reduce((mapParam, reward) => {
|
const selectClaimedRewardsByTransactionId = reselect.createSelector(selectClaimedRewards, rewards => rewards.reduce((mapParam, reward) => {
|
||||||
const map = mapParam;
|
const map = mapParam;
|
||||||
map[reward.transaction_id] = reward;
|
map[reward.transaction_id] = reward;
|
||||||
return map;
|
return map;
|
||||||
}, {}));
|
}, {}));
|
||||||
const selectUnclaimedRewards = reselect.createSelector(selectState, state => state.unclaimedRewards);
|
const selectUnclaimedRewards = reselect.createSelector(selectState$1, state => state.unclaimedRewards);
|
||||||
const selectFetchingRewards = reselect.createSelector(selectState, state => !!state.fetching);
|
const selectFetchingRewards = reselect.createSelector(selectState$1, state => !!state.fetching);
|
||||||
const selectUnclaimedRewardValue = reselect.createSelector(selectUnclaimedRewards, rewards => rewards.reduce((sum, reward) => sum + reward.reward_amount, 0));
|
const selectUnclaimedRewardValue = reselect.createSelector(selectUnclaimedRewards, rewards => rewards.reduce((sum, reward) => sum + reward.reward_amount, 0));
|
||||||
const selectClaimsPendingByType = reselect.createSelector(selectState, state => state.claimPendingByType);
|
const selectClaimsPendingByType = reselect.createSelector(selectState$1, state => state.claimPendingByType);
|
||||||
|
|
||||||
const selectIsClaimRewardPending = (state, props) => selectClaimsPendingByType(state, props)[props.reward_type];
|
const selectIsClaimRewardPending = (state, props) => selectClaimsPendingByType(state, props)[props.reward_type];
|
||||||
|
|
||||||
const makeSelectIsRewardClaimPending = () => reselect.createSelector(selectIsClaimRewardPending, isClaiming => isClaiming);
|
const makeSelectIsRewardClaimPending = () => reselect.createSelector(selectIsClaimRewardPending, isClaiming => isClaiming);
|
||||||
const selectClaimErrorsByType = reselect.createSelector(selectState, state => state.claimErrorsByType);
|
const selectClaimErrorsByType = reselect.createSelector(selectState$1, state => state.claimErrorsByType);
|
||||||
|
|
||||||
const selectClaimRewardError = (state, props) => selectClaimErrorsByType(state, props)[props.reward_type];
|
const selectClaimRewardError = (state, props) => selectClaimErrorsByType(state, props)[props.reward_type];
|
||||||
|
|
||||||
|
@ -686,38 +960,39 @@ const selectRewardByType = (state, rewardType) => selectUnclaimedRewards(state).
|
||||||
|
|
||||||
const makeSelectRewardByType = () => reselect.createSelector(selectRewardByType, reward => reward);
|
const makeSelectRewardByType = () => reselect.createSelector(selectRewardByType, reward => reward);
|
||||||
const makeSelectRewardAmountByType = () => reselect.createSelector(selectRewardByType, reward => reward ? reward.reward_amount : 0);
|
const makeSelectRewardAmountByType = () => reselect.createSelector(selectRewardByType, reward => reward ? reward.reward_amount : 0);
|
||||||
const selectRewardContentClaimIds = reselect.createSelector(selectState, state => state.rewardedContentClaimIds);
|
const selectRewardContentClaimIds = reselect.createSelector(selectState$1, state => state.rewardedContentClaimIds);
|
||||||
const selectReferralReward = reselect.createSelector(selectUnclaimedRewards, unclaimedRewards => unclaimedRewards.filter(reward => reward.reward_type === rewards.TYPE_REFERRAL)[0]);
|
const selectReferralReward = reselect.createSelector(selectUnclaimedRewards, unclaimedRewards => unclaimedRewards.filter(reward => reward.reward_type === rewards.TYPE_REFERRAL)[0]);
|
||||||
|
|
||||||
const selectState$1 = state => state.user || {};
|
const selectState$2 = state => state.user || {};
|
||||||
const selectAuthenticationIsPending = reselect.createSelector(selectState$1, state => state.authenticationIsPending);
|
const selectAuthenticationIsPending = reselect.createSelector(selectState$2, state => state.authenticationIsPending);
|
||||||
const selectUserIsPending = reselect.createSelector(selectState$1, state => state.userIsPending);
|
const selectUserIsPending = reselect.createSelector(selectState$2, state => state.userIsPending);
|
||||||
const selectUser = reselect.createSelector(selectState$1, state => state.user);
|
const selectUser = reselect.createSelector(selectState$2, state => state.user);
|
||||||
const selectUserEmail = reselect.createSelector(selectUser, user => user ? user.primary_email : null);
|
const selectUserEmail = reselect.createSelector(selectUser, user => user ? user.primary_email : null);
|
||||||
const selectUserPhone = reselect.createSelector(selectUser, user => user ? user.phone_number : null);
|
const selectUserPhone = reselect.createSelector(selectUser, user => user ? user.phone_number : null);
|
||||||
const selectUserCountryCode = reselect.createSelector(selectUser, user => user ? user.country_code : null);
|
const selectUserCountryCode = reselect.createSelector(selectUser, user => user ? user.country_code : null);
|
||||||
const selectEmailToVerify = reselect.createSelector(selectState$1, selectUserEmail, (state, userEmail) => state.emailToVerify || userEmail);
|
const selectEmailToVerify = reselect.createSelector(selectState$2, selectUserEmail, (state, userEmail) => state.emailToVerify || userEmail);
|
||||||
const selectPhoneToVerify = reselect.createSelector(selectState$1, selectUserPhone, (state, userPhone) => state.phoneToVerify || userPhone);
|
const selectPhoneToVerify = reselect.createSelector(selectState$2, selectUserPhone, (state, userPhone) => state.phoneToVerify || userPhone);
|
||||||
const selectUserIsRewardApproved = reselect.createSelector(selectUser, user => user && user.is_reward_approved);
|
const selectUserIsRewardApproved = reselect.createSelector(selectUser, user => user && user.is_reward_approved);
|
||||||
const selectEmailNewIsPending = reselect.createSelector(selectState$1, state => state.emailNewIsPending);
|
const selectEmailNewIsPending = reselect.createSelector(selectState$2, state => state.emailNewIsPending);
|
||||||
const selectEmailNewErrorMessage = reselect.createSelector(selectState$1, state => state.emailNewErrorMessage);
|
const selectEmailNewErrorMessage = reselect.createSelector(selectState$2, state => state.emailNewErrorMessage);
|
||||||
const selectPhoneNewErrorMessage = reselect.createSelector(selectState$1, state => state.phoneNewErrorMessage);
|
const selectPhoneNewErrorMessage = reselect.createSelector(selectState$2, state => state.phoneNewErrorMessage);
|
||||||
const selectEmailVerifyIsPending = reselect.createSelector(selectState$1, state => state.emailVerifyIsPending);
|
const selectEmailVerifyIsPending = reselect.createSelector(selectState$2, state => state.emailVerifyIsPending);
|
||||||
const selectEmailVerifyErrorMessage = reselect.createSelector(selectState$1, state => state.emailVerifyErrorMessage);
|
const selectEmailVerifyErrorMessage = reselect.createSelector(selectState$2, state => state.emailVerifyErrorMessage);
|
||||||
const selectPhoneNewIsPending = reselect.createSelector(selectState$1, state => state.phoneNewIsPending);
|
const selectPhoneNewIsPending = reselect.createSelector(selectState$2, state => state.phoneNewIsPending);
|
||||||
const selectPhoneVerifyIsPending = reselect.createSelector(selectState$1, state => state.phoneVerifyIsPending);
|
const selectPhoneVerifyIsPending = reselect.createSelector(selectState$2, state => state.phoneVerifyIsPending);
|
||||||
const selectPhoneVerifyErrorMessage = reselect.createSelector(selectState$1, state => state.phoneVerifyErrorMessage);
|
const selectPhoneVerifyErrorMessage = reselect.createSelector(selectState$2, state => state.phoneVerifyErrorMessage);
|
||||||
const selectIdentityVerifyIsPending = reselect.createSelector(selectState$1, state => state.identityVerifyIsPending);
|
const selectIdentityVerifyIsPending = reselect.createSelector(selectState$2, state => state.identityVerifyIsPending);
|
||||||
const selectIdentityVerifyErrorMessage = reselect.createSelector(selectState$1, state => state.identityVerifyErrorMessage);
|
const selectIdentityVerifyErrorMessage = reselect.createSelector(selectState$2, state => state.identityVerifyErrorMessage);
|
||||||
|
const selectUserVerifiedEmail = reselect.createSelector(selectUser, user => user && user.has_verified_email);
|
||||||
const selectUserIsVerificationCandidate = reselect.createSelector(selectUser, user => user && (!user.has_verified_email || !user.is_identity_verified));
|
const selectUserIsVerificationCandidate = reselect.createSelector(selectUser, user => user && (!user.has_verified_email || !user.is_identity_verified));
|
||||||
const selectAccessToken = reselect.createSelector(selectState$1, state => state.accessToken);
|
const selectAccessToken = reselect.createSelector(selectState$2, state => state.accessToken);
|
||||||
const selectUserInviteStatusIsPending = reselect.createSelector(selectState$1, state => state.inviteStatusIsPending);
|
const selectUserInviteStatusIsPending = reselect.createSelector(selectState$2, state => state.inviteStatusIsPending);
|
||||||
const selectUserInvitesRemaining = reselect.createSelector(selectState$1, state => state.invitesRemaining);
|
const selectUserInvitesRemaining = reselect.createSelector(selectState$2, state => state.invitesRemaining);
|
||||||
const selectUserInvitees = reselect.createSelector(selectState$1, state => state.invitees);
|
const selectUserInvitees = reselect.createSelector(selectState$2, state => state.invitees);
|
||||||
const selectUserInviteStatusFailed = reselect.createSelector(selectUserInvitesRemaining, () => selectUserInvitesRemaining === null);
|
const selectUserInviteStatusFailed = reselect.createSelector(selectUserInvitesRemaining, () => selectUserInvitesRemaining === null);
|
||||||
const selectUserInviteNewIsPending = reselect.createSelector(selectState$1, state => state.inviteNewIsPending);
|
const selectUserInviteNewIsPending = reselect.createSelector(selectState$2, state => state.inviteNewIsPending);
|
||||||
const selectUserInviteNewErrorMessage = reselect.createSelector(selectState$1, state => state.inviteNewErrorMessage);
|
const selectUserInviteNewErrorMessage = reselect.createSelector(selectState$2, state => state.inviteNewErrorMessage);
|
||||||
const selectUserInviteReferralLink = reselect.createSelector(selectState$1, state => state.referralLink);
|
const selectUserInviteReferralLink = reselect.createSelector(selectState$2, state => state.referralLink);
|
||||||
|
|
||||||
function doFetchInviteStatus() {
|
function doFetchInviteStatus() {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
|
@ -1121,16 +1396,16 @@ function doClaimRewardType(rewardType, options = {}) {
|
||||||
const unclaimedRewards = selectUnclaimedRewards(state);
|
const unclaimedRewards = selectUnclaimedRewards(state);
|
||||||
const reward = rewardType === rewards.TYPE_REWARD_CODE ? {
|
const reward = rewardType === rewards.TYPE_REWARD_CODE ? {
|
||||||
reward_type: rewards.TYPE_REWARD_CODE
|
reward_type: rewards.TYPE_REWARD_CODE
|
||||||
} : unclaimedRewards.find(ur => ur.reward_type === rewardType);
|
} : unclaimedRewards.find(ur => ur.reward_type === rewardType); // Try to claim the email reward right away, even if we haven't called reward_list yet
|
||||||
|
|
||||||
if (rewardType !== rewards.TYPE_REWARD_CODE) {
|
if (rewardType !== rewards.TYPE_REWARD_CODE || rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
||||||
if (!reward || reward.transaction_id) {
|
if (!reward || reward.transaction_id) {
|
||||||
// already claimed or doesn't exist, do nothing
|
// already claimed or doesn't exist, do nothing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL && rewardType !== rewards.TYPE_REWARD_CODE) {
|
||||||
if (!options || !options.failSilently && rewards.callbacks.rewardApprovalRequested) {
|
if (!options || !options.failSilently && rewards.callbacks.rewardApprovalRequested) {
|
||||||
rewards.callbacks.rewardApprovalRequested();
|
rewards.callbacks.rewardApprovalRequested();
|
||||||
}
|
}
|
||||||
|
@ -1163,6 +1438,10 @@ function doClaimRewardType(rewardType, options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(doRewardList());
|
dispatch(doRewardList());
|
||||||
|
|
||||||
|
if (options.callback) {
|
||||||
|
options.callback();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const failure = error => {
|
const failure = error => {
|
||||||
|
@ -1180,6 +1459,10 @@ function doClaimRewardType(rewardType, options = {}) {
|
||||||
isError: true
|
isError: true
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.callback) {
|
||||||
|
options.callback(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rewards.claimReward(rewardType, params).then(success, failure);
|
rewards.claimReward(rewardType, params).then(success, failure);
|
||||||
|
@ -1244,217 +1527,6 @@ function doFetchRewardedContent() {
|
||||||
|
|
||||||
const PAGE_SIZE = 20;
|
const PAGE_SIZE = 20;
|
||||||
|
|
||||||
function swapKeyAndValue(dict) {
|
|
||||||
const ret = {}; // eslint-disable-next-line no-restricted-syntax
|
|
||||||
|
|
||||||
for (const key in dict) {
|
|
||||||
if (dict.hasOwnProperty(key)) {
|
|
||||||
ret[dict[key]] = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectState$2 = state => state.subscriptions || {}; // Returns the list of channel uris a user is subscribed to
|
|
||||||
|
|
||||||
|
|
||||||
const selectSubscriptions = reselect.createSelector(selectState$2, state => state.subscriptions); // Fetching list of users subscriptions
|
|
||||||
|
|
||||||
const selectIsFetchingSubscriptions = reselect.createSelector(selectState$2, state => state.loading); // The current view mode on the subscriptions page
|
|
||||||
|
|
||||||
const selectViewMode = reselect.createSelector(selectState$2, state => state.viewMode); // Suggested subscriptions from internal apis
|
|
||||||
|
|
||||||
const selectSuggested = reselect.createSelector(selectState$2, state => state.suggested);
|
|
||||||
const selectIsFetchingSuggested = reselect.createSelector(selectState$2, state => state.loadingSuggested);
|
|
||||||
const selectSuggestedChannels = reselect.createSelector(selectSubscriptions, selectSuggested, (userSubscriptions, suggested) => {
|
|
||||||
if (!suggested) {
|
|
||||||
return null;
|
|
||||||
} // Swap the key/value because we will use the uri for everything, this just makes it easier
|
|
||||||
// suggested is returned from the api with the form:
|
|
||||||
// {
|
|
||||||
// featured: { "Channel label": uri, ... },
|
|
||||||
// top_subscribed: { "@channel": uri, ... }
|
|
||||||
// top_bid: { "@channel": uri, ... }
|
|
||||||
// }
|
|
||||||
// To properly compare the suggested subscriptions from our current subscribed channels
|
|
||||||
// We only care about the uri, not the label
|
|
||||||
// We also only care about top_subscribed and featured
|
|
||||||
// top_bid could just be porn or a channel with no content
|
|
||||||
|
|
||||||
|
|
||||||
const topSubscribedSuggestions = swapKeyAndValue(suggested[SUGGESTED_TOP_SUBSCRIBED]);
|
|
||||||
const featuredSuggestions = swapKeyAndValue(suggested[SUGGESTED_FEATURED]); // Make sure there are no duplicates
|
|
||||||
// If a uri isn't already in the suggested object, add it
|
|
||||||
|
|
||||||
const suggestedChannels = { ...topSubscribedSuggestions
|
|
||||||
};
|
|
||||||
Object.keys(featuredSuggestions).forEach(uri => {
|
|
||||||
if (!suggestedChannels[uri]) {
|
|
||||||
const channelLabel = featuredSuggestions[uri];
|
|
||||||
suggestedChannels[uri] = channelLabel;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
userSubscriptions.forEach(({
|
|
||||||
uri
|
|
||||||
}) => {
|
|
||||||
// Note to passer bys:
|
|
||||||
// Maybe we should just remove the `lbry://` prefix from subscription uris
|
|
||||||
// Most places don't store them like that
|
|
||||||
const subscribedUri = uri.slice('lbry://'.length);
|
|
||||||
|
|
||||||
if (suggestedChannels[subscribedUri]) {
|
|
||||||
delete suggestedChannels[subscribedUri];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Object.keys(suggestedChannels).map(uri => ({
|
|
||||||
uri,
|
|
||||||
label: suggestedChannels[uri]
|
|
||||||
})).slice(0, 5);
|
|
||||||
});
|
|
||||||
const selectFirstRunCompleted = reselect.createSelector(selectState$2, state => state.firstRunCompleted);
|
|
||||||
const selectShowSuggestedSubs = reselect.createSelector(selectState$2, state => state.showSuggestedSubs); // Fetching any claims that are a part of a users subscriptions
|
|
||||||
|
|
||||||
const selectSubscriptionsBeingFetched = reselect.createSelector(selectSubscriptions, lbryRedux.selectAllFetchingChannelClaims, (subscriptions, fetchingChannelClaims) => {
|
|
||||||
const fetchingSubscriptionMap = {};
|
|
||||||
subscriptions.forEach(sub => {
|
|
||||||
const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
|
|
||||||
|
|
||||||
if (isFetching) {
|
|
||||||
fetchingSubscriptionMap[sub.uri] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return fetchingSubscriptionMap;
|
|
||||||
});
|
|
||||||
const selectUnreadByChannel = reselect.createSelector(selectState$2, state => state.unread); // Returns the current total of unread subscriptions
|
|
||||||
|
|
||||||
const selectUnreadAmount = reselect.createSelector(selectUnreadByChannel, unreadByChannel => {
|
|
||||||
const unreadChannels = Object.keys(unreadByChannel);
|
|
||||||
let badges = 0;
|
|
||||||
|
|
||||||
if (!unreadChannels.length) {
|
|
||||||
return badges;
|
|
||||||
}
|
|
||||||
|
|
||||||
unreadChannels.forEach(channel => {
|
|
||||||
badges += unreadByChannel[channel].uris.length;
|
|
||||||
});
|
|
||||||
return badges;
|
|
||||||
}); // Returns the uris with channels as an array with the channel with the newest content first
|
|
||||||
// If you just want the `unread` state, use selectUnread
|
|
||||||
|
|
||||||
const selectUnreadSubscriptions = reselect.createSelector(selectUnreadAmount, selectUnreadByChannel, lbryRedux.selectClaimsByUri, (unreadAmount, unreadByChannel, claimsByUri) => {
|
|
||||||
// determine which channel has the newest content
|
|
||||||
const unreadList = [];
|
|
||||||
|
|
||||||
if (!unreadAmount) {
|
|
||||||
return unreadList;
|
|
||||||
}
|
|
||||||
|
|
||||||
const channelUriList = Object.keys(unreadByChannel); // There is only one channel with unread notifications
|
|
||||||
|
|
||||||
if (unreadAmount === 1) {
|
|
||||||
channelUriList.forEach(channel => {
|
|
||||||
const unreadChannel = {
|
|
||||||
channel,
|
|
||||||
uris: unreadByChannel[channel].uris
|
|
||||||
};
|
|
||||||
unreadList.push(unreadChannel);
|
|
||||||
});
|
|
||||||
return unreadList;
|
|
||||||
}
|
|
||||||
|
|
||||||
channelUriList.sort((channel1, channel2) => {
|
|
||||||
const latestUriFromChannel1 = unreadByChannel[channel1].uris[0];
|
|
||||||
const latestClaimFromChannel1 = claimsByUri[latestUriFromChannel1] || {};
|
|
||||||
const latestUriFromChannel2 = unreadByChannel[channel2].uris[0];
|
|
||||||
const latestClaimFromChannel2 = claimsByUri[latestUriFromChannel2] || {};
|
|
||||||
const latestHeightFromChannel1 = latestClaimFromChannel1.height || 0;
|
|
||||||
const latestHeightFromChannel2 = latestClaimFromChannel2.height || 0;
|
|
||||||
|
|
||||||
if (latestHeightFromChannel1 !== latestHeightFromChannel2) {
|
|
||||||
return latestHeightFromChannel2 - latestHeightFromChannel1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}).forEach(channel => {
|
|
||||||
const unreadSubscription = unreadByChannel[channel];
|
|
||||||
const unreadChannel = {
|
|
||||||
channel,
|
|
||||||
uris: unreadSubscription.uris
|
|
||||||
};
|
|
||||||
unreadList.push(unreadChannel);
|
|
||||||
});
|
|
||||||
return unreadList;
|
|
||||||
}); // Returns all unread subscriptions for a uri passed in
|
|
||||||
|
|
||||||
const makeSelectUnreadByChannel = uri => reselect.createSelector(selectUnreadByChannel, unread => unread[uri]); // Returns the first page of claims for every channel a user is subscribed to
|
|
||||||
|
|
||||||
const selectSubscriptionClaims = reselect.createSelector(lbryRedux.selectAllClaimsByChannel, lbryRedux.selectClaimsById, selectSubscriptions, selectUnreadByChannel, (channelIds, allClaims, savedSubscriptions, unreadByChannel) => {
|
|
||||||
// no claims loaded yet
|
|
||||||
if (!Object.keys(channelIds).length) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let fetchedSubscriptions = [];
|
|
||||||
savedSubscriptions.forEach(subscription => {
|
|
||||||
let channelClaims = []; // if subscribed channel has content
|
|
||||||
|
|
||||||
if (channelIds[subscription.uri] && channelIds[subscription.uri]['1']) {
|
|
||||||
// This will need to be more robust, we will want to be able to load more than the first page
|
|
||||||
// Strip out any ids that will be shown as notifications
|
|
||||||
const pageOneChannelIds = channelIds[subscription.uri]['1']; // we have the channel ids and the corresponding claims
|
|
||||||
// loop over the list of ids and grab the claim
|
|
||||||
|
|
||||||
pageOneChannelIds.forEach(id => {
|
|
||||||
const grabbedClaim = allClaims[id];
|
|
||||||
|
|
||||||
if (unreadByChannel[subscription.uri] && unreadByChannel[subscription.uri].uris.some(uri => uri.includes(id))) {
|
|
||||||
grabbedClaim.isNew = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
channelClaims = channelClaims.concat([grabbedClaim]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchedSubscriptions = fetchedSubscriptions.concat(channelClaims);
|
|
||||||
});
|
|
||||||
return fetchedSubscriptions;
|
|
||||||
}); // Returns true if a user is subscribed to the channel associated with the uri passed in
|
|
||||||
// Accepts content or channel uris
|
|
||||||
|
|
||||||
const makeSelectIsSubscribed = uri => reselect.createSelector(selectSubscriptions, lbryRedux.makeSelectChannelForClaimUri(uri, true), (subscriptions, channelUri) => {
|
|
||||||
if (channelUri) {
|
|
||||||
return subscriptions.some(sub => sub.uri === channelUri);
|
|
||||||
} // If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
|
|
||||||
|
|
||||||
|
|
||||||
const {
|
|
||||||
isChannel
|
|
||||||
} = lbryRedux.parseURI(uri);
|
|
||||||
|
|
||||||
if (isChannel) {
|
|
||||||
const uriWithPrefix = uri.startsWith('lbry://') ? uri : `lbry://${uri}`;
|
|
||||||
return subscriptions.some(sub => sub.uri === uriWithPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
const makeSelectIsNew = uri => reselect.createSelector(makeSelectIsSubscribed(uri), lbryRedux.makeSelectChannelForClaimUri(uri), selectUnreadByChannel, (isSubscribed, channel, unreadByChannel) => {
|
|
||||||
if (!isSubscribed) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unreadForChannel = unreadByChannel[`lbry://${channel}`];
|
|
||||||
|
|
||||||
if (unreadForChannel) {
|
|
||||||
return unreadForChannel.uris.includes(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // If they are subscribed, check to see if this uri is in the list of unreads
|
|
||||||
});
|
|
||||||
const selectEnabledChannelNotifications = reselect.createSelector(selectState$2, state => state.enabledChannelNotifications);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
||||||
const doSetViewMode = viewMode => dispatch => dispatch({
|
const doSetViewMode = viewMode => dispatch => dispatch({
|
||||||
|
@ -2409,7 +2481,8 @@ reducers$2[lbryRedux.ACTIONS.USER_FETCH_STARTED] = state => Object.assign({}, st
|
||||||
|
|
||||||
reducers$2[lbryRedux.ACTIONS.USER_FETCH_SUCCESS] = (state, action) => Object.assign({}, state, {
|
reducers$2[lbryRedux.ACTIONS.USER_FETCH_SUCCESS] = (state, action) => Object.assign({}, state, {
|
||||||
userIsPending: false,
|
userIsPending: false,
|
||||||
user: action.data.user
|
user: action.data.user,
|
||||||
|
emailToVerify: action.data.user.has_verified_email ? null : state.emailToVerify
|
||||||
});
|
});
|
||||||
|
|
||||||
reducers$2[lbryRedux.ACTIONS.USER_FETCH_FAILURE] = state => Object.assign({}, state, {
|
reducers$2[lbryRedux.ACTIONS.USER_FETCH_FAILURE] = state => Object.assign({}, state, {
|
||||||
|
@ -2971,9 +3044,11 @@ exports.selectUserIsPending = selectUserIsPending;
|
||||||
exports.selectUserIsRewardApproved = selectUserIsRewardApproved;
|
exports.selectUserIsRewardApproved = selectUserIsRewardApproved;
|
||||||
exports.selectUserIsVerificationCandidate = selectUserIsVerificationCandidate;
|
exports.selectUserIsVerificationCandidate = selectUserIsVerificationCandidate;
|
||||||
exports.selectUserPhone = selectUserPhone;
|
exports.selectUserPhone = selectUserPhone;
|
||||||
|
exports.selectUserVerifiedEmail = selectUserVerifiedEmail;
|
||||||
exports.selectViewMode = selectViewMode;
|
exports.selectViewMode = selectViewMode;
|
||||||
exports.setSubscriptionLatest = setSubscriptionLatest;
|
exports.setSubscriptionLatest = setSubscriptionLatest;
|
||||||
exports.statsReducer = statsReducer;
|
exports.statsReducer = statsReducer;
|
||||||
exports.subscriptionsReducer = subscriptions;
|
exports.subscriptionsReducer = subscriptions;
|
||||||
exports.syncReducer = syncReducer;
|
exports.syncReducer = syncReducer;
|
||||||
exports.userReducer = userReducer;
|
exports.userReducer = userReducer;
|
||||||
|
exports.userStateSyncMiddleware = userStateSyncMiddleware;
|
||||||
|
|
1697
dist/bundle.js
vendored
1697
dist/bundle.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -3,4 +3,3 @@
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
export type Dispatch<T> = (action: T | Promise<T> | Array<T> | ThunkAction<T>) => any; // Need to refer to ThunkAction
|
export type Dispatch<T> = (action: T | Promise<T> | Array<T> | ThunkAction<T>) => any; // Need to refer to ThunkAction
|
||||||
export type GetState = () => any;
|
export type GetState = () => any;
|
||||||
export type ThunkAction<T> = (dispatch: Dispatch<T>, getState: GetState) => any;
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { Dispatch as ReduxDispatch } from 'types/redux';
|
import type { Dispatch } from 'flow-typed/Redux';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import {
|
import {
|
||||||
DOWNLOADED,
|
DOWNLOADED,
|
||||||
|
@ -12,7 +12,7 @@ import {
|
||||||
SUGGESTED_FEATURED,
|
SUGGESTED_FEATURED,
|
||||||
} from 'constants/subscriptions';
|
} from 'constants/subscriptions';
|
||||||
|
|
||||||
export type Subscription = {
|
declare type Subscription = {
|
||||||
channelName: string, // @CryptoCandor,
|
channelName: string, // @CryptoCandor,
|
||||||
uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6
|
uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6
|
||||||
latest?: string, // substratum#b0ab143243020e7831fd070d9f871e1fda948620
|
latest?: string, // substratum#b0ab143243020e7831fd070d9f871e1fda948620
|
||||||
|
@ -21,26 +21,26 @@ export type Subscription = {
|
||||||
// Tracking for new content
|
// Tracking for new content
|
||||||
// i.e. If a subscription has a DOWNLOADING type, we will trigger an OS notification
|
// i.e. If a subscription has a DOWNLOADING type, we will trigger an OS notification
|
||||||
// to tell users there is new content from their subscriptions
|
// to tell users there is new content from their subscriptions
|
||||||
export type SubscriptionNotificationType = DOWNLOADED | DOWNLOADING | NOTIFY_ONLY;
|
declare type SubscriptionNotificationType = DOWNLOADED | DOWNLOADING | NOTIFY_ONLY;
|
||||||
|
|
||||||
export type UnreadSubscription = {
|
declare type UnreadSubscription = {
|
||||||
type: SubscriptionNotificationType,
|
type: SubscriptionNotificationType,
|
||||||
uris: Array<string>,
|
uris: Array<string>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UnreadSubscriptions = {
|
declare type UnreadSubscriptions = {
|
||||||
[string]: UnreadSubscription,
|
[string]: UnreadSubscription,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewMode = VIEW_LATEST_FIRST | VIEW_ALL;
|
declare type ViewMode = VIEW_LATEST_FIRST | VIEW_ALL;
|
||||||
|
|
||||||
export type SuggestedType = SUGGESTED_TOP_BID | SUGGESTED_TOP_SUBSCRIBED | SUGGESTED_FEATURED;
|
declare type SuggestedType = SUGGESTED_TOP_BID | SUGGESTED_TOP_SUBSCRIBED | SUGGESTED_FEATURED;
|
||||||
|
|
||||||
export type SuggestedSubscriptions = {
|
declare type SuggestedSubscriptions = {
|
||||||
[SuggestedType]: string,
|
[SuggestedType]: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SubscriptionState = {
|
declare type SubscriptionState = {
|
||||||
enabledChannelNotifications: Array<string>,
|
enabledChannelNotifications: Array<string>,
|
||||||
subscriptions: Array<Subscription>,
|
subscriptions: Array<Subscription>,
|
||||||
unread: UnreadSubscriptions,
|
unread: UnreadSubscriptions,
|
||||||
|
@ -55,27 +55,27 @@ export type SubscriptionState = {
|
||||||
//
|
//
|
||||||
// Action types
|
// Action types
|
||||||
//
|
//
|
||||||
export type DoChannelSubscriptionEnableNotifications = {
|
declare type DoChannelSubscriptionEnableNotifications = {
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS,
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS,
|
||||||
data: string,
|
data: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DoChannelSubscriptionDisableNotifications = {
|
declare type DoChannelSubscriptionDisableNotifications = {
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS,
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS,
|
||||||
data: string,
|
data: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DoChannelSubscribe = {
|
declare type DoChannelSubscribe = {
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIBE,
|
type: ACTIONS.CHANNEL_SUBSCRIBE,
|
||||||
data: Subscription,
|
data: Subscription,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DoChannelUnsubscribe = {
|
declare type DoChannelUnsubscribe = {
|
||||||
type: ACTIONS.CHANNEL_UNSUBSCRIBE,
|
type: ACTIONS.CHANNEL_UNSUBSCRIBE,
|
||||||
data: Subscription,
|
data: Subscription,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DoUpdateSubscriptionUnreads = {
|
declare type DoUpdateSubscriptionUnreads = {
|
||||||
type: ACTIONS.UPDATE_SUBSCRIPTION_UNREADS,
|
type: ACTIONS.UPDATE_SUBSCRIPTION_UNREADS,
|
||||||
data: {
|
data: {
|
||||||
channel: string,
|
channel: string,
|
||||||
|
@ -84,7 +84,7 @@ export type DoUpdateSubscriptionUnreads = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DoRemoveSubscriptionUnreads = {
|
declare type DoRemoveSubscriptionUnreads = {
|
||||||
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
||||||
data: {
|
data: {
|
||||||
channel: string,
|
channel: string,
|
||||||
|
@ -92,7 +92,7 @@ export type DoRemoveSubscriptionUnreads = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SetSubscriptionLatest = {
|
declare type SetSubscriptionLatest = {
|
||||||
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
||||||
data: {
|
data: {
|
||||||
subscription: Subscription,
|
subscription: Subscription,
|
||||||
|
@ -100,30 +100,30 @@ export type SetSubscriptionLatest = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CheckSubscriptionStarted = {
|
declare type CheckSubscriptionStarted = {
|
||||||
type: ACTIONS.CHECK_SUBSCRIPTION_STARTED,
|
type: ACTIONS.CHECK_SUBSCRIPTION_STARTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CheckSubscriptionCompleted = {
|
declare type CheckSubscriptionCompleted = {
|
||||||
type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED,
|
type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FetchedSubscriptionsSucess = {
|
declare type FetchedSubscriptionsSucess = {
|
||||||
type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
|
type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
|
||||||
data: Array<Subscription>,
|
data: Array<Subscription>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SetViewMode = {
|
declare type SetViewMode = {
|
||||||
type: ACTIONS.SET_VIEW_MODE,
|
type: ACTIONS.SET_VIEW_MODE,
|
||||||
data: ViewMode,
|
data: ViewMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GetSuggestedSubscriptionsSuccess = {
|
declare type GetSuggestedSubscriptionsSuccess = {
|
||||||
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
||||||
data: SuggestedSubscriptions,
|
data: SuggestedSubscriptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Action =
|
declare type SubscriptionAction =
|
||||||
| DoChannelSubscribe
|
| DoChannelSubscribe
|
||||||
| DoChannelUnsubscribe
|
| DoChannelUnsubscribe
|
||||||
| DoUpdateSubscriptionUnreads
|
| DoUpdateSubscriptionUnreads
|
||||||
|
@ -134,4 +134,4 @@ export type Action =
|
||||||
| SetViewMode
|
| SetViewMode
|
||||||
| Function;
|
| Function;
|
||||||
|
|
||||||
export type Dispatch = ReduxDispatch<Action>;
|
declare type SubscriptionDispatch = Dispatch<SubscriptionAction>;
|
23
dist/flow-typed/User.js
vendored
Normal file
23
dist/flow-typed/User.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
declare type User = {
|
||||||
|
created_at: string,
|
||||||
|
family_name: ?string,
|
||||||
|
given_name: ?string,
|
||||||
|
groups: Array<string>,
|
||||||
|
has_verified_email: boolean,
|
||||||
|
id: number,
|
||||||
|
invite_reward_claimed: boolean,
|
||||||
|
invited_at: ?number,
|
||||||
|
invited_by_id: number,
|
||||||
|
invites_remaining: number,
|
||||||
|
is_email_enabled: boolean,
|
||||||
|
is_identity_verified: boolean,
|
||||||
|
is_reward_approved: boolean,
|
||||||
|
language: string,
|
||||||
|
manual_approval_user_id: ?number,
|
||||||
|
primary_email: string,
|
||||||
|
reward_status_change_trigger: string,
|
||||||
|
updated_at: string,
|
||||||
|
youtube_channels: ?Array<string>,
|
||||||
|
};
|
5
flow-typed/Redux.js
vendored
Normal file
5
flow-typed/Redux.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
export type Dispatch<T> = (action: T | Promise<T> | Array<T> | ThunkAction<T>) => any; // Need to refer to ThunkAction
|
||||||
|
export type GetState = () => any;
|
137
flow-typed/Subscription.js
vendored
Normal file
137
flow-typed/Subscription.js
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// @flow
|
||||||
|
import type { Dispatch } from 'flow-typed/Redux';
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import {
|
||||||
|
DOWNLOADED,
|
||||||
|
DOWNLOADING,
|
||||||
|
NOTIFY_ONLY,
|
||||||
|
VIEW_ALL,
|
||||||
|
VIEW_LATEST_FIRST,
|
||||||
|
SUGGESTED_TOP_BID,
|
||||||
|
SUGGESTED_TOP_SUBSCRIBED,
|
||||||
|
SUGGESTED_FEATURED,
|
||||||
|
} from 'constants/subscriptions';
|
||||||
|
|
||||||
|
declare type Subscription = {
|
||||||
|
channelName: string, // @CryptoCandor,
|
||||||
|
uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6
|
||||||
|
latest?: string, // substratum#b0ab143243020e7831fd070d9f871e1fda948620
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tracking for new content
|
||||||
|
// i.e. If a subscription has a DOWNLOADING type, we will trigger an OS notification
|
||||||
|
// to tell users there is new content from their subscriptions
|
||||||
|
declare type SubscriptionNotificationType = DOWNLOADED | DOWNLOADING | NOTIFY_ONLY;
|
||||||
|
|
||||||
|
declare type UnreadSubscription = {
|
||||||
|
type: SubscriptionNotificationType,
|
||||||
|
uris: Array<string>,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type UnreadSubscriptions = {
|
||||||
|
[string]: UnreadSubscription,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type ViewMode = VIEW_LATEST_FIRST | VIEW_ALL;
|
||||||
|
|
||||||
|
declare type SuggestedType = SUGGESTED_TOP_BID | SUGGESTED_TOP_SUBSCRIBED | SUGGESTED_FEATURED;
|
||||||
|
|
||||||
|
declare type SuggestedSubscriptions = {
|
||||||
|
[SuggestedType]: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type SubscriptionState = {
|
||||||
|
enabledChannelNotifications: Array<string>,
|
||||||
|
subscriptions: Array<Subscription>,
|
||||||
|
unread: UnreadSubscriptions,
|
||||||
|
loading: boolean,
|
||||||
|
viewMode: ViewMode,
|
||||||
|
suggested: SuggestedSubscriptions,
|
||||||
|
loadingSuggested: boolean,
|
||||||
|
firstRunCompleted: boolean,
|
||||||
|
showSuggestedSubs: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Action types
|
||||||
|
//
|
||||||
|
declare type DoChannelSubscriptionEnableNotifications = {
|
||||||
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS,
|
||||||
|
data: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type DoChannelSubscriptionDisableNotifications = {
|
||||||
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS,
|
||||||
|
data: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type DoChannelSubscribe = {
|
||||||
|
type: ACTIONS.CHANNEL_SUBSCRIBE,
|
||||||
|
data: Subscription,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type DoChannelUnsubscribe = {
|
||||||
|
type: ACTIONS.CHANNEL_UNSUBSCRIBE,
|
||||||
|
data: Subscription,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type DoUpdateSubscriptionUnreads = {
|
||||||
|
type: ACTIONS.UPDATE_SUBSCRIPTION_UNREADS,
|
||||||
|
data: {
|
||||||
|
channel: string,
|
||||||
|
uris: Array<string>,
|
||||||
|
type?: SubscriptionNotificationType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type DoRemoveSubscriptionUnreads = {
|
||||||
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
||||||
|
data: {
|
||||||
|
channel: string,
|
||||||
|
uris: Array<string>,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type SetSubscriptionLatest = {
|
||||||
|
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
||||||
|
data: {
|
||||||
|
subscription: Subscription,
|
||||||
|
uri: string,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type CheckSubscriptionStarted = {
|
||||||
|
type: ACTIONS.CHECK_SUBSCRIPTION_STARTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type CheckSubscriptionCompleted = {
|
||||||
|
type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type FetchedSubscriptionsSucess = {
|
||||||
|
type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
|
||||||
|
data: Array<Subscription>,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type SetViewMode = {
|
||||||
|
type: ACTIONS.SET_VIEW_MODE,
|
||||||
|
data: ViewMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type GetSuggestedSubscriptionsSuccess = {
|
||||||
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
||||||
|
data: SuggestedSubscriptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type SubscriptionAction =
|
||||||
|
| DoChannelSubscribe
|
||||||
|
| DoChannelUnsubscribe
|
||||||
|
| DoUpdateSubscriptionUnreads
|
||||||
|
| DoRemoveSubscriptionUnreads
|
||||||
|
| SetSubscriptionLatest
|
||||||
|
| CheckSubscriptionStarted
|
||||||
|
| CheckSubscriptionCompleted
|
||||||
|
| SetViewMode
|
||||||
|
| Function;
|
||||||
|
|
||||||
|
declare type SubscriptionDispatch = Dispatch<SubscriptionAction>;
|
23
flow-typed/User.js
vendored
Normal file
23
flow-typed/User.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
declare type User = {
|
||||||
|
created_at: string,
|
||||||
|
family_name: ?string,
|
||||||
|
given_name: ?string,
|
||||||
|
groups: Array<string>,
|
||||||
|
has_verified_email: boolean,
|
||||||
|
id: number,
|
||||||
|
invite_reward_claimed: boolean,
|
||||||
|
invited_at: ?number,
|
||||||
|
invited_by_id: number,
|
||||||
|
invites_remaining: number,
|
||||||
|
is_email_enabled: boolean,
|
||||||
|
is_identity_verified: boolean,
|
||||||
|
is_reward_approved: boolean,
|
||||||
|
language: string,
|
||||||
|
manual_approval_user_id: ?number,
|
||||||
|
primary_email: string,
|
||||||
|
reward_status_change_trigger: string,
|
||||||
|
updated_at: string,
|
||||||
|
youtube_channels: ?Array<string>,
|
||||||
|
};
|
|
@ -57,7 +57,9 @@
|
||||||
"lint-staged": "^7.0.4",
|
"lint-staged": "^7.0.4",
|
||||||
"prettier": "^1.4.2",
|
"prettier": "^1.4.2",
|
||||||
"rollup": "^1.8.0",
|
"rollup": "^1.8.0",
|
||||||
|
"rollup-plugin-alias": "^2.0.0",
|
||||||
"rollup-plugin-babel": "^4.3.2",
|
"rollup-plugin-babel": "^4.3.2",
|
||||||
|
"rollup-plugin-copy": "^3.1.0",
|
||||||
"rollup-plugin-flow": "^1.1.1",
|
"rollup-plugin-flow": "^1.1.1",
|
||||||
"rollup-plugin-includepaths": "^0.2.3",
|
"rollup-plugin-includepaths": "^0.2.3",
|
||||||
"webpack": "^4.5.0",
|
"webpack": "^4.5.0",
|
||||||
|
|
|
@ -1,27 +1,38 @@
|
||||||
import babel from 'rollup-plugin-babel';
|
import babel from 'rollup-plugin-babel';
|
||||||
import flow from 'rollup-plugin-flow';
|
import flow from 'rollup-plugin-flow';
|
||||||
import includePaths from 'rollup-plugin-includepaths';
|
import includePaths from 'rollup-plugin-includepaths';
|
||||||
|
import copy from 'rollup-plugin-copy';
|
||||||
|
import alias from 'rollup-plugin-alias';
|
||||||
|
|
||||||
let includePathOptions = {
|
let includePathOptions = {
|
||||||
include: {},
|
include: {},
|
||||||
paths: ['src'],
|
paths: ['src'],
|
||||||
external: [],
|
external: [],
|
||||||
extensions: ['.js']
|
extensions: ['.js'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: 'src/index.js',
|
input: 'src/index.js',
|
||||||
output: {
|
output: {
|
||||||
file: 'dist/bundle.es.js',
|
file: 'dist/bundle.es.js',
|
||||||
format: 'cjs'
|
format: 'cjs',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
alias({
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
find: 'flow-typed',
|
||||||
|
replacement: './flow-typed',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
flow({ all: true }),
|
flow({ all: true }),
|
||||||
includePaths(includePathOptions),
|
includePaths(includePathOptions),
|
||||||
babel({
|
babel({
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [],
|
presets: [],
|
||||||
}),
|
}),
|
||||||
|
copy({ targets: [{ src: './flow-typed', dest: 'dist' }] }),
|
||||||
],
|
],
|
||||||
external: ['lbry-redux']
|
external: ['lbry-redux'],
|
||||||
}
|
};
|
||||||
|
|
|
@ -3,6 +3,9 @@ import Lbryio from 'lbryio';
|
||||||
import rewards from 'rewards';
|
import rewards from 'rewards';
|
||||||
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
||||||
|
|
||||||
|
// middleware
|
||||||
|
export { userStateSyncMiddleware } from 'redux/middleware/sync';
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
export { LBRYINC_ACTIONS };
|
export { LBRYINC_ACTIONS };
|
||||||
|
|
||||||
|
@ -147,6 +150,7 @@ export {
|
||||||
selectUserInviteNewIsPending,
|
selectUserInviteNewIsPending,
|
||||||
selectUserInviteNewErrorMessage,
|
selectUserInviteNewErrorMessage,
|
||||||
selectUserInviteReferralLink,
|
selectUserInviteReferralLink,
|
||||||
|
selectUserVerifiedEmail,
|
||||||
} from 'redux/selectors/user';
|
} from 'redux/selectors/user';
|
||||||
export {
|
export {
|
||||||
makeSelectFetchingCostInfoForUri,
|
makeSelectFetchingCostInfoForUri,
|
||||||
|
|
|
@ -48,6 +48,13 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => {
|
||||||
|
|
||||||
return Lbryio.getAuthToken().then(token => {
|
return Lbryio.getAuthToken().then(token => {
|
||||||
const fullParams = { auth_token: token, ...params };
|
const fullParams = { auth_token: token, ...params };
|
||||||
|
Object.keys(fullParams).forEach(key => {
|
||||||
|
const value = fullParams[key];
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
fullParams[key] = JSON.stringify(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const qs = querystring.stringify(fullParams);
|
const qs = querystring.stringify(fullParams);
|
||||||
let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`;
|
let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`;
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,19 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
? { reward_type: rewards.TYPE_REWARD_CODE }
|
? { reward_type: rewards.TYPE_REWARD_CODE }
|
||||||
: unclaimedRewards.find(ur => ur.reward_type === rewardType);
|
: unclaimedRewards.find(ur => ur.reward_type === rewardType);
|
||||||
|
|
||||||
if (rewardType !== rewards.TYPE_REWARD_CODE) {
|
// Try to claim the email reward right away, even if we haven't called reward_list yet
|
||||||
|
if (rewardType !== rewards.TYPE_REWARD_CODE || rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
||||||
if (!reward || reward.transaction_id) {
|
if (!reward || reward.transaction_id) {
|
||||||
// already claimed or doesn't exist, do nothing
|
// already claimed or doesn't exist, do nothing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
if (
|
||||||
|
!userIsRewardApproved &&
|
||||||
|
rewardType !== rewards.TYPE_CONFIRM_EMAIL &&
|
||||||
|
rewardType !== rewards.TYPE_REWARD_CODE
|
||||||
|
) {
|
||||||
if (!options || (!options.failSilently && rewards.callbacks.rewardApprovalRequested)) {
|
if (!options || (!options.failSilently && rewards.callbacks.rewardApprovalRequested)) {
|
||||||
rewards.callbacks.rewardApprovalRequested();
|
rewards.callbacks.rewardApprovalRequested();
|
||||||
}
|
}
|
||||||
|
@ -78,6 +83,10 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(doRewardList());
|
dispatch(doRewardList());
|
||||||
|
|
||||||
|
if (options.callback) {
|
||||||
|
options.callback();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const failure = error => {
|
const failure = error => {
|
||||||
|
@ -92,6 +101,10 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
if (options.notifyError) {
|
if (options.notifyError) {
|
||||||
dispatch(doToast({ message: error.message, isError: true }));
|
dispatch(doToast({ message: error.message, isError: true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.callback) {
|
||||||
|
options.callback(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rewards.claimReward(rewardType, params).then(success, failure);
|
rewards.claimReward(rewardType, params).then(success, failure);
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { GetState } from 'types/redux';
|
import type { SubscriptionDispatch } from 'flow-typed/Subscription';
|
||||||
import type {
|
|
||||||
Dispatch as ReduxDispatch,
|
|
||||||
SubscriptionState,
|
|
||||||
Subscription,
|
|
||||||
SubscriptionNotificationType,
|
|
||||||
ViewMode,
|
|
||||||
UnreadSubscription,
|
|
||||||
} from 'types/subscription';
|
|
||||||
import { PAGE_SIZE } from 'constants/claim';
|
import { PAGE_SIZE } from 'constants/claim';
|
||||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||||
import { selectSubscriptions, selectUnreadByChannel } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions, selectUnreadByChannel } from 'redux/selectors/subscriptions';
|
||||||
|
@ -20,14 +12,14 @@ import rewards from 'rewards';
|
||||||
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
||||||
const SUBSCRIPTION_DOWNLOAD_LIMIT = 1;
|
const SUBSCRIPTION_DOWNLOAD_LIMIT = 1;
|
||||||
|
|
||||||
export const doSetViewMode = (viewMode: ViewMode) => (dispatch: ReduxDispatch) =>
|
export const doSetViewMode = (viewMode: ViewMode) => (dispatch: SubscriptionDispatch) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SET_VIEW_MODE,
|
type: ACTIONS.SET_VIEW_MODE,
|
||||||
data: viewMode,
|
data: viewMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (
|
export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (
|
||||||
dispatch: ReduxDispatch
|
dispatch: SubscriptionDispatch
|
||||||
) =>
|
) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
||||||
|
@ -42,7 +34,7 @@ export const doUpdateUnreadSubscriptions = (
|
||||||
channelUri: string,
|
channelUri: string,
|
||||||
uris: ?Array<string>,
|
uris: ?Array<string>,
|
||||||
type: ?SubscriptionNotificationType
|
type: ?SubscriptionNotificationType
|
||||||
) => (dispatch: ReduxDispatch, getState: GetState) => {
|
) => (dispatch: SubscriptionDispatch, getState: GetState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const unreadByChannel = selectUnreadByChannel(state);
|
const unreadByChannel = selectUnreadByChannel(state);
|
||||||
const currentUnreadForChannel: UnreadSubscription = unreadByChannel[channelUri];
|
const currentUnreadForChannel: UnreadSubscription = unreadByChannel[channelUri];
|
||||||
|
@ -84,7 +76,7 @@ export const doUpdateUnreadSubscriptions = (
|
||||||
|
|
||||||
// Remove multiple files (or all) from a channels unread subscriptions
|
// Remove multiple files (or all) from a channels unread subscriptions
|
||||||
export const doRemoveUnreadSubscriptions = (channelUri: ?string, readUris: ?Array<string>) => (
|
export const doRemoveUnreadSubscriptions = (channelUri: ?string, readUris: ?Array<string>) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: SubscriptionDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -133,13 +125,13 @@ export const doRemoveUnreadSubscriptions = (channelUri: ?string, readUris: ?Arra
|
||||||
|
|
||||||
// Remove a single file from a channels unread subscriptions
|
// Remove a single file from a channels unread subscriptions
|
||||||
export const doRemoveUnreadSubscription = (channelUri: string, readUri: string) => (
|
export const doRemoveUnreadSubscription = (channelUri: string, readUri: string) => (
|
||||||
dispatch: ReduxDispatch
|
dispatch: SubscriptionDispatch
|
||||||
) => {
|
) => {
|
||||||
dispatch(doRemoveUnreadSubscriptions(channelUri, [readUri]));
|
dispatch(doRemoveUnreadSubscriptions(channelUri, [readUri]));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: boolean) => (
|
export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: boolean) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: SubscriptionDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
// no dispatching FETCH_CHANNEL_CLAIMS_STARTED; causes loading issues on <SubscriptionsPage>
|
// no dispatching FETCH_CHANNEL_CLAIMS_STARTED; causes loading issues on <SubscriptionsPage>
|
||||||
|
@ -238,7 +230,7 @@ export const doCheckSubscription = (subscriptionUri: string, shouldNotify?: bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doChannelSubscribe = (subscription: Subscription) => (
|
export const doChannelSubscribe = (subscription: Subscription) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: SubscriptionDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
|
@ -275,7 +267,7 @@ export const doChannelSubscribe = (subscription: Subscription) => (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doChannelUnsubscribe = (subscription: Subscription) => (
|
export const doChannelUnsubscribe = (subscription: Subscription) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: SubscriptionDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
|
@ -296,7 +288,7 @@ export const doChannelUnsubscribe = (subscription: Subscription) => (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doCheckSubscriptions = () => (dispatch: ReduxDispatch, getState: GetState) => {
|
export const doCheckSubscriptions = () => (dispatch: SubscriptionDispatch, getState: GetState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const subscriptions = selectSubscriptions(state);
|
const subscriptions = selectSubscriptions(state);
|
||||||
|
|
||||||
|
@ -305,7 +297,10 @@ export const doCheckSubscriptions = () => (dispatch: ReduxDispatch, getState: Ge
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doFetchMySubscriptions = () => (dispatch: ReduxDispatch, getState: GetState) => {
|
export const doFetchMySubscriptions = () => (
|
||||||
|
dispatch: SubscriptionDispatch,
|
||||||
|
getState: GetState
|
||||||
|
) => {
|
||||||
const state: { subscriptions: SubscriptionState, settings: any } = getState();
|
const state: { subscriptions: SubscriptionState, settings: any } = getState();
|
||||||
const { subscriptions: reduxSubscriptions } = state.subscriptions;
|
const { subscriptions: reduxSubscriptions } = state.subscriptions;
|
||||||
|
|
||||||
|
@ -386,7 +381,7 @@ export const doFetchMySubscriptions = () => (dispatch: ReduxDispatch, getState:
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doCheckSubscriptionsInit = () => (dispatch: ReduxDispatch) => {
|
export const doCheckSubscriptionsInit = () => (dispatch: SubscriptionDispatch) => {
|
||||||
// doCheckSubscriptionsInit is called by doDaemonReady
|
// doCheckSubscriptionsInit is called by doDaemonReady
|
||||||
// setTimeout below is a hack to ensure redux is hydrated when subscriptions are checked
|
// setTimeout below is a hack to ensure redux is hydrated when subscriptions are checked
|
||||||
// this will be replaced with <PersistGate> which reqiures a package upgrade
|
// this will be replaced with <PersistGate> which reqiures a package upgrade
|
||||||
|
@ -402,7 +397,7 @@ export const doCheckSubscriptionsInit = () => (dispatch: ReduxDispatch) => {
|
||||||
setInterval(() => dispatch(doCheckSubscriptions()), CHECK_SUBSCRIPTIONS_INTERVAL);
|
setInterval(() => dispatch(doCheckSubscriptions()), CHECK_SUBSCRIPTIONS_INTERVAL);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doFetchRecommendedSubscriptions = () => (dispatch: ReduxDispatch) => {
|
export const doFetchRecommendedSubscriptions = () => (dispatch: SubscriptionDispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
||||||
});
|
});
|
||||||
|
@ -422,18 +417,18 @@ export const doFetchRecommendedSubscriptions = () => (dispatch: ReduxDispatch) =
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doCompleteFirstRun = () => (dispatch: ReduxDispatch) =>
|
export const doCompleteFirstRun = () => (dispatch: SubscriptionDispatch) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SUBSCRIPTION_FIRST_RUN_COMPLETED,
|
type: ACTIONS.SUBSCRIPTION_FIRST_RUN_COMPLETED,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const doShowSuggestedSubs = () => (dispatch: ReduxDispatch) =>
|
export const doShowSuggestedSubs = () => (dispatch: SubscriptionDispatch) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.VIEW_SUGGESTED_SUBSCRIPTIONS,
|
type: ACTIONS.VIEW_SUGGESTED_SUBSCRIPTIONS,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const doChannelSubscriptionEnableNotifications = (channelName: string) => (
|
export const doChannelSubscriptionEnableNotifications = (channelName: string) => (
|
||||||
dispatch: ReduxDispatch
|
dispatch: SubscriptionDispatch
|
||||||
) =>
|
) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS,
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS,
|
||||||
|
@ -441,7 +436,7 @@ export const doChannelSubscriptionEnableNotifications = (channelName: string) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
export const doChannelSubscriptionDisableNotifications = (channelName: string) => (
|
export const doChannelSubscriptionDisableNotifications = (channelName: string) => (
|
||||||
dispatch: ReduxDispatch
|
dispatch: SubscriptionDispatch
|
||||||
) =>
|
) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS,
|
type: ACTIONS.CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS,
|
||||||
|
|
58
src/redux/middleware/sync.js
Normal file
58
src/redux/middleware/sync.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import {
|
||||||
|
ACTIONS as LBRY_REDUX_ACTIONS,
|
||||||
|
makeSelectIsFollowingTag,
|
||||||
|
selectFollowedTags,
|
||||||
|
} from 'lbry-redux';
|
||||||
|
import Lbryio from 'lbryio';
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
|
|
||||||
|
const persistShape = {
|
||||||
|
version: '0',
|
||||||
|
shared: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function userStateSyncMiddleware() {
|
||||||
|
return ({ getState }) => next => action => {
|
||||||
|
if (
|
||||||
|
action.type === ACTIONS.CHANNEL_SUBSCRIBE ||
|
||||||
|
action.type === ACTIONS.CHANNEL_UNSUBSCRIBE ||
|
||||||
|
action.type === LBRY_REDUX_ACTIONS.TOGGLE_TAG_FOLLOW
|
||||||
|
) {
|
||||||
|
const newShape = { ...persistShape };
|
||||||
|
const state = getState();
|
||||||
|
const subscriptions = selectSubscriptions(state).map(({ uri }) => uri);
|
||||||
|
const tags = selectFollowedTags(state);
|
||||||
|
newShape.shared.subscriptions = subscriptions;
|
||||||
|
newShape.shared.tags = tags;
|
||||||
|
|
||||||
|
const { uri } = action.data;
|
||||||
|
|
||||||
|
if (action.type === ACTIONS.CHANNEL_SUBSCRIBE) {
|
||||||
|
const newSubscriptions = subscriptions.slice();
|
||||||
|
newSubscriptions.push(uri);
|
||||||
|
newShape.shared.subscriptions = newSubscriptions;
|
||||||
|
} else if (action.type === ACTIONS.CHANNEL_UNSUBSCRIBE) {
|
||||||
|
let newSubscriptions = subscriptions.slice();
|
||||||
|
newSubscriptions = newSubscriptions.filter(subscribedUri => subscribedUri !== uri);
|
||||||
|
newShape.shared.subscriptions = newSubscriptions;
|
||||||
|
} else {
|
||||||
|
const toggledTag = action.data.name;
|
||||||
|
const followedTags = selectFollowedTags(state).map(({ name }) => name);
|
||||||
|
const isFollowing = makeSelectIsFollowingTag(toggledTag)(state);
|
||||||
|
let newTags = followedTags.slice();
|
||||||
|
|
||||||
|
if (isFollowing) {
|
||||||
|
newTags = newTags.filter(followedTag => followedTag.name !== toggledTag);
|
||||||
|
} else {
|
||||||
|
newTags.push(toggledTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
newShape.shared.tags = newTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lbryio.call('user_settings', 'set', { settings: newShape });
|
||||||
|
}
|
||||||
|
return next(action);
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,20 +2,6 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import { VIEW_ALL } from 'constants/subscriptions';
|
import { VIEW_ALL } from 'constants/subscriptions';
|
||||||
import { handleActions } from 'util/redux-utils';
|
import { handleActions } from 'util/redux-utils';
|
||||||
import type {
|
|
||||||
SubscriptionState,
|
|
||||||
Subscription,
|
|
||||||
DoChannelSubscribe,
|
|
||||||
DoChannelUnsubscribe,
|
|
||||||
DoChannelSubscriptionEnableNotifications,
|
|
||||||
DoChannelSubscriptionDisableNotifications,
|
|
||||||
SetSubscriptionLatest,
|
|
||||||
DoUpdateSubscriptionUnreads,
|
|
||||||
DoRemoveSubscriptionUnreads,
|
|
||||||
FetchedSubscriptionsSucess,
|
|
||||||
SetViewMode,
|
|
||||||
GetSuggestedSubscriptionsSuccess,
|
|
||||||
} from 'types/subscription';
|
|
||||||
|
|
||||||
const defaultState: SubscriptionState = {
|
const defaultState: SubscriptionState = {
|
||||||
enabledChannelNotifications: [],
|
enabledChannelNotifications: [],
|
||||||
|
|
|
@ -46,6 +46,7 @@ reducers[ACTIONS.USER_FETCH_SUCCESS] = (state, action) =>
|
||||||
Object.assign({}, state, {
|
Object.assign({}, state, {
|
||||||
userIsPending: false,
|
userIsPending: false,
|
||||||
user: action.data.user,
|
user: action.data.user,
|
||||||
|
emailToVerify: action.data.user.has_verified_email ? null : state.emailToVerify,
|
||||||
});
|
});
|
||||||
|
|
||||||
reducers[ACTIONS.USER_FETCH_FAILURE] = state =>
|
reducers[ACTIONS.USER_FETCH_FAILURE] = state =>
|
||||||
|
|
|
@ -93,6 +93,11 @@ export const selectIdentityVerifyErrorMessage = createSelector(
|
||||||
state => state.identityVerifyErrorMessage
|
state => state.identityVerifyErrorMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectUserVerifiedEmail = createSelector(
|
||||||
|
selectUser,
|
||||||
|
user => user && user.has_verified_email
|
||||||
|
);
|
||||||
|
|
||||||
export const selectUserIsVerificationCandidate = createSelector(
|
export const selectUserIsVerificationCandidate = createSelector(
|
||||||
selectUser,
|
selectUser,
|
||||||
user => user && (!user.has_verified_email || !user.is_identity_verified)
|
user => user && (!user.has_verified_email || !user.is_identity_verified)
|
||||||
|
|
|
@ -5,7 +5,7 @@ const rewards = {};
|
||||||
|
|
||||||
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
|
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
|
||||||
rewards.TYPE_NEW_USER = 'new_user';
|
rewards.TYPE_NEW_USER = 'new_user';
|
||||||
rewards.TYPE_CONFIRM_EMAIL = 'verified_email';
|
rewards.TYPE_CONFIRM_EMAIL = 'email_provided';
|
||||||
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
|
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
|
||||||
rewards.TYPE_FIRST_STREAM = 'first_stream';
|
rewards.TYPE_FIRST_STREAM = 'first_stream';
|
||||||
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
|
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
|
||||||
|
|
|
@ -20,6 +20,9 @@ module.exports = {
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
|
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
|
||||||
|
alias: {
|
||||||
|
'flow-typed': path.resolve(__dirname, './flow-typed'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
externals: 'lbry-redux',
|
externals: 'lbry-redux',
|
||||||
};
|
};
|
||||||
|
|
226
yarn.lock
226
yarn.lock
|
@ -642,6 +642,27 @@
|
||||||
lodash "^4.17.11"
|
lodash "^4.17.11"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@nodelib/fs.scandir@2.1.2":
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.2.tgz#1f981cd5b83e85cfdeb386fc693d4baab392fa54"
|
||||||
|
integrity sha512-wrIBsjA5pl13f0RN4Zx4FNWmU71lv03meGKnqRUoCyan17s4V3WL92f3w3AIuWbNnpcrQyFBU5qMavJoB8d27w==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.stat" "2.0.2"
|
||||||
|
run-parallel "^1.1.9"
|
||||||
|
|
||||||
|
"@nodelib/fs.stat@2.0.2", "@nodelib/fs.stat@^2.0.1":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz#2762aea8fe78ea256860182dcb52d61ee4b8fda6"
|
||||||
|
integrity sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw==
|
||||||
|
|
||||||
|
"@nodelib/fs.walk@^1.2.1":
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.3.tgz#a555dc256acaf00c62b0db29529028dd4d4cb141"
|
||||||
|
integrity sha512-l6t8xEhfK9Sa4YO5mIRdau7XSOADfmh3jCr0evNHdY+HNkW6xuQhgMH7D73VV6WpZOagrW0UludvMTiifiwTfA==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.scandir" "2.1.2"
|
||||||
|
fastq "^1.6.0"
|
||||||
|
|
||||||
"@samverschueren/stream-to-observable@^0.3.0":
|
"@samverschueren/stream-to-observable@^0.3.0":
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
||||||
|
@ -652,6 +673,37 @@
|
||||||
version "0.0.39"
|
version "0.0.39"
|
||||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||||
|
|
||||||
|
"@types/events@*":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||||
|
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||||
|
|
||||||
|
"@types/fs-extra@^8.0.0":
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.0.0.tgz#d3e2c313ca29f95059f198dd60d1f774642d4b25"
|
||||||
|
integrity sha512-bCtL5v9zdbQW86yexOlXWTEGvLNqWxMFyi7gQA7Gcthbezr2cPSOb8SkESVKA937QD5cIwOFLDFt0MQoXOEr9Q==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/glob@^7.1.1":
|
||||||
|
version "7.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
|
||||||
|
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
|
||||||
|
dependencies:
|
||||||
|
"@types/events" "*"
|
||||||
|
"@types/minimatch" "*"
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/minimatch@*":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
|
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||||
|
|
||||||
|
"@types/node@*":
|
||||||
|
version "12.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f"
|
||||||
|
integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==
|
||||||
|
|
||||||
"@types/node@^11.11.6":
|
"@types/node@^11.11.6":
|
||||||
version "11.13.0"
|
version "11.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.0.tgz#b0df8d6ef9b5001b2be3a94d909ce3c29a80f9e1"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.0.tgz#b0df8d6ef9b5001b2be3a94d909ce3c29a80f9e1"
|
||||||
|
@ -974,6 +1026,11 @@ array-union@^1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
array-uniq "^1.0.1"
|
array-uniq "^1.0.1"
|
||||||
|
|
||||||
|
array-union@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
|
||||||
|
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
|
||||||
|
|
||||||
array-uniq@^1.0.1:
|
array-uniq@^1.0.1:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
|
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
|
||||||
|
@ -1154,6 +1211,13 @@ braces@^2.3.1, braces@^2.3.2:
|
||||||
split-string "^3.0.2"
|
split-string "^3.0.2"
|
||||||
to-regex "^3.0.1"
|
to-regex "^3.0.1"
|
||||||
|
|
||||||
|
braces@^3.0.1:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||||
|
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||||
|
dependencies:
|
||||||
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
brorand@^1.0.1:
|
brorand@^1.0.1:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||||
|
@ -1477,6 +1541,11 @@ color-name@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
|
||||||
|
|
||||||
|
colorette@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.1.0.tgz#1f943e5a357fac10b4e0f5aaef3b14cdc1af6ec7"
|
||||||
|
integrity sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==
|
||||||
|
|
||||||
colors@^1.1.2:
|
colors@^1.1.2:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e"
|
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e"
|
||||||
|
@ -1790,6 +1859,13 @@ diffie-hellman@^5.0.0:
|
||||||
miller-rabin "^4.0.0"
|
miller-rabin "^4.0.0"
|
||||||
randombytes "^2.0.0"
|
randombytes "^2.0.0"
|
||||||
|
|
||||||
|
dir-glob@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
|
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
|
||||||
|
dependencies:
|
||||||
|
path-type "^4.0.0"
|
||||||
|
|
||||||
doctrine@1.5.0:
|
doctrine@1.5.0:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
||||||
|
@ -2201,6 +2277,18 @@ fast-diff@^1.1.1:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
|
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
|
||||||
|
|
||||||
|
fast-glob@^3.0.3:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602"
|
||||||
|
integrity sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.stat" "^2.0.1"
|
||||||
|
"@nodelib/fs.walk" "^1.2.1"
|
||||||
|
glob-parent "^5.0.0"
|
||||||
|
is-glob "^4.0.1"
|
||||||
|
merge2 "^1.2.3"
|
||||||
|
micromatch "^4.0.2"
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||||
|
@ -2209,6 +2297,13 @@ fast-levenshtein@~2.0.4:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||||
|
|
||||||
|
fastq@^1.6.0:
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
|
||||||
|
integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==
|
||||||
|
dependencies:
|
||||||
|
reusify "^1.0.0"
|
||||||
|
|
||||||
figgy-pudding@^3.5.1:
|
figgy-pudding@^3.5.1:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||||
|
@ -2243,6 +2338,13 @@ fill-range@^4.0.0:
|
||||||
repeat-string "^1.6.1"
|
repeat-string "^1.6.1"
|
||||||
to-regex-range "^2.1.0"
|
to-regex-range "^2.1.0"
|
||||||
|
|
||||||
|
fill-range@^7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||||
|
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||||
|
dependencies:
|
||||||
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
find-babel-config@^1.1.0:
|
find-babel-config@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355"
|
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355"
|
||||||
|
@ -2370,6 +2472,15 @@ fs-extra@^5.0.0:
|
||||||
jsonfile "^4.0.0"
|
jsonfile "^4.0.0"
|
||||||
universalify "^0.1.0"
|
universalify "^0.1.0"
|
||||||
|
|
||||||
|
fs-extra@^8.1.0:
|
||||||
|
version "8.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||||
|
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||||
|
dependencies:
|
||||||
|
graceful-fs "^4.2.0"
|
||||||
|
jsonfile "^4.0.0"
|
||||||
|
universalify "^0.1.0"
|
||||||
|
|
||||||
fs-minipass@^1.2.5:
|
fs-minipass@^1.2.5:
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
|
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
|
||||||
|
@ -2476,6 +2587,13 @@ glob-parent@^3.1.0:
|
||||||
is-glob "^3.1.0"
|
is-glob "^3.1.0"
|
||||||
path-dirname "^1.0.0"
|
path-dirname "^1.0.0"
|
||||||
|
|
||||||
|
glob-parent@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
|
||||||
|
integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==
|
||||||
|
dependencies:
|
||||||
|
is-glob "^4.0.1"
|
||||||
|
|
||||||
glob@^7.0.3, glob@^7.1.2:
|
glob@^7.0.3, glob@^7.1.2:
|
||||||
version "7.1.2"
|
version "7.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||||
|
@ -2538,6 +2656,20 @@ globals@^11.0.1, globals@^11.1.0:
|
||||||
version "11.7.0"
|
version "11.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
|
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
|
||||||
|
|
||||||
|
globby@10.0.1:
|
||||||
|
version "10.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22"
|
||||||
|
integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==
|
||||||
|
dependencies:
|
||||||
|
"@types/glob" "^7.1.1"
|
||||||
|
array-union "^2.1.0"
|
||||||
|
dir-glob "^3.0.1"
|
||||||
|
fast-glob "^3.0.3"
|
||||||
|
glob "^7.1.3"
|
||||||
|
ignore "^5.1.1"
|
||||||
|
merge2 "^1.2.3"
|
||||||
|
slash "^3.0.0"
|
||||||
|
|
||||||
globby@^5.0.0:
|
globby@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
|
resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
|
||||||
|
@ -2568,7 +2700,7 @@ got@^7.1.0:
|
||||||
url-parse-lax "^1.0.0"
|
url-parse-lax "^1.0.0"
|
||||||
url-to-options "^1.0.1"
|
url-to-options "^1.0.1"
|
||||||
|
|
||||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15:
|
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.2.0:
|
||||||
version "4.2.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
||||||
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
||||||
|
@ -2717,6 +2849,11 @@ ignore@^3.3.3:
|
||||||
version "3.3.10"
|
version "3.3.10"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
|
||||||
|
|
||||||
|
ignore@^5.1.1:
|
||||||
|
version "5.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
|
||||||
|
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
|
||||||
|
|
||||||
import-local@2.0.0:
|
import-local@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
|
resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
|
||||||
|
@ -2945,12 +3082,24 @@ is-glob@^4.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-extglob "^2.1.1"
|
is-extglob "^2.1.1"
|
||||||
|
|
||||||
|
is-glob@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||||
|
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
||||||
|
dependencies:
|
||||||
|
is-extglob "^2.1.1"
|
||||||
|
|
||||||
is-number@^3.0.0:
|
is-number@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
|
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
|
||||||
dependencies:
|
dependencies:
|
||||||
kind-of "^3.0.2"
|
kind-of "^3.0.2"
|
||||||
|
|
||||||
|
is-number@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||||
|
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||||
|
|
||||||
is-obj@^1.0.1:
|
is-obj@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||||
|
@ -2992,6 +3141,13 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
isobject "^3.0.1"
|
isobject "^3.0.1"
|
||||||
|
|
||||||
|
is-plain-object@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928"
|
||||||
|
integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==
|
||||||
|
dependencies:
|
||||||
|
isobject "^4.0.0"
|
||||||
|
|
||||||
is-promise@^2.1.0:
|
is-promise@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
||||||
|
@ -3072,6 +3228,11 @@ isobject@^3.0.0, isobject@^3.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||||
|
|
||||||
|
isobject@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
|
||||||
|
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
|
||||||
|
|
||||||
isurl@^1.0.0-alpha5:
|
isurl@^1.0.0-alpha5:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
|
resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
|
||||||
|
@ -3468,6 +3629,11 @@ memory-fs@^0.4.0, memory-fs@^0.4.1:
|
||||||
errno "^0.1.3"
|
errno "^0.1.3"
|
||||||
readable-stream "^2.0.1"
|
readable-stream "^2.0.1"
|
||||||
|
|
||||||
|
merge2@^1.2.3:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
|
||||||
|
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
|
||||||
|
|
||||||
micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
|
micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
|
||||||
version "3.1.10"
|
version "3.1.10"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||||
|
@ -3486,6 +3652,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
|
||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.2"
|
to-regex "^3.0.2"
|
||||||
|
|
||||||
|
micromatch@^4.0.2:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
|
||||||
|
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
|
||||||
|
dependencies:
|
||||||
|
braces "^3.0.1"
|
||||||
|
picomatch "^2.0.5"
|
||||||
|
|
||||||
miller-rabin@^4.0.0:
|
miller-rabin@^4.0.0:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
||||||
|
@ -4073,6 +4247,11 @@ path-type@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
pify "^2.0.0"
|
pify "^2.0.0"
|
||||||
|
|
||||||
|
path-type@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||||
|
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||||
|
|
||||||
pbkdf2@^3.0.3:
|
pbkdf2@^3.0.3:
|
||||||
version "3.0.16"
|
version "3.0.16"
|
||||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c"
|
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c"
|
||||||
|
@ -4083,6 +4262,11 @@ pbkdf2@^3.0.3:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
sha.js "^2.4.8"
|
sha.js "^2.4.8"
|
||||||
|
|
||||||
|
picomatch@^2.0.5:
|
||||||
|
version "2.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
|
||||||
|
integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
|
||||||
|
|
||||||
pify@^2.0.0:
|
pify@^2.0.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||||
|
@ -4496,6 +4680,11 @@ ret@~0.1.10:
|
||||||
version "0.1.15"
|
version "0.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||||
|
|
||||||
|
reusify@^1.0.0:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
rimraf@2, rimraf@^2.2.8, rimraf@^2.6.2:
|
rimraf@2, rimraf@^2.2.8, rimraf@^2.6.2:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||||
|
@ -4516,6 +4705,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||||
hash-base "^3.0.0"
|
hash-base "^3.0.0"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
|
|
||||||
|
rollup-plugin-alias@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup-plugin-alias/-/rollup-plugin-alias-2.0.0.tgz#eea77466a8a8a063007c8edb2e9d7a3d06cbb889"
|
||||||
|
integrity sha512-JVwxV9nwzjc0q7JmrV9jvZlJ8FykNd5r7RmYps8i/7v+vcmmVpeMvXrljhCboYErf4VZ2z9FEj+fP7eJlEGfug==
|
||||||
|
dependencies:
|
||||||
|
slash "^3.0.0"
|
||||||
|
|
||||||
rollup-plugin-babel@^4.3.2:
|
rollup-plugin-babel@^4.3.2:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-4.3.2.tgz#8c0e1bd7aa9826e90769cf76895007098ffd1413"
|
resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-4.3.2.tgz#8c0e1bd7aa9826e90769cf76895007098ffd1413"
|
||||||
|
@ -4523,6 +4719,17 @@ rollup-plugin-babel@^4.3.2:
|
||||||
"@babel/helper-module-imports" "^7.0.0"
|
"@babel/helper-module-imports" "^7.0.0"
|
||||||
rollup-pluginutils "^2.3.0"
|
rollup-pluginutils "^2.3.0"
|
||||||
|
|
||||||
|
rollup-plugin-copy@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-3.1.0.tgz#435589857f4e346ea63fc137d99dcc1b25f51c3b"
|
||||||
|
integrity sha512-oVw3ljRV5jv7Yw/6eCEHntVs9Mc+NFglc0iU0J8ei76gldYmtBQ0M/j6WAkZUFVRSrhgfCrEakUllnN87V2f4w==
|
||||||
|
dependencies:
|
||||||
|
"@types/fs-extra" "^8.0.0"
|
||||||
|
colorette "^1.1.0"
|
||||||
|
fs-extra "^8.1.0"
|
||||||
|
globby "10.0.1"
|
||||||
|
is-plain-object "^3.0.0"
|
||||||
|
|
||||||
rollup-plugin-flow@^1.1.1:
|
rollup-plugin-flow@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/rollup-plugin-flow/-/rollup-plugin-flow-1.1.1.tgz#6ce568f1dd559666b77ab76b4bae251407528db6"
|
resolved "https://registry.yarnpkg.com/rollup-plugin-flow/-/rollup-plugin-flow-1.1.1.tgz#6ce568f1dd559666b77ab76b4bae251407528db6"
|
||||||
|
@ -4562,6 +4769,11 @@ run-async@^2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-promise "^2.1.0"
|
is-promise "^2.1.0"
|
||||||
|
|
||||||
|
run-parallel@^1.1.9:
|
||||||
|
version "1.1.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
|
||||||
|
integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
|
||||||
|
|
||||||
run-queue@^1.0.0, run-queue@^1.0.3:
|
run-queue@^1.0.0, run-queue@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
|
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
|
||||||
|
@ -4682,6 +4894,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||||
|
|
||||||
|
slash@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
slice-ansi@0.0.4:
|
slice-ansi@0.0.4:
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||||
|
@ -5064,6 +5281,13 @@ to-regex-range@^2.1.0:
|
||||||
is-number "^3.0.0"
|
is-number "^3.0.0"
|
||||||
repeat-string "^1.6.1"
|
repeat-string "^1.6.1"
|
||||||
|
|
||||||
|
to-regex-range@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||||
|
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||||
|
dependencies:
|
||||||
|
is-number "^7.0.0"
|
||||||
|
|
||||||
to-regex@^3.0.1, to-regex@^3.0.2:
|
to-regex@^3.0.1, to-regex@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
|
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
|
||||||
|
|
Loading…
Reference in a new issue