Subscribe notify #1066

Merged
liamcardenas merged 9 commits from subscribe-notify into master 2018-03-08 06:13:26 +01:00
5 changed files with 69 additions and 6 deletions
Showing only changes of commit c3dd7f3449 - Show all commits

View file

@ -165,6 +165,9 @@ export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE';
export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE';
export const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS';
export const SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST';
export const CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED';
export const CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED';
export const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE';
// Video controls
export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE';

View file

@ -11,6 +11,7 @@ import { doFetchDaemonSettings } from 'redux/actions/settings';
import { doAuthenticate } from 'redux/actions/user';
import { doBalanceSubscribe } from 'redux/actions/wallet';
import { doPause } from 'redux/actions/media';
import { doCheckSubscriptions } from 'redux/actions/subscriptions';
import {
selectCurrentModal,
@ -298,6 +299,7 @@ export function doDaemonReady() {
dispatch(doCheckUpgradeAvailable());
}
dispatch(doCheckUpgradeSubscribe());
dispatch(doCheckSubscriptions());
};
}

View file

@ -289,7 +289,7 @@ export function doLoadVideo(uri) {
};
}
export function doPurchaseUri(uri) {
export function doPurchaseUri(uri, specificCostInfo) {
return (dispatch, getState) => {
const state = getState();
const balance = selectBalance(state);
@ -322,7 +322,7 @@ export function doPurchaseUri(uri) {
return;
}
const costInfo = makeSelectCostInfoForUri(uri)(state);
const costInfo = makeSelectCostInfoForUri(uri)(state) || specificCostInfo;
const { cost } = costInfo;
if (cost > balance) {
@ -359,8 +359,8 @@ export function doFetchClaimsByChannel(uri, page) {
const claimResult = result[uri] || {};
const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult;
if(claimResult && claimResult.claims_in_channel && claimResult.claims_in_channel.length) {
let latest = claimResult.claims_in_channel[0];
if(claimsInChannel && claimsInChannel.length) {
let latest = claimsInChannel[0];
dispatch(setSubscriptionLatest({
channelName: latest.channel_name,
uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}`

View file

@ -1,6 +1,12 @@
// @flow
import * as ACTIONS from 'constants/action_types';
import type { Subscription, Dispatch } from 'redux/reducers/subscriptions';
import type { Subscription, Dispatch, SubscriptionState } from 'redux/reducers/subscriptions';
import { selectSubscriptions } from 'redux/selectors/subscriptions';
import Lbry from 'lbry';
import { doPurchaseUri } from 'redux/actions/content';
import { doNavigate } from 'redux/actions/navigation';
const CHECK_SUBSCRIPTIONS_INTERVAL = 10 * 60 * 1000;
export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch) =>
dispatch({
@ -14,6 +20,50 @@ export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: D
data: subscription,
neb-b commented 2018-03-06 19:13:27 +01:00 (Migrated from github.com)
Review

Why do you need to pass in the new cost object. Shouldn't doPurchaseUri be able to select that data with the uri?

Why do you need to pass in the new cost object. Shouldn't `doPurchaseUri` be able to select that data with the uri?
kauffj commented 2018-03-06 21:55:55 +01:00 (Migrated from github.com)
Review

Can we wait to show this notification until after content is ready to watch? I.e. after get has successfully started? That way when the user clicks the notification they get something immediately.

Can we wait to show this notification until after content is ready to watch? I.e. after `get` has successfully started? That way when the user clicks the notification they get something immediately.
liamcardenas commented 2018-03-07 20:27:56 +01:00 (Migrated from github.com)
Review

its is more efficient this way because I already have the cost information so we don't need to fetch it again and

its is more efficient this way because I already have the cost information so we don't need to fetch it again and
liamcardenas commented 2018-03-07 20:37:11 +01:00 (Migrated from github.com)
Review

Yes, @seanyesmunt brought this up as well. I have reasons for why I didn't make it this way, which I think we should discuss -- although I think you are right that we probably want to download it first and I probably should have implemented it this way. I will schedule this in the next sprint.

Yes, @seanyesmunt brought this up as well. I have reasons for why I didn't make it this way, which I think we should discuss -- although I think you are right that we probably want to download it first and I probably should have implemented it this way. I will schedule this in the next sprint.
kauffj commented 2018-03-07 22:51:26 +01:00 (Migrated from github.com)
Review

I checked out the code here:

  1. doLoadVideo and doPurchaseUri are confusingly -- almost backwardly -- named. It may make sense to tweak these.
  2. Since you are already checking that the price is free, it seems like you could potentially skip doPurchaseUri and go right to doLoadVideo.
  3. Both doLoadVideo and doPurchaseUri can trigger modal popups. It is weird that asynchronous background loading of content can trigger a modal. Fairly guaranteed that this will cause confusion at some point.
  4. It doesn't seem particularly tricky to attach a notification to the success of the call to get. I think a light modification of doLoadVideo to take a notification or callback would get you there.
I checked out the code here: 1) `doLoadVideo` and `doPurchaseUri` are confusingly -- almost backwardly -- named. It may make sense to tweak these. 2) Since you are already checking that the price is free, it seems like you could potentially skip `doPurchaseUri` and go right to `doLoadVideo`. 3) Both `doLoadVideo` and `doPurchaseUri` can trigger modal popups. It is weird that asynchronous background loading of content can trigger a modal. Fairly guaranteed that this will cause confusion at some point. 4) It doesn't seem particularly tricky to attach a notification to the success of the call to `get`. I think a light modification of `doLoadVideo` to take a notification or callback would get you there.
});
export const doCheckSubscriptions = () => (dispatch: Dispatch, getState: () => SubscriptionState) => {
const checkSubscriptionsTimer = setInterval(
() => selectSubscriptions(getState()).map((subscription: Subscription) => dispatch(doCheckSubscription(subscription))),
CHECK_SUBSCRIPTIONS_INTERVAL
);
dispatch({
type: ACTIONS.CHECK_SUBSCRIPTIONS_SUBSCRIBE,
data: { checkSubscriptionsTimer },
});
};
export const doCheckSubscription = (subscription: Subscription) => (dispatch: Dispatch) => {
dispatch({
type: ACTIONS.CHECK_SUBSCRIPTION_STARTED,
data: subscription,
});
Lbry.claim_list_by_channel({ uri: subscription.uri, page: 1 }).then(result => {
const claimResult = result[subscription.uri] || {};
const { claims_in_channel: claimsInChannel } = claimResult;
let count = claimsInChannel.reduce((prev, cur, index) => `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, -1)
if(count !== 0) {
if(!claimsInChannel[0].value.stream.metadata.fee) {
dispatch(doPurchaseUri(`${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, {cost: 0}));
}
const notif = new window.Notification(subscription.channelName, {
body: `Posted ${claimsInChannel[0].value.stream.metadata.title}${count > 1 ? ` and ${count-1} other new items` : '' }${count < 0 ? ' and 9+ other new items' : ''}`,
silent: false,
});
notif.onclick = () => {
dispatch(doNavigate('/show', { uri: `lbry://${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` }))
};
}
dispatch({
type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED,
data: subscription
});
});
}
export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) =>
{
return dispatch({

View file

@ -37,7 +37,15 @@ type setSubscriptionLatest = {
}
}
export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest;
type CheckSubscriptionStarted = {
type: ACTIONS.CHECK_SUBSCRIPTION_STARTED
}
type CheckSubscriptionCompleted = {
type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED
}
export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest | CheckSubscriptionStarted | CheckSubscriptionCompleted | Function;
export type Dispatch = (action: Action) => any;
const defaultState = {