lbry-desktop/ui/redux/selectors/subscriptions.js

166 lines
5.6 KiB
JavaScript
Raw Permalink Normal View History

2018-11-21 22:20:55 +01:00
import { SUGGESTED_FEATURED, SUGGESTED_TOP_SUBSCRIBED } from 'constants/subscriptions';
import { createSelector } from 'reselect';
import {
selectAllFetchingChannelClaims,
2018-10-19 22:38:07 +02:00
makeSelectChannelForClaimUri,
parseURI,
2019-09-04 18:00:56 +02:00
makeSelectClaimForUri,
2021-07-15 22:22:44 +02:00
isURIEqual,
} from 'lbry-redux';
2018-11-21 22:20:55 +01:00
import { swapKeyAndValue } from 'util/swap-json';
2017-12-08 21:14:35 +01:00
2018-10-19 22:38:07 +02:00
// Returns the entire subscriptions state
const selectState = (state) => state.subscriptions || {};
2017-12-08 21:14:35 +01:00
2018-10-19 22:38:07 +02:00
// Returns the list of channel uris a user is subscribed to
2019-03-05 05:46:57 +01:00
export const selectSubscriptions = createSelector(
selectState,
(state) => state.subscriptions && state.subscriptions.sort((a, b) => a.channelName.localeCompare(b.channelName))
2019-03-05 05:46:57 +01:00
);
2018-10-19 22:38:07 +02:00
export const selectFollowing = createSelector(selectState, (state) => state.following && state.following);
2020-11-02 17:51:08 +01:00
2018-10-19 22:38:07 +02:00
// Fetching list of users subscriptions
export const selectIsFetchingSubscriptions = createSelector(selectState, (state) => state.loading);
2018-10-19 22:38:07 +02:00
// The current view mode on the subscriptions page
export const selectViewMode = createSelector(selectState, (state) => state.viewMode);
2018-11-21 22:20:55 +01:00
// Suggested subscriptions from internal apis
export const selectSuggested = createSelector(selectState, (state) => state.suggested);
export const selectIsFetchingSuggested = createSelector(selectState, (state) => state.loadingSuggested);
2018-11-21 22:20:55 +01:00
export const selectSuggestedChannels = 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) => {
2018-11-21 22:20:55 +01:00
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) => ({
2019-06-11 20:10:58 +02:00
uri,
label: suggestedChannels[uri],
}));
2018-11-21 22:20:55 +01:00
}
);
export const selectFirstRunCompleted = createSelector(selectState, (state) => state.firstRunCompleted);
export const selectshowSuggestedSubs = createSelector(selectState, (state) => state.showSuggestedSubs);
2018-11-21 22:20:55 +01:00
2018-10-19 22:38:07 +02:00
// Fetching any claims that are a part of a users subscriptions
export const selectSubscriptionsBeingFetched = createSelector(
selectSubscriptions,
selectAllFetchingChannelClaims,
(subscriptions, fetchingChannelClaims) => {
const fetchingSubscriptionMap = {};
subscriptions.forEach((sub) => {
2018-10-19 22:38:07 +02:00
const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
if (isFetching) {
fetchingSubscriptionMap[sub.uri] = true;
}
});
return fetchingSubscriptionMap;
}
);
// Returns true if a user is subscribed to the channel associated with the uri passed in
// Accepts content or channel uris
export const makeSelectChannelInSubscriptions = (uri) =>
createSelector(selectSubscriptions, (subscriptions) => subscriptions.some((sub) => sub.uri === uri));
export const makeSelectIsSubscribed = (uri) =>
2018-10-19 22:38:07 +02:00
createSelector(
selectSubscriptions,
makeSelectChannelForClaimUri(uri, true),
2019-09-04 18:00:56 +02:00
makeSelectClaimForUri(uri),
(subscriptions, channelUri, claim) => {
2018-10-19 22:38:07 +02:00
if (channelUri) {
2021-07-15 22:22:44 +02:00
return subscriptions.some((sub) => isURIEqual(sub.uri, channelUri));
}
2018-10-19 22:38:07 +02:00
// If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
2019-08-14 20:09:45 +02:00
let isChannel;
try {
({ isChannel } = parseURI(uri));
} catch (e) {}
2019-09-04 18:00:56 +02:00
if (isChannel && claim) {
const uri = claim.permanent_url;
2021-07-15 22:22:44 +02:00
return subscriptions.some((sub) => isURIEqual(sub.uri, uri));
}
if (isChannel && !claim) {
2021-07-15 22:22:44 +02:00
return subscriptions.some((sub) => isURIEqual(sub.uri, uri));
2018-10-19 22:38:07 +02:00
}
return false;
}
2018-10-19 22:38:07 +02:00
);
export const makeSelectNotificationsDisabled = (uri) =>
createSelector(
2020-11-02 17:51:08 +01:00
selectFollowing,
makeSelectChannelForClaimUri(uri, true),
makeSelectClaimForUri(uri),
(following, channelUri, claim) => {
if (channelUri) {
return following.some((following) => following.uri === channelUri && following.notificationsDisabled);
}
2018-11-29 00:21:33 +01:00
2020-11-02 17:51:08 +01:00
// If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
let isChannel;
try {
({ isChannel } = parseURI(uri));
} catch (e) {}
if (isChannel && claim) {
const uri = claim.permanent_url;
const disabled = following.some((sub) => {
2020-11-02 17:51:08 +01:00
return sub.uri === uri && sub.notificationsDisabled === true;
});
return disabled;
}
2020-11-02 17:51:08 +01:00
return true;
}
);