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

145 lines
4.5 KiB
JavaScript
Raw Normal View History

2021-06-11 22:49:18 +02:00
// @flow
import * as ACTIONS from 'constants/action_types';
import { SIDEBAR_SUBS_DISPLAYED } from 'constants/subscriptions';
import REWARDS from 'rewards';
import { Lbryio } from 'lbryinc';
import { doClaimSearch } from 'redux/actions/claims';
import { doClaimRewardType } from 'redux/actions/rewards';
import { getChannelFromClaim } from 'util/claim';
import { parseURI } from 'util/lbryURI';
import { doAlertWaitingForSync } from 'redux/actions/app';
2021-06-11 22:49:18 +02:00
import { doToast } from 'redux/actions/notifications';
import { selectSubscriptions } from 'redux/selectors/subscriptions';
2017-12-08 21:14:35 +01:00
2021-06-11 22:49:18 +02:00
type SubscriptionArgs = {
channelName: string,
uri: string,
notificationsDisabled?: boolean,
};
const FETCH_LAST_ACTIVE_SUBS_MIN_INTERVAL_MS = 5 * 60 * 1000;
let activeSubsLastFetchedTime = 0;
export function doToggleSubscription(
subscription: SubscriptionArgs,
followToast: boolean,
isSubscribed: boolean = false
) {
2021-06-11 22:49:18 +02:00
return async (dispatch: Dispatch, getState: GetState) => {
const {
settings: { daemonSettings },
sync: { prefsReady: ready },
} = getState();
2021-06-11 22:49:18 +02:00
if (!ready) {
return dispatch(doAlertWaitingForSync());
}
2021-06-11 22:49:18 +02:00
const { share_usage_data: shareSetting } = daemonSettings;
const isSharingData = shareSetting || IS_WEB;
2018-10-31 18:08:30 +01:00
2021-06-11 22:49:18 +02:00
if (!isSubscribed) {
const subscriptionUri = subscription.uri;
if (!subscriptionUri.startsWith('lbry://')) {
throw Error(`Subscription uris must include the "lbry://" prefix.\nTried to subscribe to ${subscriptionUri}`);
}
}
2021-06-11 22:49:18 +02:00
dispatch({
type: !isSubscribed ? ACTIONS.CHANNEL_SUBSCRIBE : ACTIONS.CHANNEL_UNSUBSCRIBE,
data: subscription,
});
2021-06-11 22:49:18 +02:00
// if the user isn't sharing data, keep the subscriptions entirely in the app
if (isSharingData || IS_WEB) {
const { channelClaimId } = parseURI(subscription.uri);
2021-06-11 22:49:18 +02:00
if (!isSubscribed) {
// They are sharing data, we can store their subscriptions in our internal database
Lbryio.call('subscription', 'new', {
channel_name: subscription.channelName,
claim_id: channelClaimId,
notifications_disabled: subscription.notificationsDisabled,
});
2021-06-11 22:49:18 +02:00
dispatch(doClaimRewardType(REWARDS.TYPE_SUBSCRIPTION, { failSilently: true }));
} else {
Lbryio.call('subscription', 'delete', {
claim_id: channelClaimId,
});
}
}
2021-07-05 18:49:58 +02:00
if (followToast) {
dispatch(
doToast({
message: __(!isSubscribed ? 'You followed %CHANNEL_NAME%!' : 'Unfollowed %CHANNEL_NAME%.', {
CHANNEL_NAME: subscription.channelName,
}),
})
);
2021-07-05 18:49:58 +02:00
}
// Reset last-fetch counter
activeSubsLastFetchedTime = 0;
2021-06-11 22:49:18 +02:00
};
}
2021-07-05 18:49:58 +02:00
export function doChannelSubscribe(subscription: SubscriptionArgs, followToast: boolean = true) {
2021-06-11 22:49:18 +02:00
return (dispatch: Dispatch) => {
2021-07-05 18:49:58 +02:00
return dispatch(doToggleSubscription(subscription, followToast));
2021-06-11 22:49:18 +02:00
};
}
2021-07-05 18:49:58 +02:00
export function doChannelUnsubscribe(subscription: SubscriptionArgs, followToast: boolean = true) {
2021-06-11 22:49:18 +02:00
return (dispatch: Dispatch) => {
2021-07-05 18:49:58 +02:00
return dispatch(doToggleSubscription(subscription, followToast, true));
2021-06-11 22:49:18 +02:00
};
}
export function doFetchLastActiveSubs(forceFetch: boolean = false, count: number = SIDEBAR_SUBS_DISPLAYED) {
function parseIdFromUri(uri) {
try {
const { channelClaimId } = parseURI(uri);
return channelClaimId;
} catch {
return '';
}
}
return (dispatch: Dispatch, getState: GetState) => {
const now = Date.now();
if (!forceFetch && now - activeSubsLastFetchedTime < FETCH_LAST_ACTIVE_SUBS_MIN_INTERVAL_MS) {
dispatch({ type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_SKIP });
return;
}
const state = getState();
const subscriptions = selectSubscriptions(state);
const channelIds = subscriptions.map((sub) => parseIdFromUri(sub.uri));
activeSubsLastFetchedTime = now;
const searchOptions = {
limit_claims_per_channel: 1,
channel_ids: channelIds,
claim_type: ['stream', 'repost'],
page: 1,
page_size: count,
no_totals: true,
order_by: ['release_time'],
};
dispatch(doClaimSearch(searchOptions))
.then((results) => {
const values = Object.values(results || {});
dispatch({
type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_DONE,
// $FlowFixMe https://github.com/facebook/flow/issues/2221
data: values.map((v) => getChannelFromClaim(v.stream)),
});
})
.catch(() => {
dispatch({ type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_FAIL });
});
};
}