check channels and populate notifications and download queue
This commit is contained in:
parent
aba062ae43
commit
e7fca1b911
8 changed files with 179 additions and 31 deletions
1
flow-typed/Claim.js
vendored
1
flow-typed/Claim.js
vendored
|
@ -67,6 +67,7 @@ declare type GenericMetadata = {
|
|||
languages?: Array<string>,
|
||||
tags?: Array<string>,
|
||||
locations?: Array<Location>,
|
||||
release_time?: number, // this shouldn't be here, but... fixme?
|
||||
};
|
||||
|
||||
declare type ChannelMetadata = GenericMetadata & {
|
||||
|
|
|
@ -358,8 +358,9 @@ export const LBRYIO_NOTIFICATION_SEEN_FAILED = 'LBRYIO_NOTIFICATION_SEEN_FAILED'
|
|||
export const LBRYIO_NOTIFICATION_DELETE_STARTED = 'LBRYIO_NOTIFICATION_DELETE_STARTED';
|
||||
export const LBRYIO_NOTIFICATION_DELETE_COMPLETED = 'LBRYIO_NOTIFICATION_DELETE_COMPLETED';
|
||||
export const LBRYIO_NOTIFICATION_DELETE_FAILED = 'LBRYIO_NOTIFICATION_DELETE_FAILED';
|
||||
export const LOCAL_NOTIFICATION_DELETE_COMPLETED = 'LBRYIO_NOTIFICATION_DELETE_COMPLETED';
|
||||
export const LOCAL_NOTIFICATION_SEEN_COMPLETED = 'LBRYIO_NOTIFICATION_DELETE_COMPLETED';
|
||||
export const LOCAL_NOTIFICATION_DELETE = 'LBRYIO_NOTIFICATION_DELETE';
|
||||
export const LOCAL_NOTIFICATION_ADD = 'LBRYIO_NOTIFICATION_ADD';
|
||||
export const LOCAL_NOTIFICATION_SEEN = 'LBRYIO_NOTIFICATION_SEEN';
|
||||
|
||||
export const CREATE_TOAST = 'CREATE_TOAST';
|
||||
export const DISMISS_TOAST = 'DISMISS_TOAST';
|
||||
|
|
|
@ -186,16 +186,22 @@ export function doLbryioDeleteNotification(notificationId: number) {
|
|||
};
|
||||
}
|
||||
|
||||
export function doLocalAddNotification(notifications: Array<any>) {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({ type: ACTIONS.LOCAL_NOTIFICATION_ADD, data: { notifications } });
|
||||
};
|
||||
}
|
||||
|
||||
export function doLocalDeleteNotification(notificationId: number) {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({ type: ACTIONS.LOCAL_NOTIFICATION_DELETE_COMPLETED, data: { notificationId } });
|
||||
dispatch({ type: ACTIONS.LOCAL_NOTIFICATION_DELETE, data: { notificationId } });
|
||||
};
|
||||
}
|
||||
|
||||
export function doLocalSeeNotification(notificationIds: Array<string>) {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({
|
||||
type: ACTIONS.LOCAL_NOTIFICATION_SEEN_COMPLETED,
|
||||
type: ACTIONS.LOCAL_NOTIFICATION_SEEN,
|
||||
data: {
|
||||
notificationIds,
|
||||
},
|
||||
|
|
|
@ -5,8 +5,17 @@ import { Lbryio } from 'lbryinc';
|
|||
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||
import { parseURI } from 'util/lbryURI';
|
||||
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||
import { doToast } from 'redux/actions/notifications';
|
||||
import { makeSelectNotificationsDisabled, selectSubscriptionUris } from '../selectors/subscriptions';
|
||||
import { doLocalAddNotification, doToast } from 'redux/actions/notifications';
|
||||
import { setUnion } from 'util/set-operations';
|
||||
import { getNotificationFromClaim } from 'util/notifications';
|
||||
|
||||
import {
|
||||
makeSelectNotificationsDisabled,
|
||||
selectDownloadEnabledUrls,
|
||||
makeSelectLastReleaseForUri,
|
||||
selectSubscriptionUris,
|
||||
} from 'redux/selectors/subscriptions';
|
||||
import Lbry from '../../lbry';
|
||||
|
||||
type SubscriptionArgs = {
|
||||
channelName: string,
|
||||
|
@ -89,27 +98,34 @@ export function doChannelUnsubscribe(subscription: SubscriptionArgs, followToast
|
|||
|
||||
export function doAddUriToDownloadQueue(uri: string) {
|
||||
return (dispatch: Dispatch) => {
|
||||
return {
|
||||
type: ACTIONS.SUBSCRIPTION_DOWNLOAD_ADD,
|
||||
data: uri,
|
||||
return dispatch(doAddUrisToDownloadQueue([uri]));
|
||||
};
|
||||
}
|
||||
|
||||
export function doAddUrisToDownloadQueue(uris: Array<string>) {
|
||||
return (dispatch: Dispatch) => {
|
||||
return dispatch({
|
||||
type: ACTIONS.SUBSCRIPTION_DOWNLOAD_ADD,
|
||||
data: uris,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function doRemoveUriFromDownloadQueue(uri: string) {
|
||||
return (dispatch: Dispatch) => {
|
||||
return {
|
||||
return dispatch({
|
||||
type: ACTIONS.SUBSCRIPTION_DOWNLOAD_REMOVE,
|
||||
data: uri,
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function doUpdateLastReleaseForUri(uri: string, timestamp: number) {
|
||||
export function doUpdateLastReleasesForUri(entries: { [string]: number }) {
|
||||
return (dispatch: Dispatch) => {
|
||||
return dispatch({
|
||||
type: ACTIONS.SUBSCRIPTION_RELEASE_UPDATE,
|
||||
data: { uri, timestamp },
|
||||
// data: entries = { [uri]: timestamp } >
|
||||
data: entries,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -123,22 +139,66 @@ export function doSubscriptionDownloadEnableForUri(uri: string, enable: boolean)
|
|||
};
|
||||
}
|
||||
|
||||
export function doCheckSubscribedPublishes() {
|
||||
export function doCheckChannelPublishes() {
|
||||
// finish this
|
||||
return async (dispatch: Dispatch, getState: GetState) => {
|
||||
const state = getState();
|
||||
// for sub in subs, if notify+ or download+, getnewpublishes()
|
||||
const subs = selectSubscriptionUris(state);
|
||||
for (const sub in subs) {
|
||||
// $FlowFixMe
|
||||
const hasNotify = makeSelectNotificationsDisabled(sub.uri)(state); // eslint-disable-line
|
||||
// const shouldDownload =
|
||||
// doFileGet(uri)
|
||||
}
|
||||
const subs = new Set(selectSubscriptionUris(state));
|
||||
const dls = new Set(selectDownloadEnabledUrls(state));
|
||||
const channels = Array.from(setUnion(subs, dls));
|
||||
|
||||
// ./lbrynet claim search --channel_id="9d4c31875f534dc1f989db6c13b92ab1aab85ecf" --release_time=">1647101965" --order_by="release_time"
|
||||
// add most recent release time
|
||||
// add to downloads,
|
||||
// add notifications,
|
||||
for (const channelUri of channels) {
|
||||
// $FlowFixMe
|
||||
const hasNotify = !makeSelectNotificationsDisabled(channelUri)(state); // eslint-disable-line
|
||||
const hasDownload = dls.has(channelUri);
|
||||
const lastRelease = makeSelectLastReleaseForUri(channelUri)(state);
|
||||
if (hasNotify || hasDownload) {
|
||||
// getNewPublishes since ???
|
||||
let lastTime = Math.floor(Date.now() / 1000);
|
||||
const results = await Lbry.claim_search({
|
||||
channel: channelUri,
|
||||
release_time: `>${lastRelease}`,
|
||||
order_by: ['release_time'],
|
||||
});
|
||||
const latest = results.items;
|
||||
if (latest.length && latest[0].value && latest[0].value.release_time) {
|
||||
lastTime = latest[0].value.release_time;
|
||||
}
|
||||
// dispatch release time update()
|
||||
const notifications = [];
|
||||
const downloads = [];
|
||||
const releaseEntries = {}; // refactor to {} maybe
|
||||
for (const claim of latest) {
|
||||
if (hasNotify) {
|
||||
const notification = getNotificationFromClaim(claim);
|
||||
notifications.push(notification);
|
||||
}
|
||||
if (hasDownload) {
|
||||
downloads.push(claim.permanent_url);
|
||||
}
|
||||
releaseEntries[channelUri] = lastTime;
|
||||
}
|
||||
dispatch(doLocalAddNotification(notifications));
|
||||
dispatch(doAddUrisToDownloadQueue(downloads));
|
||||
// dispatch last check for channelUri
|
||||
dispatch(doUpdateLastReleasesForUri(releaseEntries));
|
||||
}
|
||||
}
|
||||
// do download
|
||||
};
|
||||
}
|
||||
|
||||
export function doCheckChannelsSubscribe() {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch(doCheckChannelPublishes());
|
||||
setInterval(() => dispatch(doCheckChannelPublishes()), 10000);
|
||||
};
|
||||
}
|
||||
|
||||
export function doDownloadQueue() {
|
||||
return (dispatch: Dispatch) => {
|
||||
// for each download, trigger download,
|
||||
// if downloading, back off
|
||||
};
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ export default handleActions(
|
|||
};
|
||||
},
|
||||
|
||||
[ACTIONS.LOCAL_NOTIFICATION_DELETE_COMPLETED]: (state, action) => {
|
||||
[ACTIONS.LOCAL_NOTIFICATION_DELETE]: (state, action) => {
|
||||
const { localNotifications } = state;
|
||||
const { notificationId } = action.data;
|
||||
|
||||
|
@ -147,8 +147,12 @@ export default handleActions(
|
|||
localNotifications: deleteId(localNotifications, notificationId),
|
||||
};
|
||||
},
|
||||
|
||||
[ACTIONS.LOCAL_NOTIFICATION_SEEN_COMPLETED]: (state, action) => {
|
||||
[ACTIONS.LOCAL_NOTIFICATION_ADD]: (state, action) => {
|
||||
const { localNotifications } = state;
|
||||
const { notifications } = action.data;
|
||||
return localNotifications.concat(notifications);
|
||||
},
|
||||
[ACTIONS.LOCAL_NOTIFICATION_SEEN]: (state, action) => {
|
||||
const { localNotifications } = state;
|
||||
const { notificationIds } = action.data;
|
||||
|
||||
|
|
|
@ -94,9 +94,11 @@ export default handleActions(
|
|||
},
|
||||
[ACTIONS.SUBSCRIPTION_RELEASE_UPDATE]: (state: SubscriptionState, action): SubscriptionState => {
|
||||
const { lastReleaseBySubUrl } = state;
|
||||
const { uri, timestamp } = action.data;
|
||||
const entries = action.data;
|
||||
|
||||
Object.entries(entries).forEach(([uri, timestamp]) => {
|
||||
lastReleaseBySubUrl[uri] = timestamp;
|
||||
});
|
||||
return {
|
||||
...state,
|
||||
lastReleaseBySubUrl,
|
||||
|
|
|
@ -31,6 +31,10 @@ export const selectFollowing = createSelector(selectState, (state) => state.foll
|
|||
export const selectIsFetchingSubscriptions = createSelector(selectState, (state) => state.loading);
|
||||
|
||||
export const selectDownloadEnabledByUrl = createSelector(selectState, (state) => state.downloadEnabledByUrl);
|
||||
export const selectLastReleasesByUrl = createSelector(selectState, (state) => state.lastReleaseBySubUrl);
|
||||
export const selectDownloadEnabledUrls = createSelector(selectDownloadEnabledByUrl, (enabledByUrl) =>
|
||||
Object.keys(enabledByUrl)
|
||||
);
|
||||
|
||||
// The current view mode on the subscriptions page
|
||||
export const selectViewMode = createSelector(selectState, (state) => state.viewMode);
|
||||
|
@ -149,7 +153,6 @@ export const makeSelectNotificationsDisabled = (uri) =>
|
|||
const disabled = following.some((sub) => {
|
||||
return sub.uri === uri && sub.notificationsDisabled === true;
|
||||
});
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
|
@ -161,3 +164,8 @@ export const makeSelectDownloadEnabled = (uri) =>
|
|||
createSelector(selectDownloadEnabledByUrl, (downloadEnabledByUrl) => {
|
||||
return downloadEnabledByUrl[uri] || false;
|
||||
});
|
||||
|
||||
export const makeSelectLastReleaseForUri = (uri) =>
|
||||
createSelector(selectLastReleasesByUrl, (last) => {
|
||||
return last[uri] || Math.floor(Date.now() / 1000) - 604800; // fall back to a week ago
|
||||
});
|
||||
|
|
66
ui/util/notifications.js
Normal file
66
ui/util/notifications.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
export const getNotificationFromClaim = (claim) => {
|
||||
// create a notification object from claim
|
||||
const claimName = claim.name;
|
||||
const claimTitle = claim.title;
|
||||
|
||||
const signingChannel = claim.signing_channel;
|
||||
const channelUrl = signingChannel && signingChannel.permanent_url;
|
||||
const claimThumbnail = claim.value.thumbnail;
|
||||
const channelThumbnail = signingChannel.value.thumbnail;
|
||||
|
||||
const dynamic = {};
|
||||
dynamic.claim_name = claimName;
|
||||
dynamic.channel_url = channelUrl;
|
||||
dynamic.claim_title = claimTitle;
|
||||
dynamic.claim_thumbnail = claimThumbnail;
|
||||
dynamic.channel_thumbnail = channelThumbnail;
|
||||
|
||||
const target = `lbry://${claimName}#${claim.claim_id}`;
|
||||
const device = { target };
|
||||
|
||||
const notificationParams = {};
|
||||
notificationParams.dynamic = dynamic;
|
||||
notificationParams.device = device;
|
||||
|
||||
const timestamp = new Date().toISOString();
|
||||
const notification = {};
|
||||
notification.notification_rule = 'new_content';
|
||||
notification.notification_params = notificationParams;
|
||||
notification.is_seen = false;
|
||||
notification.is_read = false;
|
||||
notification.active_at = timestamp;
|
||||
notification.created_at = timestamp;
|
||||
notification.updated_at = timestamp;
|
||||
notification.id = claim.claim_id;
|
||||
|
||||
return notification;
|
||||
};
|
||||
|
||||
/*
|
||||
id(pin):1063634811
|
||||
user_id(pin):1006101
|
||||
type(pin):"new_content"
|
||||
notification_rule(pin):"new_content"
|
||||
is_app_readable(pin):true
|
||||
is_read(pin):false
|
||||
is_emailed(pin):true
|
||||
is_device_notified(pin):true
|
||||
active_at(pin):"2022-05-07T21:47:28Z"
|
||||
created_at(pin):"2022-05-07T21:47:28Z"
|
||||
updated_at(pin):"2022-05-07T21:48:41Z"
|
||||
is_seen(pin):false
|
||||
is_deleted(pin):false
|
||||
dynamic: {
|
||||
claim_name(pin):"macbook-logic-board-repair-livestream-3"
|
||||
channel_url(pin):"lbry://@rossmanngroup#aa5544b6778d3620d57d8dcd3229c6c59354857a"
|
||||
claim_title(pin):"Macbook logic board repair livestream with Louis Rossmann"
|
||||
claim_thumbnail(pin):"https://thumbnails.lbry.com/3zuzWlc8jsg"
|
||||
channel_thumbnail(pin):"https://thumbnails.lbry.com/UCl2mFZoRqjw_ELax4Yisf6w"
|
||||
}
|
||||
|
||||
notification_rule
|
||||
notificatoin_parameters { dynamic: { claim_name:, channel_url:, claim_title:, claim_thumbnail:, channel_thumbnail:, }
|
||||
is_read
|
||||
is_seen
|
||||
|
||||
*/
|
Loading…
Reference in a new issue