2017-12-08 21:14:35 +01:00
|
|
|
// @flow
|
2017-12-21 18:32:51 +01:00
|
|
|
import * as ACTIONS from 'constants/action_types';
|
2020-06-15 22:33:03 +02:00
|
|
|
import REWARDS from 'rewards';
|
|
|
|
import { Lbryio } from 'lbryinc';
|
|
|
|
import { doClaimRewardType } from 'redux/actions/rewards';
|
2019-10-15 06:20:12 +02:00
|
|
|
import { selectUnreadByChannel } from 'redux/selectors/subscriptions';
|
2019-11-19 21:34:25 +01:00
|
|
|
import { parseURI } from 'lbry-redux';
|
2017-12-08 21:14:35 +01:00
|
|
|
|
2019-03-18 06:09:50 +01:00
|
|
|
export const doSetViewMode = (viewMode: ViewMode) => (dispatch: Dispatch) =>
|
2018-10-19 22:38:07 +02:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.SET_VIEW_MODE,
|
|
|
|
data: viewMode,
|
|
|
|
});
|
|
|
|
|
2019-05-07 23:38:29 +02:00
|
|
|
export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) =>
|
2017-12-13 22:36:30 +01:00
|
|
|
dispatch({
|
2018-05-07 06:50:55 +02:00
|
|
|
type: ACTIONS.SET_SUBSCRIPTION_LATEST,
|
|
|
|
data: {
|
|
|
|
subscription,
|
|
|
|
uri,
|
|
|
|
},
|
2017-12-08 21:14:35 +01:00
|
|
|
});
|
|
|
|
|
2018-10-19 22:38:07 +02:00
|
|
|
// Populate a channels unread subscriptions or update the type
|
|
|
|
export const doUpdateUnreadSubscriptions = (
|
|
|
|
channelUri: string,
|
|
|
|
uris: ?Array<string>,
|
|
|
|
type: ?SubscriptionNotificationType
|
2019-03-18 06:09:50 +01:00
|
|
|
) => (dispatch: Dispatch, getState: GetState) => {
|
2018-10-19 22:38:07 +02:00
|
|
|
const state = getState();
|
|
|
|
const unreadByChannel = selectUnreadByChannel(state);
|
|
|
|
const currentUnreadForChannel: UnreadSubscription = unreadByChannel[channelUri];
|
|
|
|
|
|
|
|
let newUris;
|
|
|
|
let newType;
|
|
|
|
|
|
|
|
if (!currentUnreadForChannel) {
|
|
|
|
newUris = uris;
|
|
|
|
newType = type;
|
|
|
|
} else {
|
|
|
|
if (uris) {
|
|
|
|
// If a channel currently has no unread uris, just add them all
|
|
|
|
if (!currentUnreadForChannel.uris || !currentUnreadForChannel.uris.length) {
|
|
|
|
newUris = uris;
|
|
|
|
} else {
|
|
|
|
// They already have unreads and now there are new ones
|
|
|
|
// Add the new ones to the beginning of the list
|
|
|
|
// Make sure there are no duplicates
|
|
|
|
const currentUnreadUris = currentUnreadForChannel.uris;
|
|
|
|
newUris = uris.filter(uri => !currentUnreadUris.includes(uri)).concat(currentUnreadUris);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
newUris = currentUnreadForChannel.uris;
|
|
|
|
}
|
|
|
|
|
|
|
|
newType = type || currentUnreadForChannel.type;
|
|
|
|
}
|
|
|
|
|
2018-03-06 08:44:36 +01:00
|
|
|
dispatch({
|
2018-10-19 22:38:07 +02:00
|
|
|
type: ACTIONS.UPDATE_SUBSCRIPTION_UNREADS,
|
2018-05-07 06:50:55 +02:00
|
|
|
data: {
|
2018-10-19 22:38:07 +02:00
|
|
|
channel: channelUri,
|
|
|
|
uris: newUris,
|
|
|
|
type: newType,
|
2018-05-07 06:50:55 +02:00
|
|
|
},
|
2018-03-06 08:44:36 +01:00
|
|
|
});
|
2018-10-19 22:38:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Remove multiple files (or all) from a channels unread subscriptions
|
2018-11-27 23:16:23 +01:00
|
|
|
export const doRemoveUnreadSubscriptions = (channelUri: ?string, readUris: ?Array<string>) => (
|
2019-03-18 06:09:50 +01:00
|
|
|
dispatch: Dispatch,
|
2018-10-19 22:38:07 +02:00
|
|
|
getState: GetState
|
|
|
|
) => {
|
|
|
|
const state = getState();
|
|
|
|
const unreadByChannel = selectUnreadByChannel(state);
|
2018-11-27 23:16:23 +01:00
|
|
|
|
|
|
|
// If no channel is passed in, remove all unread subscriptions from all channels
|
|
|
|
if (!channelUri) {
|
|
|
|
return dispatch({
|
|
|
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
|
|
|
data: { channel: null },
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-19 22:38:07 +02:00
|
|
|
const currentChannelUnread = unreadByChannel[channelUri];
|
|
|
|
if (!currentChannelUnread || !currentChannelUnread.uris) {
|
2018-11-27 23:16:23 +01:00
|
|
|
// Channel passed in doesn't have any unreads
|
2018-10-19 22:38:07 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// For each uri passed in, remove it from the list of unread uris
|
2018-11-27 23:16:23 +01:00
|
|
|
// If no uris are passed in, remove them all
|
|
|
|
let newUris;
|
|
|
|
if (readUris) {
|
|
|
|
const urisToRemoveMap = readUris.reduce(
|
|
|
|
(acc, val) => ({
|
|
|
|
...acc,
|
|
|
|
[val]: true,
|
|
|
|
}),
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
|
|
|
|
const filteredUris = currentChannelUnread.uris.filter(uri => !urisToRemoveMap[uri]);
|
|
|
|
newUris = filteredUris.length ? filteredUris : null;
|
|
|
|
} else {
|
|
|
|
newUris = null;
|
|
|
|
}
|
2018-10-19 22:38:07 +02:00
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
|
|
|
data: {
|
|
|
|
channel: channelUri,
|
|
|
|
uris: newUris,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Remove a single file from a channels unread subscriptions
|
2019-05-07 23:38:29 +02:00
|
|
|
export const doRemoveUnreadSubscription = (channelUri: string, readUri: string) => (dispatch: Dispatch) => {
|
2018-10-19 22:38:07 +02:00
|
|
|
dispatch(doRemoveUnreadSubscriptions(channelUri, [readUri]));
|
|
|
|
};
|
2018-03-06 08:44:36 +01:00
|
|
|
|
2019-05-07 23:38:29 +02:00
|
|
|
export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
2018-05-07 06:50:55 +02:00
|
|
|
const {
|
|
|
|
settings: { daemonSettings },
|
|
|
|
} = getState();
|
2019-10-14 23:25:20 +02:00
|
|
|
const { share_usage_data: shareSetting } = daemonSettings;
|
|
|
|
const isSharingData = shareSetting || IS_WEB;
|
2018-05-07 06:50:55 +02:00
|
|
|
|
2018-10-31 18:08:30 +01:00
|
|
|
const subscriptionUri = subscription.uri;
|
|
|
|
if (!subscriptionUri.startsWith('lbry://')) {
|
2019-10-13 19:41:51 +02:00
|
|
|
throw Error(`Subscription uris must include the "lbry://" prefix.\nTried to subscribe to ${subscriptionUri}`);
|
2018-10-31 18:08:30 +01:00
|
|
|
}
|
|
|
|
|
2018-03-26 09:31:52 +02:00
|
|
|
dispatch({
|
2018-05-07 06:50:55 +02:00
|
|
|
type: ACTIONS.CHANNEL_SUBSCRIBE,
|
|
|
|
data: subscription,
|
2018-03-26 09:31:52 +02:00
|
|
|
});
|
|
|
|
|
2018-05-07 06:50:55 +02:00
|
|
|
// if the user isn't sharing data, keep the subscriptions entirely in the app
|
2019-10-14 23:25:20 +02:00
|
|
|
if (isSharingData || IS_WEB) {
|
2019-08-30 01:18:06 +02:00
|
|
|
const { channelClaimId } = parseURI(subscription.uri);
|
2018-05-07 06:50:55 +02:00
|
|
|
// They are sharing data, we can store their subscriptions in our internal database
|
|
|
|
Lbryio.call('subscription', 'new', {
|
|
|
|
channel_name: subscription.channelName,
|
2019-08-30 01:18:06 +02:00
|
|
|
claim_id: channelClaimId,
|
2018-05-07 06:50:55 +02:00
|
|
|
});
|
2018-08-09 13:45:07 +02:00
|
|
|
|
2020-06-15 22:33:03 +02:00
|
|
|
dispatch(doClaimRewardType(REWARDS.TYPE_SUBSCRIPTION, { failSilently: true }));
|
2018-05-07 06:50:55 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-07 23:38:29 +02:00
|
|
|
export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
2018-05-07 06:50:55 +02:00
|
|
|
const {
|
|
|
|
settings: { daemonSettings },
|
|
|
|
} = getState();
|
2019-10-14 23:25:20 +02:00
|
|
|
const { share_usage_data: shareSetting } = daemonSettings;
|
|
|
|
const isSharingData = shareSetting || IS_WEB;
|
2018-05-07 06:50:55 +02:00
|
|
|
|
2018-03-26 09:31:52 +02:00
|
|
|
dispatch({
|
2018-05-07 06:50:55 +02:00
|
|
|
type: ACTIONS.CHANNEL_UNSUBSCRIBE,
|
|
|
|
data: subscription,
|
2018-03-26 09:31:52 +02:00
|
|
|
});
|
|
|
|
|
2018-05-07 06:50:55 +02:00
|
|
|
if (isSharingData) {
|
2019-08-30 01:18:06 +02:00
|
|
|
const { channelClaimId } = parseURI(subscription.uri);
|
2018-05-07 06:50:55 +02:00
|
|
|
Lbryio.call('subscription', 'delete', {
|
2019-08-30 01:18:06 +02:00
|
|
|
claim_id: channelClaimId,
|
2018-05-07 06:50:55 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-03-18 06:09:50 +01:00
|
|
|
export const doFetchRecommendedSubscriptions = () => (dispatch: Dispatch) => {
|
2018-11-21 22:20:55 +01:00
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START,
|
|
|
|
});
|
|
|
|
|
|
|
|
return Lbryio.call('subscription', 'suggest')
|
|
|
|
.then(suggested =>
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_SUCCESS,
|
|
|
|
data: suggested,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
.catch(error =>
|
|
|
|
dispatch({
|
|
|
|
type: ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_FAIL,
|
|
|
|
error,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|