mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-29 16:31:33 +00:00
187 lines
5.9 KiB
JavaScript
187 lines
5.9 KiB
JavaScript
import { createSelector } from 'reselect';
|
|
import {
|
|
selectAllClaimsByChannel,
|
|
selectClaimsById,
|
|
selectAllFetchingChannelClaims,
|
|
makeSelectChannelForClaimUri,
|
|
selectClaimsByUri,
|
|
parseURI,
|
|
} from 'lbry-redux';
|
|
|
|
// Returns the entire subscriptions state
|
|
const selectState = state => state.subscriptions || {};
|
|
|
|
// Returns the list of channel uris a user is subscribed to
|
|
export const selectSubscriptions = createSelector(selectState, state => state.subscriptions);
|
|
|
|
// Fetching list of users subscriptions
|
|
export const selectIsFetchingSubscriptions = createSelector(selectState, state => state.loading);
|
|
|
|
// The current view mode on the subscriptions page
|
|
export const selectViewMode = createSelector(selectState, state => state.viewMode);
|
|
|
|
// Fetching any claims that are a part of a users subscriptions
|
|
export const selectSubscriptionsBeingFetched = createSelector(
|
|
selectSubscriptions,
|
|
selectAllFetchingChannelClaims,
|
|
(subscriptions, fetchingChannelClaims) => {
|
|
const fetchingSubscriptionMap = {};
|
|
subscriptions.forEach(sub => {
|
|
const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
|
|
if (isFetching) {
|
|
fetchingSubscriptionMap[sub.uri] = true;
|
|
}
|
|
});
|
|
|
|
return fetchingSubscriptionMap;
|
|
}
|
|
);
|
|
|
|
export const selectUnreadByChannel = createSelector(selectState, state => state.unread);
|
|
|
|
// Returns the current total of unread subscriptions
|
|
export const selectUnreadAmount = 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
|
|
export const selectUnreadSubscriptions = createSelector(
|
|
selectUnreadAmount,
|
|
selectUnreadByChannel,
|
|
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
|
|
export const makeSelectUnreadByChannel = uri =>
|
|
createSelector(selectUnreadByChannel, unread => unread[uri]);
|
|
|
|
// Returns the first page of claims for every channel a user is subscribed to
|
|
export const selectSubscriptionClaims = createSelector(
|
|
selectAllClaimsByChannel,
|
|
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
|
|
export const makeSelectIsSubscribed = uri =>
|
|
createSelector(
|
|
selectSubscriptions,
|
|
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 } = parseURI(uri);
|
|
if (isChannel) {
|
|
const uriWithPrefix = uri.startsWith('lbry://') ? uri : `lbry://${uri}`;
|
|
return subscriptions.some(sub => sub.uri === uriWithPrefix);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
);
|