2019-04-03 23:34:07 +02:00
'use strict' ;
Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
function _interopDefault ( ex ) { return ( ex && ( typeof ex === 'object' ) && 'default' in ex ) ? ex [ 'default' ] : ex ; }
var lbryRedux = require ( 'lbry-redux' ) ;
var querystring = _interopDefault ( require ( 'querystring' ) ) ;
var reselect = require ( 'reselect' ) ;
// Auth Token
const GENERATE _AUTH _TOKEN _FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE' ;
const GENERATE _AUTH _TOKEN _STARTED = 'GENERATE_AUTH_TOKEN_STARTED' ;
const GENERATE _AUTH _TOKEN _SUCCESS = 'GENERATE_AUTH_TOKEN_SUCCESS' ; // Claims
const FETCH _FEATURED _CONTENT _STARTED = 'FETCH_FEATURED_CONTENT_STARTED' ;
const FETCH _FEATURED _CONTENT _COMPLETED = 'FETCH_FEATURED_CONTENT_COMPLETED' ;
const FETCH _TRENDING _CONTENT _STARTED = 'FETCH_TRENDING_CONTENT_STARTED' ;
const FETCH _TRENDING _CONTENT _COMPLETED = 'FETCH_TRENDING_CONTENT_COMPLETED' ;
const RESOLVE _URIS _STARTED = 'RESOLVE_URIS_STARTED' ;
const RESOLVE _URIS _COMPLETED = 'RESOLVE_URIS_COMPLETED' ;
const FETCH _CHANNEL _CLAIMS _STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED' ;
const FETCH _CHANNEL _CLAIMS _COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED' ;
const FETCH _CHANNEL _CLAIM _COUNT _STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED' ;
const FETCH _CHANNEL _CLAIM _COUNT _COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED' ;
const FETCH _CLAIM _LIST _MINE _STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED' ;
const FETCH _CLAIM _LIST _MINE _COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED' ;
const ABANDON _CLAIM _STARTED = 'ABANDON_CLAIM_STARTED' ;
const ABANDON _CLAIM _SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED' ;
const FETCH _CHANNEL _LIST _STARTED = 'FETCH_CHANNEL_LIST_STARTED' ;
const FETCH _CHANNEL _LIST _COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED' ;
const CREATE _CHANNEL _STARTED = 'CREATE_CHANNEL_STARTED' ;
const CREATE _CHANNEL _COMPLETED = 'CREATE_CHANNEL_COMPLETED' ;
const PUBLISH _STARTED = 'PUBLISH_STARTED' ;
const PUBLISH _COMPLETED = 'PUBLISH_COMPLETED' ;
const PUBLISH _FAILED = 'PUBLISH_FAILED' ;
const SET _PLAYING _URI = 'SET_PLAYING_URI' ;
const SET _CONTENT _POSITION = 'SET_CONTENT_POSITION' ;
const SET _CONTENT _LAST _VIEWED = 'SET_CONTENT_LAST_VIEWED' ;
const CLEAR _CONTENT _HISTORY _URI = 'CLEAR_CONTENT_HISTORY_URI' ;
const CLEAR _CONTENT _HISTORY _ALL = 'CLEAR_CONTENT_HISTORY_ALL' ; // Subscriptions
const CHANNEL _SUBSCRIBE = 'CHANNEL_SUBSCRIBE' ;
const CHANNEL _UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE' ;
const CHANNEL _SUBSCRIPTION _ENABLE _NOTIFICATIONS = 'CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS' ;
const CHANNEL _SUBSCRIPTION _DISABLE _NOTIFICATIONS = 'CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS' ;
const HAS _FETCHED _SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS' ;
const SET _SUBSCRIPTION _LATEST = 'SET_SUBSCRIPTION_LATEST' ;
const UPDATE _SUBSCRIPTION _UNREADS = 'UPDATE_SUBSCRIPTION_UNREADS' ;
const REMOVE _SUBSCRIPTION _UNREADS = 'REMOVE_SUBSCRIPTION_UNREADS' ;
const CHECK _SUBSCRIPTION _STARTED = 'CHECK_SUBSCRIPTION_STARTED' ;
const CHECK _SUBSCRIPTION _COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED' ;
const CHECK _SUBSCRIPTIONS _SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE' ;
const FETCH _SUBSCRIPTIONS _START = 'FETCH_SUBSCRIPTIONS_START' ;
const FETCH _SUBSCRIPTIONS _FAIL = 'FETCH_SUBSCRIPTIONS_FAIL' ;
const FETCH _SUBSCRIPTIONS _SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS' ;
const SET _VIEW _MODE = 'SET_VIEW_MODE' ;
const GET _SUGGESTED _SUBSCRIPTIONS _START = 'GET_SUGGESTED_SUBSCRIPTIONS_START' ;
const GET _SUGGESTED _SUBSCRIPTIONS _SUCCESS = 'GET_SUGGESTED_SUBSCRIPTIONS_SUCCESS' ;
const GET _SUGGESTED _SUBSCRIPTIONS _FAIL = 'GET_SUGGESTED_SUBSCRIPTIONS_FAIL' ;
const SUBSCRIPTION _FIRST _RUN _COMPLETED = 'SUBSCRIPTION_FIRST_RUN_COMPLETED' ;
const VIEW _SUGGESTED _SUBSCRIPTIONS = 'VIEW_SUGGESTED_SUBSCRIPTIONS' ; // Blacklist
const FETCH _BLACK _LISTED _CONTENT _STARTED = 'FETCH_BLACK_LISTED_CONTENT_STARTED' ;
const FETCH _BLACK _LISTED _CONTENT _COMPLETED = 'FETCH_BLACK_LISTED_CONTENT_COMPLETED' ;
const FETCH _BLACK _LISTED _CONTENT _FAILED = 'FETCH_BLACK_LISTED_CONTENT_FAILED' ;
2019-07-09 16:20:01 +02:00
const BLACK _LISTED _CONTENT _SUBSCRIBE = 'BLACK_LISTED_CONTENT_SUBSCRIBE' ; // Filtered list
const FETCH _FILTERED _CONTENT _STARTED = 'FETCH_FILTERED_CONTENT_STARTED' ;
const FETCH _FILTERED _CONTENT _COMPLETED = 'FETCH_FILTERED_CONTENT_COMPLETED' ;
const FETCH _FILTERED _CONTENT _FAILED = 'FETCH_FILTERED_CONTENT_FAILED' ;
const FILTERED _CONTENT _SUBSCRIBE = 'FILTERED_CONTENT_SUBSCRIBE' ; // Cost Info
2019-04-03 23:34:07 +02:00
const FETCH _COST _INFO _STARTED = 'FETCH_COST_INFO_STARTED' ;
const FETCH _COST _INFO _COMPLETED = 'FETCH_COST_INFO_COMPLETED' ; // File Stats
const FETCH _VIEW _COUNT _STARTED = 'FETCH_VIEW_COUNT_STARTED' ;
const FETCH _VIEW _COUNT _FAILED = 'FETCH_VIEW_COUNT_FAILED' ;
2019-04-18 10:02:11 +02:00
const FETCH _VIEW _COUNT _COMPLETED = 'FETCH_VIEW_COUNT_COMPLETED' ; // Cross-device Sync
const GET _SYNC _STARTED = 'GET_SYNC_STARTED' ;
const GET _SYNC _COMPLETED = 'GET_SYNC_COMPLETED' ;
const SET _SYNC _STARTED = 'SET_SYNC_STARTED' ;
const SET _SYNC _FAILED = 'SET_SYNC_FAILED' ;
const SET _SYNC _COMPLETED = 'SET_SYNC_COMPLETED' ;
2019-05-10 16:45:56 +02:00
const SET _DEFAULT _ACCOUNT = 'SET_DEFAULT_ACCOUNT' ;
2019-05-27 15:57:31 +02:00
const SYNC _APPLY _STARTED = 'SYNC_APPLY_STARTED' ;
const SYNC _APPLY _COMPLETED = 'SYNC_APPLY_COMPLETED' ;
2019-09-16 22:12:43 +02:00
const SYNC _APPLY _FAILED = 'SYNC_APPLY_FAILED' ;
2019-04-03 23:34:07 +02:00
var action _types = /*#__PURE__*/ Object . freeze ( {
GENERATE _AUTH _TOKEN _FAILURE : GENERATE _AUTH _TOKEN _FAILURE ,
GENERATE _AUTH _TOKEN _STARTED : GENERATE _AUTH _TOKEN _STARTED ,
GENERATE _AUTH _TOKEN _SUCCESS : GENERATE _AUTH _TOKEN _SUCCESS ,
FETCH _FEATURED _CONTENT _STARTED : FETCH _FEATURED _CONTENT _STARTED ,
FETCH _FEATURED _CONTENT _COMPLETED : FETCH _FEATURED _CONTENT _COMPLETED ,
FETCH _TRENDING _CONTENT _STARTED : FETCH _TRENDING _CONTENT _STARTED ,
FETCH _TRENDING _CONTENT _COMPLETED : FETCH _TRENDING _CONTENT _COMPLETED ,
RESOLVE _URIS _STARTED : RESOLVE _URIS _STARTED ,
RESOLVE _URIS _COMPLETED : RESOLVE _URIS _COMPLETED ,
FETCH _CHANNEL _CLAIMS _STARTED : FETCH _CHANNEL _CLAIMS _STARTED ,
FETCH _CHANNEL _CLAIMS _COMPLETED : FETCH _CHANNEL _CLAIMS _COMPLETED ,
FETCH _CHANNEL _CLAIM _COUNT _STARTED : FETCH _CHANNEL _CLAIM _COUNT _STARTED ,
FETCH _CHANNEL _CLAIM _COUNT _COMPLETED : FETCH _CHANNEL _CLAIM _COUNT _COMPLETED ,
FETCH _CLAIM _LIST _MINE _STARTED : FETCH _CLAIM _LIST _MINE _STARTED ,
FETCH _CLAIM _LIST _MINE _COMPLETED : FETCH _CLAIM _LIST _MINE _COMPLETED ,
ABANDON _CLAIM _STARTED : ABANDON _CLAIM _STARTED ,
ABANDON _CLAIM _SUCCEEDED : ABANDON _CLAIM _SUCCEEDED ,
FETCH _CHANNEL _LIST _STARTED : FETCH _CHANNEL _LIST _STARTED ,
FETCH _CHANNEL _LIST _COMPLETED : FETCH _CHANNEL _LIST _COMPLETED ,
CREATE _CHANNEL _STARTED : CREATE _CHANNEL _STARTED ,
CREATE _CHANNEL _COMPLETED : CREATE _CHANNEL _COMPLETED ,
PUBLISH _STARTED : PUBLISH _STARTED ,
PUBLISH _COMPLETED : PUBLISH _COMPLETED ,
PUBLISH _FAILED : PUBLISH _FAILED ,
SET _PLAYING _URI : SET _PLAYING _URI ,
SET _CONTENT _POSITION : SET _CONTENT _POSITION ,
SET _CONTENT _LAST _VIEWED : SET _CONTENT _LAST _VIEWED ,
CLEAR _CONTENT _HISTORY _URI : CLEAR _CONTENT _HISTORY _URI ,
CLEAR _CONTENT _HISTORY _ALL : CLEAR _CONTENT _HISTORY _ALL ,
CHANNEL _SUBSCRIBE : CHANNEL _SUBSCRIBE ,
CHANNEL _UNSUBSCRIBE : CHANNEL _UNSUBSCRIBE ,
CHANNEL _SUBSCRIPTION _ENABLE _NOTIFICATIONS : CHANNEL _SUBSCRIPTION _ENABLE _NOTIFICATIONS ,
CHANNEL _SUBSCRIPTION _DISABLE _NOTIFICATIONS : CHANNEL _SUBSCRIPTION _DISABLE _NOTIFICATIONS ,
HAS _FETCHED _SUBSCRIPTIONS : HAS _FETCHED _SUBSCRIPTIONS ,
SET _SUBSCRIPTION _LATEST : SET _SUBSCRIPTION _LATEST ,
UPDATE _SUBSCRIPTION _UNREADS : UPDATE _SUBSCRIPTION _UNREADS ,
REMOVE _SUBSCRIPTION _UNREADS : REMOVE _SUBSCRIPTION _UNREADS ,
CHECK _SUBSCRIPTION _STARTED : CHECK _SUBSCRIPTION _STARTED ,
CHECK _SUBSCRIPTION _COMPLETED : CHECK _SUBSCRIPTION _COMPLETED ,
CHECK _SUBSCRIPTIONS _SUBSCRIBE : CHECK _SUBSCRIPTIONS _SUBSCRIBE ,
FETCH _SUBSCRIPTIONS _START : FETCH _SUBSCRIPTIONS _START ,
FETCH _SUBSCRIPTIONS _FAIL : FETCH _SUBSCRIPTIONS _FAIL ,
FETCH _SUBSCRIPTIONS _SUCCESS : FETCH _SUBSCRIPTIONS _SUCCESS ,
SET _VIEW _MODE : SET _VIEW _MODE ,
GET _SUGGESTED _SUBSCRIPTIONS _START : GET _SUGGESTED _SUBSCRIPTIONS _START ,
GET _SUGGESTED _SUBSCRIPTIONS _SUCCESS : GET _SUGGESTED _SUBSCRIPTIONS _SUCCESS ,
GET _SUGGESTED _SUBSCRIPTIONS _FAIL : GET _SUGGESTED _SUBSCRIPTIONS _FAIL ,
SUBSCRIPTION _FIRST _RUN _COMPLETED : SUBSCRIPTION _FIRST _RUN _COMPLETED ,
VIEW _SUGGESTED _SUBSCRIPTIONS : VIEW _SUGGESTED _SUBSCRIPTIONS ,
FETCH _BLACK _LISTED _CONTENT _STARTED : FETCH _BLACK _LISTED _CONTENT _STARTED ,
FETCH _BLACK _LISTED _CONTENT _COMPLETED : FETCH _BLACK _LISTED _CONTENT _COMPLETED ,
FETCH _BLACK _LISTED _CONTENT _FAILED : FETCH _BLACK _LISTED _CONTENT _FAILED ,
BLACK _LISTED _CONTENT _SUBSCRIBE : BLACK _LISTED _CONTENT _SUBSCRIBE ,
2019-07-09 16:20:01 +02:00
FETCH _FILTERED _CONTENT _STARTED : FETCH _FILTERED _CONTENT _STARTED ,
FETCH _FILTERED _CONTENT _COMPLETED : FETCH _FILTERED _CONTENT _COMPLETED ,
FETCH _FILTERED _CONTENT _FAILED : FETCH _FILTERED _CONTENT _FAILED ,
FILTERED _CONTENT _SUBSCRIBE : FILTERED _CONTENT _SUBSCRIBE ,
2019-04-03 23:34:07 +02:00
FETCH _COST _INFO _STARTED : FETCH _COST _INFO _STARTED ,
FETCH _COST _INFO _COMPLETED : FETCH _COST _INFO _COMPLETED ,
FETCH _VIEW _COUNT _STARTED : FETCH _VIEW _COUNT _STARTED ,
FETCH _VIEW _COUNT _FAILED : FETCH _VIEW _COUNT _FAILED ,
2019-04-18 10:02:11 +02:00
FETCH _VIEW _COUNT _COMPLETED : FETCH _VIEW _COUNT _COMPLETED ,
GET _SYNC _STARTED : GET _SYNC _STARTED ,
GET _SYNC _COMPLETED : GET _SYNC _COMPLETED ,
SET _SYNC _STARTED : SET _SYNC _STARTED ,
SET _SYNC _FAILED : SET _SYNC _FAILED ,
2019-05-10 16:45:56 +02:00
SET _SYNC _COMPLETED : SET _SYNC _COMPLETED ,
2019-05-27 15:57:31 +02:00
SET _DEFAULT _ACCOUNT : SET _DEFAULT _ACCOUNT ,
SYNC _APPLY _STARTED : SYNC _APPLY _STARTED ,
SYNC _APPLY _COMPLETED : SYNC _APPLY _COMPLETED ,
2019-09-16 22:12:43 +02:00
SYNC _APPLY _FAILED : SYNC _APPLY _FAILED
2019-04-03 23:34:07 +02:00
} ) ;
const Lbryio = {
enabled : true ,
authenticationPromise : null ,
exchangePromise : null ,
exchangeLastFetched : null ,
CONNECTION _STRING : 'https://api.lbry.com/'
} ;
const EXCHANGE _RATE _TIMEOUT = 20 * 60 * 1000 ; // We can't use env's because they aren't passed into node_modules
Lbryio . setLocalApi = endpoint => {
Lbryio . CONNECTION _STRING = endpoint . replace ( /\/*$/ , '/' ) ; // exactly one slash at the end;
} ;
Lbryio . call = ( resource , action , params = { } , method = 'get' ) => {
if ( ! Lbryio . enabled ) {
return Promise . reject ( new Error ( _ _ ( 'LBRY internal API is disabled' ) ) ) ;
}
if ( ! ( method === 'get' || method === 'post' ) ) {
return Promise . reject ( new Error ( _ _ ( 'Invalid method' ) ) ) ;
}
function checkAndParse ( response ) {
if ( response . status >= 200 && response . status < 300 ) {
return response . json ( ) ;
}
return response . json ( ) . then ( json => {
let error ;
if ( json . error ) {
error = new Error ( json . error ) ;
} else {
error = new Error ( 'Unknown API error signature' ) ;
}
error . response = response ; // This is primarily a hack used in actions/user.js
return Promise . reject ( error ) ;
} ) ;
}
function makeRequest ( url , options ) {
return fetch ( url , options ) . then ( checkAndParse ) ;
}
return Lbryio . getAuthToken ( ) . then ( token => {
const fullParams = {
auth _token : token ,
... params
} ;
2019-09-13 16:38:40 +02:00
Object . keys ( fullParams ) . forEach ( key => {
const value = fullParams [ key ] ;
if ( typeof value === 'object' ) {
fullParams [ key ] = JSON . stringify ( value ) ;
}
} ) ;
2019-04-03 23:34:07 +02:00
const qs = querystring . stringify ( fullParams ) ;
let url = ` ${ Lbryio . CONNECTION _STRING } ${ resource } / ${ action } ? ${ qs } ` ;
let options = {
method : 'GET'
} ;
if ( method === 'post' ) {
options = {
method : 'POST' ,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
} ,
body : qs
} ;
url = ` ${ Lbryio . CONNECTION _STRING } ${ resource } / ${ action } ` ;
}
return makeRequest ( url , options ) . then ( response => response . data ) ;
} ) ;
} ;
Lbryio . authToken = null ;
Lbryio . getAuthToken = ( ) => new Promise ( resolve => {
if ( Lbryio . authToken ) {
resolve ( Lbryio . authToken ) ;
} else if ( Lbryio . overrides . getAuthToken ) {
Lbryio . overrides . getAuthToken ( ) . then ( token => {
resolve ( token ) ;
} ) ;
} else {
const {
store
} = window ;
if ( store ) {
const state = store . getState ( ) ;
const token = state . auth ? state . auth . authToken : null ;
Lbryio . authToken = token ;
resolve ( token ) ;
}
resolve ( null ) ;
}
} ) ;
Lbryio . getCurrentUser = ( ) => Lbryio . call ( 'user' , 'me' ) ;
Lbryio . authenticate = ( ) => {
if ( ! Lbryio . enabled ) {
return new Promise ( resolve => {
resolve ( {
id : 1 ,
language : 'en' ,
primary _email : 'disabled@lbry.io' ,
has _verified _email : true ,
is _identity _verified : true ,
is _reward _approved : false
} ) ;
} ) ;
}
if ( Lbryio . authenticationPromise === null ) {
Lbryio . authenticationPromise = new Promise ( ( resolve , reject ) => {
Lbryio . getAuthToken ( ) . then ( token => {
if ( ! token || token . length > 60 ) {
return false ;
} // check that token works
return Lbryio . getCurrentUser ( ) . then ( user => user ) . catch ( ( ) => false ) ;
} ) . then ( user => {
if ( user ) {
return user ;
}
return lbryRedux . Lbry . status ( ) . then ( status => {
if ( Lbryio . overrides . setAuthToken ) {
return Lbryio . overrides . setAuthToken ( status ) ;
} // simply call the logic to create a new user, and obtain the auth token
return new Promise ( ( res , rej ) => {
Lbryio . call ( 'user' , 'new' , {
auth _token : '' ,
language : 'en' ,
app _id : status . installation _id
} , 'post' ) . then ( response => {
if ( ! response . auth _token ) {
throw new Error ( 'auth_token was not set in the response' ) ;
}
const {
store
} = window ;
if ( store ) {
store . dispatch ( {
type : GENERATE _AUTH _TOKEN _SUCCESS ,
data : {
authToken : response . auth _token
}
} ) ;
}
Lbryio . authToken = response . auth _token ;
res ( response ) ;
2019-04-18 10:02:11 +02:00
} ) . catch ( error => rej ( error ) ) ;
2019-04-03 23:34:07 +02:00
} ) ;
} ) ;
} ) . then ( user => {
if ( ! user ) {
return Lbryio . getCurrentUser ( ) ;
}
return user ;
} ) . then ( resolve , reject ) ;
} ) ;
}
return Lbryio . authenticationPromise ;
} ;
Lbryio . getStripeToken = ( ) => Lbryio . CONNECTION _STRING . startsWith ( 'http://localhost:' ) ? 'pk_test_NoL1JWL7i1ipfhVId5KfDZgo' : 'pk_live_e8M4dRNnCCbmpZzduEUZBgJO' ;
Lbryio . getExchangeRates = ( ) => {
if ( ! Lbryio . exchangeLastFetched || Date . now ( ) - Lbryio . exchangeLastFetched > EXCHANGE _RATE _TIMEOUT ) {
Lbryio . exchangePromise = new Promise ( ( resolve , reject ) => {
Lbryio . call ( 'lbc' , 'exchange_rate' , { } , 'get' , true ) . then ( ( {
lbc _usd : LBC _USD ,
lbc _btc : LBC _BTC ,
btc _usd : BTC _USD
} ) => {
const rates = {
LBC _USD ,
LBC _BTC ,
BTC _USD
} ;
resolve ( rates ) ;
} ) . catch ( reject ) ;
} ) ;
Lbryio . exchangeLastFetched = Date . now ( ) ;
}
return Lbryio . exchangePromise ;
} ; // Allow overriding lbryio methods
// The desktop app will need to use it for getAuthToken because we use electron's ipcRenderer
Lbryio . overrides = { } ;
Lbryio . setOverride = ( methodName , newMethod ) => {
Lbryio . overrides [ methodName ] = newMethod ;
} ;
const rewards = { } ;
rewards . TYPE _NEW _DEVELOPER = 'new_developer' ;
rewards . TYPE _NEW _USER = 'new_user' ;
2019-09-13 16:38:40 +02:00
rewards . TYPE _CONFIRM _EMAIL = 'email_provided' ;
2019-04-03 23:34:07 +02:00
rewards . TYPE _FIRST _CHANNEL = 'new_channel' ;
rewards . TYPE _FIRST _STREAM = 'first_stream' ;
rewards . TYPE _MANY _DOWNLOADS = 'many_downloads' ;
rewards . TYPE _FIRST _PUBLISH = 'first_publish' ;
rewards . TYPE _FEATURED _DOWNLOAD = 'featured_download' ;
rewards . TYPE _REFERRAL = 'referral' ;
rewards . TYPE _REWARD _CODE = 'reward_code' ;
rewards . TYPE _SUBSCRIPTION = 'subscription' ;
rewards . YOUTUBE _CREATOR = 'youtube_creator' ;
2019-09-04 17:48:31 +02:00
rewards . TYPE _DAILY _VIEW = 'daily_view' ;
2019-04-03 23:34:07 +02:00
rewards . claimReward = ( type , rewardParams ) => {
function requestReward ( resolve , reject , params ) {
if ( ! Lbryio . enabled ) {
reject ( new Error ( _ _ ( 'Rewards are not enabled.' ) ) ) ;
return ;
}
Lbryio . call ( 'reward' , 'new' , params , 'post' ) . then ( reward => {
const message = reward . reward _notification || ` You have claimed a ${ reward . reward _amount } LBC reward. ` ; // Display global notice
const action = lbryRedux . doToast ( {
message ,
linkText : _ _ ( 'Show All' ) ,
linkTarget : '/rewards'
} ) ;
window . store . dispatch ( action ) ;
if ( rewards . callbacks . claimRewardSuccess ) {
rewards . callbacks . claimRewardSuccess ( ) ;
}
resolve ( reward ) ;
} , reject ) ;
}
return new Promise ( ( resolve , reject ) => {
lbryRedux . Lbry . address _unused ( ) . then ( address => {
const params = {
reward _type : type ,
wallet _address : address ,
... rewardParams
} ;
switch ( type ) {
case rewards . TYPE _FIRST _CHANNEL :
2019-05-07 20:30:06 +02:00
lbryRedux . Lbry . claim _list ( ) . then ( claims => {
2019-04-03 23:34:07 +02:00
const claim = claims . find ( foundClaim => foundClaim . name . length && foundClaim . name [ 0 ] === '@' && foundClaim . txid . length && foundClaim . type === 'claim' ) ;
if ( claim ) {
params . transaction _id = claim . txid ;
requestReward ( resolve , reject , params ) ;
} else {
reject ( new Error ( _ _ ( 'Please create a channel identity first.' ) ) ) ;
}
} ) . catch ( reject ) ;
break ;
case rewards . TYPE _FIRST _PUBLISH :
2019-05-07 20:30:06 +02:00
lbryRedux . Lbry . claim _list ( ) . then ( claims => {
2019-04-03 23:34:07 +02:00
const claim = claims . find ( foundClaim => foundClaim . name . length && foundClaim . name [ 0 ] !== '@' && foundClaim . txid . length && foundClaim . type === 'claim' ) ;
if ( claim ) {
params . transaction _id = claim . txid ;
requestReward ( resolve , reject , params ) ;
} else {
reject ( claims . length ? new Error ( _ _ ( 'Please publish something and wait for confirmation by the network to claim this reward.' ) ) : new Error ( _ _ ( 'Please publish something to claim this reward.' ) ) ) ;
}
} ) . catch ( reject ) ;
break ;
case rewards . TYPE _FIRST _STREAM :
case rewards . TYPE _NEW _USER :
default :
requestReward ( resolve , reject , params ) ;
}
} ) ;
} ) ;
} ;
rewards . callbacks = {
// Set any callbacks that require code not found in this project
claimRewardSuccess : null ,
claimFirstRewardSuccess : null ,
rewardApprovalRequired : null
} ;
rewards . setCallback = ( name , method ) => {
rewards . callbacks [ name ] = method ;
} ;
const VIEW _ALL = 'view_all' ;
const DOWNLOADING = 'DOWNLOADING' ;
const NOTIFY _ONLY = 'NOTIFY_ONLY;' ; // Suggested types
const SUGGESTED _TOP _SUBSCRIBED = 'top_subscribed' ;
const SUGGESTED _FEATURED = 'featured' ;
// util for creating reducers
// based off of redux-actions
// https://redux-actions.js.org/docs/api/handleAction.html#handleactions
// eslint-disable-next-line import/prefer-default-export
const handleActions = ( actionMap , defaultState ) => ( state = defaultState , action ) => {
const handler = actionMap [ action . type ] ;
if ( handler ) {
const newState = handler ( state , action ) ;
return Object . assign ( { } , state , newState ) ;
} // just return the original state if no handler
// returning a copy here breaks redux-persist
return state ;
} ;
//
const defaultState = {
enabledChannelNotifications : [ ] ,
subscriptions : [ ] ,
unread : { } ,
suggested : { } ,
loading : false ,
viewMode : VIEW _ALL ,
loadingSuggested : false ,
firstRunCompleted : false ,
showSuggestedSubs : false
} ;
var subscriptions = handleActions ( {
[ CHANNEL _SUBSCRIBE ] : ( state , action ) => {
const newSubscription = action . data ;
const newSubscriptions = state . subscriptions . slice ( ) ;
newSubscriptions . unshift ( newSubscription ) ;
return { ... state ,
subscriptions : newSubscriptions
} ;
} ,
[ CHANNEL _UNSUBSCRIBE ] : ( state , action ) => {
const subscriptionToRemove = action . data ;
const newSubscriptions = state . subscriptions . slice ( ) . filter ( subscription => subscription . channelName !== subscriptionToRemove . channelName ) ; // Check if we need to remove it from the 'unread' state
const {
unread
} = state ;
if ( unread [ subscriptionToRemove . uri ] ) {
delete unread [ subscriptionToRemove . uri ] ;
}
return { ... state ,
unread : { ... unread
} ,
subscriptions : newSubscriptions
} ;
} ,
[ SET _SUBSCRIPTION _LATEST ] : ( state , action ) => ( { ... state ,
subscriptions : state . subscriptions . map ( subscription => subscription . channelName === action . data . subscription . channelName ? { ... subscription ,
latest : action . data . uri
} : subscription )
} ) ,
[ UPDATE _SUBSCRIPTION _UNREADS ] : ( state , action ) => {
const {
channel ,
uris ,
type
} = action . data ;
return { ... state ,
unread : { ... state . unread ,
[ channel ] : {
uris ,
type
}
}
} ;
} ,
[ REMOVE _SUBSCRIPTION _UNREADS ] : ( state , action ) => {
const {
channel ,
uris
} = action . data ; // If no channel is passed in, remove all unreads
let newUnread ;
if ( channel ) {
newUnread = { ... state . unread
} ;
if ( ! uris ) {
delete newUnread [ channel ] ;
} else {
newUnread [ channel ] . uris = uris ;
}
} else {
newUnread = { } ;
}
return { ... state ,
unread : { ... newUnread
}
} ;
} ,
[ CHANNEL _SUBSCRIPTION _ENABLE _NOTIFICATIONS ] : ( state , action ) => {
const channelName = action . data ;
const newEnabledChannelNotifications = state . enabledChannelNotifications . slice ( ) ;
if ( channelName && channelName . trim ( ) . length > 0 && newEnabledChannelNotifications . indexOf ( channelName ) === - 1 ) {
newEnabledChannelNotifications . push ( channelName ) ;
}
return { ... state ,
enabledChannelNotifications : newEnabledChannelNotifications
} ;
} ,
[ CHANNEL _SUBSCRIPTION _DISABLE _NOTIFICATIONS ] : ( state , action ) => {
const channelName = action . data ;
const newEnabledChannelNotifications = state . enabledChannelNotifications . slice ( ) ;
const index = newEnabledChannelNotifications . indexOf ( channelName ) ;
if ( index > - 1 ) {
newEnabledChannelNotifications . splice ( index , 1 ) ;
}
return { ... state ,
enabledChannelNotifications : newEnabledChannelNotifications
} ;
} ,
[ FETCH _SUBSCRIPTIONS _START ] : state => ( { ... state ,
loading : true
} ) ,
[ FETCH _SUBSCRIPTIONS _FAIL ] : state => ( { ... state ,
loading : false
} ) ,
[ FETCH _SUBSCRIPTIONS _SUCCESS ] : ( state , action ) => ( { ... state ,
loading : false ,
subscriptions : action . data
} ) ,
[ SET _VIEW _MODE ] : ( state , action ) => ( { ... state ,
viewMode : action . data
} ) ,
[ GET _SUGGESTED _SUBSCRIPTIONS _START ] : state => ( { ... state ,
loadingSuggested : true
} ) ,
[ GET _SUGGESTED _SUBSCRIPTIONS _SUCCESS ] : ( state , action ) => ( { ... state ,
suggested : action . data ,
loadingSuggested : false
} ) ,
[ GET _SUGGESTED _SUBSCRIPTIONS _FAIL ] : state => ( { ... state ,
loadingSuggested : false
} ) ,
[ SUBSCRIPTION _FIRST _RUN _COMPLETED ] : state => ( { ... state ,
firstRunCompleted : true
} ) ,
[ VIEW _SUGGESTED _SUBSCRIPTIONS ] : state => ( { ... state ,
showSuggestedSubs : true
} )
} , defaultState ) ;
2019-09-16 22:12:43 +02:00
function swapKeyAndValue ( dict ) {
const ret = { } ; // eslint-disable-next-line no-restricted-syntax
for ( const key in dict ) {
if ( dict . hasOwnProperty ( key ) ) {
ret [ dict [ key ] ] = key ;
}
}
return ret ;
}
const selectState = state => state . subscriptions || { } ; // Returns the list of channel uris a user is subscribed to
const selectSubscriptions = reselect . createSelector ( selectState , state => state . subscriptions ) ; // Fetching list of users subscriptions
const selectIsFetchingSubscriptions = reselect . createSelector ( selectState , state => state . loading ) ; // The current view mode on the subscriptions page
const selectViewMode = reselect . createSelector ( selectState , state => state . viewMode ) ; // Suggested subscriptions from internal apis
const selectSuggested = reselect . createSelector ( selectState , state => state . suggested ) ;
const selectIsFetchingSuggested = reselect . createSelector ( selectState , state => state . loadingSuggested ) ;
const selectSuggestedChannels = reselect . 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 => {
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 => ( {
uri ,
label : suggestedChannels [ uri ]
} ) ) . slice ( 0 , 5 ) ;
} ) ;
const selectFirstRunCompleted = reselect . createSelector ( selectState , state => state . firstRunCompleted ) ;
const selectShowSuggestedSubs = reselect . createSelector ( selectState , state => state . showSuggestedSubs ) ; // Fetching any claims that are a part of a users subscriptions
const selectSubscriptionsBeingFetched = reselect . createSelector ( selectSubscriptions , lbryRedux . selectAllFetchingChannelClaims , ( subscriptions , fetchingChannelClaims ) => {
const fetchingSubscriptionMap = { } ;
subscriptions . forEach ( sub => {
const isFetching = fetchingChannelClaims && fetchingChannelClaims [ sub . uri ] ;
if ( isFetching ) {
fetchingSubscriptionMap [ sub . uri ] = true ;
}
} ) ;
return fetchingSubscriptionMap ;
} ) ;
const selectUnreadByChannel = reselect . createSelector ( selectState , state => state . unread ) ; // Returns the current total of unread subscriptions
const selectUnreadAmount = reselect . createSelector ( selectUnreadByChannel , unreadByChannel => {
const unreadChannels = Object . keys ( unreadByChannel ) ;
let badges = 0 ;
if ( ! unreadChannels . length ) {
return badges ;
}
unreadChannels . forEach ( channel => {
badges += unreadByChannel [ channel ] . uris . length ;
} ) ;
return badges ;
} ) ; // Returns the uris with channels as an array with the channel with the newest content first
// If you just want the `unread` state, use selectUnread
const selectUnreadSubscriptions = reselect . createSelector ( selectUnreadAmount , selectUnreadByChannel , lbryRedux . selectClaimsByUri , ( unreadAmount , unreadByChannel , claimsByUri ) => {
// determine which channel has the newest content
const unreadList = [ ] ;
if ( ! unreadAmount ) {
return unreadList ;
}
const channelUriList = Object . keys ( unreadByChannel ) ; // There is only one channel with unread notifications
if ( unreadAmount === 1 ) {
channelUriList . forEach ( channel => {
const unreadChannel = {
channel ,
uris : unreadByChannel [ channel ] . uris
} ;
unreadList . push ( unreadChannel ) ;
} ) ;
return unreadList ;
}
channelUriList . sort ( ( channel1 , channel2 ) => {
const latestUriFromChannel1 = unreadByChannel [ channel1 ] . uris [ 0 ] ;
const latestClaimFromChannel1 = claimsByUri [ latestUriFromChannel1 ] || { } ;
const latestUriFromChannel2 = unreadByChannel [ channel2 ] . uris [ 0 ] ;
const latestClaimFromChannel2 = claimsByUri [ latestUriFromChannel2 ] || { } ;
const latestHeightFromChannel1 = latestClaimFromChannel1 . height || 0 ;
const latestHeightFromChannel2 = latestClaimFromChannel2 . height || 0 ;
if ( latestHeightFromChannel1 !== latestHeightFromChannel2 ) {
return latestHeightFromChannel2 - latestHeightFromChannel1 ;
}
return 0 ;
} ) . forEach ( channel => {
const unreadSubscription = unreadByChannel [ channel ] ;
const unreadChannel = {
channel ,
uris : unreadSubscription . uris
} ;
unreadList . push ( unreadChannel ) ;
} ) ;
return unreadList ;
} ) ; // Returns all unread subscriptions for a uri passed in
const makeSelectUnreadByChannel = uri => reselect . createSelector ( selectUnreadByChannel , unread => unread [ uri ] ) ; // Returns the first page of claims for every channel a user is subscribed to
const selectSubscriptionClaims = reselect . createSelector ( lbryRedux . selectAllClaimsByChannel , lbryRedux . selectClaimsById , selectSubscriptions , selectUnreadByChannel , ( channelIds , allClaims , savedSubscriptions , unreadByChannel ) => {
// no claims loaded yet
if ( ! Object . keys ( channelIds ) . length ) {
return [ ] ;
}
let fetchedSubscriptions = [ ] ;
savedSubscriptions . forEach ( subscription => {
let channelClaims = [ ] ; // if subscribed channel has content
if ( channelIds [ subscription . uri ] && channelIds [ subscription . uri ] [ '1' ] ) {
// This will need to be more robust, we will want to be able to load more than the first page
// Strip out any ids that will be shown as notifications
const pageOneChannelIds = channelIds [ subscription . uri ] [ '1' ] ; // we have the channel ids and the corresponding claims
// loop over the list of ids and grab the claim
pageOneChannelIds . forEach ( id => {
const grabbedClaim = allClaims [ id ] ;
if ( unreadByChannel [ subscription . uri ] && unreadByChannel [ subscription . uri ] . uris . some ( uri => uri . includes ( id ) ) ) {
grabbedClaim . isNew = true ;
}
channelClaims = channelClaims . concat ( [ grabbedClaim ] ) ;
} ) ;
}
fetchedSubscriptions = fetchedSubscriptions . concat ( channelClaims ) ;
} ) ;
return fetchedSubscriptions ;
} ) ; // Returns true if a user is subscribed to the channel associated with the uri passed in
// Accepts content or channel uris
const makeSelectIsSubscribed = uri => reselect . createSelector ( selectSubscriptions , lbryRedux . makeSelectChannelForClaimUri ( uri , true ) , ( subscriptions , channelUri ) => {
if ( channelUri ) {
return subscriptions . some ( sub => sub . uri === channelUri ) ;
} // If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
const {
isChannel
} = lbryRedux . parseURI ( uri ) ;
if ( isChannel ) {
const uriWithPrefix = uri . startsWith ( 'lbry://' ) ? uri : ` lbry:// ${ uri } ` ;
return subscriptions . some ( sub => sub . uri === uriWithPrefix ) ;
}
return false ;
} ) ;
const makeSelectIsNew = uri => reselect . createSelector ( makeSelectIsSubscribed ( uri ) , lbryRedux . makeSelectChannelForClaimUri ( uri ) , selectUnreadByChannel , ( isSubscribed , channel , unreadByChannel ) => {
if ( ! isSubscribed ) {
return false ;
}
const unreadForChannel = unreadByChannel [ ` lbry:// ${ channel } ` ] ;
if ( unreadForChannel ) {
return unreadForChannel . uris . includes ( uri ) ;
}
return false ; // If they are subscribed, check to see if this uri is in the list of unreads
} ) ;
const selectEnabledChannelNotifications = reselect . createSelector ( selectState , state => state . enabledChannelNotifications ) ;
const persistShape = {
version : '0' ,
shared : { }
} ;
function userStateSyncMiddleware ( ) {
return ( {
getState
} ) => next => action => {
if ( action . type === CHANNEL _SUBSCRIBE || action . type === CHANNEL _UNSUBSCRIBE || action . type === lbryRedux . ACTIONS . TOGGLE _TAG _FOLLOW ) {
const newShape = { ... persistShape
} ;
const state = getState ( ) ;
const subscriptions = selectSubscriptions ( state ) . map ( ( {
uri
} ) => uri ) ;
const tags = lbryRedux . selectFollowedTags ( state ) ;
newShape . shared . subscriptions = subscriptions ;
newShape . shared . tags = tags ;
const {
uri
} = action . data ;
if ( action . type === CHANNEL _SUBSCRIBE ) {
const newSubscriptions = subscriptions . slice ( ) ;
newSubscriptions . push ( uri ) ;
newShape . shared . subscriptions = newSubscriptions ;
} else if ( action . type === CHANNEL _UNSUBSCRIBE ) {
let newSubscriptions = subscriptions . slice ( ) ;
newSubscriptions = newSubscriptions . filter ( subscribedUri => subscribedUri !== uri ) ;
newShape . shared . subscriptions = newSubscriptions ;
} else {
const toggledTag = action . data . name ;
const followedTags = lbryRedux . selectFollowedTags ( state ) . map ( ( {
name
} ) => name ) ;
const isFollowing = lbryRedux . makeSelectIsFollowingTag ( toggledTag ) ( state ) ;
let newTags = followedTags . slice ( ) ;
if ( isFollowing ) {
newTags = newTags . filter ( followedTag => followedTag . name !== toggledTag ) ;
} else {
newTags . push ( toggledTag ) ;
}
newShape . shared . tags = newTags ;
}
Lbryio . call ( 'user_settings' , 'set' , {
settings : newShape
} ) ;
}
return next ( action ) ;
} ;
}
2019-04-03 23:34:07 +02:00
function doGenerateAuthToken ( installationId ) {
return dispatch => {
dispatch ( {
type : GENERATE _AUTH _TOKEN _STARTED
} ) ;
Lbryio . call ( 'user' , 'new' , {
auth _token : '' ,
language : 'en' ,
app _id : installationId
} , 'post' ) . then ( response => {
if ( ! response . auth _token ) {
dispatch ( {
type : GENERATE _AUTH _TOKEN _FAILURE
} ) ;
} else {
dispatch ( {
type : GENERATE _AUTH _TOKEN _SUCCESS ,
data : {
authToken : response . auth _token
}
} ) ;
}
} ) . catch ( ( ) => {
dispatch ( {
type : GENERATE _AUTH _TOKEN _FAILURE
} ) ;
} ) ;
} ;
}
2019-09-16 22:12:43 +02:00
const selectState$1 = state => state . rewards || { } ;
2019-04-03 23:34:07 +02:00
2019-09-16 22:12:43 +02:00
const selectUnclaimedRewardsByType = reselect . createSelector ( selectState$1 , state => state . unclaimedRewardsByType ) ;
const selectClaimedRewardsById = reselect . createSelector ( selectState$1 , state => state . claimedRewardsById ) ;
2019-04-03 23:34:07 +02:00
const selectClaimedRewards = reselect . createSelector ( selectClaimedRewardsById , byId => Object . values ( byId ) || [ ] ) ;
const selectClaimedRewardsByTransactionId = reselect . createSelector ( selectClaimedRewards , rewards => rewards . reduce ( ( mapParam , reward ) => {
const map = mapParam ;
map [ reward . transaction _id ] = reward ;
return map ;
} , { } ) ) ;
2019-09-16 22:12:43 +02:00
const selectUnclaimedRewards = reselect . createSelector ( selectState$1 , state => state . unclaimedRewards ) ;
const selectFetchingRewards = reselect . createSelector ( selectState$1 , state => ! ! state . fetching ) ;
2019-04-03 23:34:07 +02:00
const selectUnclaimedRewardValue = reselect . createSelector ( selectUnclaimedRewards , rewards => rewards . reduce ( ( sum , reward ) => sum + reward . reward _amount , 0 ) ) ;
2019-09-16 22:12:43 +02:00
const selectClaimsPendingByType = reselect . createSelector ( selectState$1 , state => state . claimPendingByType ) ;
2019-04-03 23:34:07 +02:00
const selectIsClaimRewardPending = ( state , props ) => selectClaimsPendingByType ( state , props ) [ props . reward _type ] ;
const makeSelectIsRewardClaimPending = ( ) => reselect . createSelector ( selectIsClaimRewardPending , isClaiming => isClaiming ) ;
2019-09-16 22:12:43 +02:00
const selectClaimErrorsByType = reselect . createSelector ( selectState$1 , state => state . claimErrorsByType ) ;
2019-04-03 23:34:07 +02:00
const selectClaimRewardError = ( state , props ) => selectClaimErrorsByType ( state , props ) [ props . reward _type ] ;
const makeSelectClaimRewardError = ( ) => reselect . createSelector ( selectClaimRewardError , errorMessage => errorMessage ) ;
const selectRewardByType = ( state , rewardType ) => selectUnclaimedRewards ( state ) . find ( reward => reward . reward _type === rewardType ) ;
const makeSelectRewardByType = ( ) => reselect . createSelector ( selectRewardByType , reward => reward ) ;
const makeSelectRewardAmountByType = ( ) => reselect . createSelector ( selectRewardByType , reward => reward ? reward . reward _amount : 0 ) ;
2019-09-16 22:12:43 +02:00
const selectRewardContentClaimIds = reselect . createSelector ( selectState$1 , state => state . rewardedContentClaimIds ) ;
2019-04-03 23:34:07 +02:00
const selectReferralReward = reselect . createSelector ( selectUnclaimedRewards , unclaimedRewards => unclaimedRewards . filter ( reward => reward . reward _type === rewards . TYPE _REFERRAL ) [ 0 ] ) ;
2019-09-16 22:12:43 +02:00
const selectState$2 = state => state . user || { } ;
const selectAuthenticationIsPending = reselect . createSelector ( selectState$2 , state => state . authenticationIsPending ) ;
const selectUserIsPending = reselect . createSelector ( selectState$2 , state => state . userIsPending ) ;
const selectUser = reselect . createSelector ( selectState$2 , state => state . user ) ;
2019-04-03 23:34:07 +02:00
const selectUserEmail = reselect . createSelector ( selectUser , user => user ? user . primary _email : null ) ;
const selectUserPhone = reselect . createSelector ( selectUser , user => user ? user . phone _number : null ) ;
const selectUserCountryCode = reselect . createSelector ( selectUser , user => user ? user . country _code : null ) ;
2019-09-16 22:12:43 +02:00
const selectEmailToVerify = reselect . createSelector ( selectState$2 , selectUserEmail , ( state , userEmail ) => state . emailToVerify || userEmail ) ;
const selectPhoneToVerify = reselect . createSelector ( selectState$2 , selectUserPhone , ( state , userPhone ) => state . phoneToVerify || userPhone ) ;
2019-04-03 23:34:07 +02:00
const selectUserIsRewardApproved = reselect . createSelector ( selectUser , user => user && user . is _reward _approved ) ;
2019-09-16 22:12:43 +02:00
const selectEmailNewIsPending = reselect . createSelector ( selectState$2 , state => state . emailNewIsPending ) ;
const selectEmailNewErrorMessage = reselect . createSelector ( selectState$2 , state => state . emailNewErrorMessage ) ;
const selectPhoneNewErrorMessage = reselect . createSelector ( selectState$2 , state => state . phoneNewErrorMessage ) ;
const selectEmailVerifyIsPending = reselect . createSelector ( selectState$2 , state => state . emailVerifyIsPending ) ;
const selectEmailVerifyErrorMessage = reselect . createSelector ( selectState$2 , state => state . emailVerifyErrorMessage ) ;
const selectPhoneNewIsPending = reselect . createSelector ( selectState$2 , state => state . phoneNewIsPending ) ;
const selectPhoneVerifyIsPending = reselect . createSelector ( selectState$2 , state => state . phoneVerifyIsPending ) ;
const selectPhoneVerifyErrorMessage = reselect . createSelector ( selectState$2 , state => state . phoneVerifyErrorMessage ) ;
const selectIdentityVerifyIsPending = reselect . createSelector ( selectState$2 , state => state . identityVerifyIsPending ) ;
const selectIdentityVerifyErrorMessage = reselect . createSelector ( selectState$2 , state => state . identityVerifyErrorMessage ) ;
2019-09-13 16:38:40 +02:00
const selectUserVerifiedEmail = reselect . createSelector ( selectUser , user => user && user . has _verified _email ) ;
2019-04-03 23:34:07 +02:00
const selectUserIsVerificationCandidate = reselect . createSelector ( selectUser , user => user && ( ! user . has _verified _email || ! user . is _identity _verified ) ) ;
2019-09-16 22:12:43 +02:00
const selectAccessToken = reselect . createSelector ( selectState$2 , state => state . accessToken ) ;
const selectUserInviteStatusIsPending = reselect . createSelector ( selectState$2 , state => state . inviteStatusIsPending ) ;
const selectUserInvitesRemaining = reselect . createSelector ( selectState$2 , state => state . invitesRemaining ) ;
const selectUserInvitees = reselect . createSelector ( selectState$2 , state => state . invitees ) ;
2019-04-03 23:34:07 +02:00
const selectUserInviteStatusFailed = reselect . createSelector ( selectUserInvitesRemaining , ( ) => selectUserInvitesRemaining === null ) ;
2019-09-16 22:12:43 +02:00
const selectUserInviteNewIsPending = reselect . createSelector ( selectState$2 , state => state . inviteNewIsPending ) ;
const selectUserInviteNewErrorMessage = reselect . createSelector ( selectState$2 , state => state . inviteNewErrorMessage ) ;
const selectUserInviteReferralLink = reselect . createSelector ( selectState$2 , state => state . referralLink ) ;
2019-04-03 23:34:07 +02:00
function doFetchInviteStatus ( ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _STARTED
} ) ;
Promise . all ( [ Lbryio . call ( 'user' , 'invite_status' ) , Lbryio . call ( 'user_referral_code' , 'list' ) ] ) . then ( ( [ status , code ] ) => {
dispatch ( doRewardList ( ) ) ;
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _SUCCESS ,
data : {
invitesRemaining : status . invites _remaining ? status . invites _remaining : 0 ,
invitees : status . invitees ,
referralLink : ` ${ Lbryio . CONNECTION _STRING } user/refer?r= ${ code } `
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _FAILURE ,
data : {
error
}
} ) ;
} ) ;
} ;
}
function doInstallNew ( appVersion , os = null ) {
const payload = {
app _version : appVersion
} ;
lbryRedux . Lbry . status ( ) . then ( status => {
payload . app _id = status . installation _id ;
payload . node _id = status . lbry _id ;
lbryRedux . Lbry . version ( ) . then ( version => {
payload . daemon _version = version . lbrynet _version ;
payload . operating _system = os || version . os _system ;
payload . platform = version . platform ;
Lbryio . call ( 'install' , 'new' , payload ) ;
} ) ;
} ) ;
} // TODO: Call doInstallNew separately so we don't have to pass appVersion and os_system params?
function doAuthenticate ( appVersion , os = null ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . AUTHENTICATION _STARTED
} ) ;
Lbryio . authenticate ( ) . then ( user => {
// analytics.setUser(user);
dispatch ( {
type : lbryRedux . ACTIONS . AUTHENTICATION _SUCCESS ,
data : {
user
}
} ) ;
dispatch ( doRewardList ( ) ) ;
dispatch ( doFetchInviteStatus ( ) ) ;
doInstallNew ( appVersion , os ) ;
} ) . catch ( error => {
dispatch ( {
type : lbryRedux . ACTIONS . AUTHENTICATION _FAILURE ,
data : {
error
}
} ) ;
} ) ;
} ;
}
function doUserFetch ( ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _FETCH _STARTED
} ) ;
Lbryio . getCurrentUser ( ) . then ( user => {
// analytics.setUser(user);
dispatch ( doRewardList ( ) ) ;
dispatch ( {
type : lbryRedux . ACTIONS . USER _FETCH _SUCCESS ,
data : {
user
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _FETCH _FAILURE ,
data : {
error
}
} ) ;
} ) ;
} ;
}
function doUserCheckEmailVerified ( ) {
// This will happen in the background so we don't need loading booleans
return dispatch => {
Lbryio . getCurrentUser ( ) . then ( user => {
if ( user . has _verified _email ) {
dispatch ( doRewardList ( ) ) ;
dispatch ( {
type : lbryRedux . ACTIONS . USER _FETCH _SUCCESS ,
data : {
user
}
} ) ;
}
} ) ;
} ;
}
function doUserPhoneReset ( ) {
return {
type : lbryRedux . ACTIONS . USER _PHONE _RESET
} ;
}
function doUserPhoneNew ( phone , countryCode ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _PHONE _NEW _STARTED ,
data : {
phone ,
country _code : countryCode
}
} ) ;
const success = ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _PHONE _NEW _SUCCESS ,
data : {
phone
}
} ) ;
} ;
const failure = error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _PHONE _NEW _FAILURE ,
data : {
error
}
} ) ;
} ;
Lbryio . call ( 'user' , 'phone_number_new' , {
phone _number : phone ,
country _code : countryCode
} , 'post' ) . then ( success , failure ) ;
} ;
}
function doUserPhoneVerifyFailure ( error ) {
return {
type : lbryRedux . ACTIONS . USER _PHONE _VERIFY _FAILURE ,
data : {
error
}
} ;
}
function doUserPhoneVerify ( verificationCode ) {
return ( dispatch , getState ) => {
const phoneNumber = selectPhoneToVerify ( getState ( ) ) ;
const countryCode = selectUserCountryCode ( getState ( ) ) ;
dispatch ( {
type : lbryRedux . ACTIONS . USER _PHONE _VERIFY _STARTED ,
code : verificationCode
} ) ;
Lbryio . call ( 'user' , 'phone_number_confirm' , {
verification _code : verificationCode ,
phone _number : phoneNumber ,
country _code : countryCode
} , 'post' ) . then ( user => {
if ( user . is _identity _verified ) {
dispatch ( {
type : lbryRedux . ACTIONS . USER _PHONE _VERIFY _SUCCESS ,
data : {
user
}
} ) ;
dispatch ( doClaimRewardType ( rewards . TYPE _NEW _USER ) ) ;
}
} ) . catch ( error => dispatch ( doUserPhoneVerifyFailure ( error ) ) ) ;
} ;
}
function doUserEmailToVerify ( email ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _VERIFY _SET ,
data : {
email
}
} ) ;
} ;
}
function doUserEmailNew ( email ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _NEW _STARTED ,
email
} ) ;
const success = ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _NEW _SUCCESS ,
data : {
email
}
} ) ;
dispatch ( doUserFetch ( ) ) ;
} ;
const failure = error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _NEW _FAILURE ,
data : {
error
}
} ) ;
} ;
Lbryio . call ( 'user_email' , 'new' , {
email ,
send _verification _email : true
} , 'post' ) . catch ( error => {
if ( error . response && error . response . status === 409 ) {
return Lbryio . call ( 'user_email' , 'resend_token' , {
email ,
only _if _expired : true
} , 'post' ) . then ( success , failure ) ;
}
throw error ;
} ) . then ( success , failure ) ;
} ;
}
function doUserResendVerificationEmail ( email ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _VERIFY _RETRY ,
email
} ) ;
const success = ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _NEW _SUCCESS ,
data : {
email
}
} ) ;
dispatch ( doUserFetch ( ) ) ;
} ;
const failure = error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _NEW _FAILURE ,
data : {
error
}
} ) ;
} ;
Lbryio . call ( 'user_email' , 'resend_token' , {
email
} , 'post' ) . catch ( error => {
if ( error . response && error . response . status === 409 ) {
throw error ;
}
} ) . then ( success , failure ) ;
} ;
}
function doUserEmailVerifyFailure ( error ) {
return {
type : lbryRedux . ACTIONS . USER _EMAIL _VERIFY _FAILURE ,
data : {
error
}
} ;
}
function doUserEmailVerify ( verificationToken , recaptcha ) {
return ( dispatch , getState ) => {
const email = selectEmailToVerify ( getState ( ) ) ;
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _VERIFY _STARTED ,
code : verificationToken ,
recaptcha
} ) ;
Lbryio . call ( 'user_email' , 'confirm' , {
verification _token : verificationToken ,
email ,
recaptcha
} , 'post' ) . then ( userEmail => {
if ( userEmail . is _verified ) {
dispatch ( {
type : lbryRedux . ACTIONS . USER _EMAIL _VERIFY _SUCCESS ,
data : {
email
}
} ) ;
dispatch ( doUserFetch ( ) ) ;
} else {
throw new Error ( 'Your email is still not verified.' ) ; // shouldn't happen
}
} ) . catch ( error => dispatch ( doUserEmailVerifyFailure ( error ) ) ) ;
} ;
}
function doFetchAccessToken ( ) {
return dispatch => {
const success = token => dispatch ( {
type : lbryRedux . ACTIONS . FETCH _ACCESS _TOKEN _SUCCESS ,
data : {
token
}
} ) ;
Lbryio . getAuthToken ( ) . then ( success ) ;
} ;
}
function doUserIdentityVerify ( stripeToken ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _STARTED ,
token : stripeToken
} ) ;
Lbryio . call ( 'user' , 'verify_identity' , {
stripe _token : stripeToken
} , 'post' ) . then ( user => {
if ( user . is _identity _verified ) {
dispatch ( {
type : lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _SUCCESS ,
data : {
user
}
} ) ;
dispatch ( doClaimRewardType ( rewards . TYPE _NEW _USER ) ) ;
} else {
throw new Error ( 'Your identity is still not verified. This should not happen.' ) ; // shouldn't happen
}
} ) . catch ( error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _FAILURE ,
data : {
error : error . toString ( )
}
} ) ;
} ) ;
} ;
}
function doUserInviteNew ( email ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _NEW _STARTED
} ) ;
Lbryio . call ( 'user' , 'invite' , {
email
} , 'post' ) . then ( ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _NEW _SUCCESS ,
data : {
email
}
} ) ;
dispatch ( lbryRedux . doToast ( {
message : _ _ ( 'Invite sent to %s' , email )
} ) ) ;
dispatch ( doFetchInviteStatus ( ) ) ;
} ) . catch ( error => {
dispatch ( {
type : lbryRedux . ACTIONS . USER _INVITE _NEW _FAILURE ,
data : {
error
}
} ) ;
} ) ;
} ;
}
function doRewardList ( ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . FETCH _REWARDS _STARTED
} ) ;
Lbryio . call ( 'reward' , 'list' , {
multiple _rewards _per _type : true
} ) . then ( userRewards => {
dispatch ( {
type : lbryRedux . ACTIONS . FETCH _REWARDS _COMPLETED ,
data : {
userRewards
}
} ) ;
} ) . catch ( ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . FETCH _REWARDS _COMPLETED ,
data : {
userRewards : [ ]
}
} ) ;
} ) ;
} ;
}
function doClaimRewardType ( rewardType , options = { } ) {
return ( dispatch , getState ) => {
const state = getState ( ) ;
const userIsRewardApproved = selectUserIsRewardApproved ( state ) ;
const unclaimedRewards = selectUnclaimedRewards ( state ) ;
const reward = rewardType === rewards . TYPE _REWARD _CODE ? {
reward _type : rewards . TYPE _REWARD _CODE
2019-09-13 16:38:40 +02:00
} : unclaimedRewards . find ( ur => ur . reward _type === rewardType ) ; // Try to claim the email reward right away, even if we haven't called reward_list yet
2019-04-03 23:34:07 +02:00
2019-09-13 16:38:40 +02:00
if ( rewardType !== rewards . TYPE _REWARD _CODE || rewardType !== rewards . TYPE _CONFIRM _EMAIL ) {
2019-04-03 23:34:07 +02:00
if ( ! reward || reward . transaction _id ) {
// already claimed or doesn't exist, do nothing
return ;
}
}
2019-09-13 16:38:40 +02:00
if ( ! userIsRewardApproved && rewardType !== rewards . TYPE _CONFIRM _EMAIL && rewardType !== rewards . TYPE _REWARD _CODE ) {
2019-04-03 23:34:07 +02:00
if ( ! options || ! options . failSilently && rewards . callbacks . rewardApprovalRequested ) {
rewards . callbacks . rewardApprovalRequested ( ) ;
}
return ;
} // Set `claim_code` so the api knows which reward to give if there are multiple of the same type
const params = options . params || { } ;
params . claim _code = reward . claim _code ;
dispatch ( {
type : lbryRedux . ACTIONS . CLAIM _REWARD _STARTED ,
data : {
reward
}
} ) ;
const success = successReward => {
dispatch ( {
type : lbryRedux . ACTIONS . CLAIM _REWARD _SUCCESS ,
data : {
reward : successReward
}
} ) ;
if ( successReward . reward _type === rewards . TYPE _NEW _USER && rewards . callbacks . claimFirstRewardSuccess ) {
rewards . callbacks . claimFirstRewardSuccess ( ) ;
} else if ( successReward . reward _type === rewards . TYPE _REFERRAL ) {
dispatch ( doFetchInviteStatus ( ) ) ;
}
dispatch ( doRewardList ( ) ) ;
2019-09-13 16:38:40 +02:00
if ( options . callback ) {
options . callback ( ) ;
}
2019-04-03 23:34:07 +02:00
} ;
const failure = error => {
dispatch ( {
type : lbryRedux . ACTIONS . CLAIM _REWARD _FAILURE ,
data : {
reward ,
error : ! options || ! options . failSilently ? error : undefined
}
} ) ;
if ( options . notifyError ) {
dispatch ( lbryRedux . doToast ( {
message : error . message ,
isError : true
} ) ) ;
}
2019-09-13 16:38:40 +02:00
if ( options . callback ) {
options . callback ( error ) ;
}
2019-04-03 23:34:07 +02:00
} ;
rewards . claimReward ( rewardType , params ) . then ( success , failure ) ;
} ;
}
function doClaimEligiblePurchaseRewards ( ) {
return ( dispatch , getState ) => {
const state = getState ( ) ;
const unclaimedRewards = selectUnclaimedRewards ( state ) ;
const userIsRewardApproved = selectUserIsRewardApproved ( state ) ;
if ( ! userIsRewardApproved || ! Lbryio . enabled ) {
return ;
}
if ( unclaimedRewards . find ( ur => ur . reward _type === rewards . TYPE _FIRST _STREAM ) ) {
dispatch ( doClaimRewardType ( rewards . TYPE _FIRST _STREAM ) ) ;
} else {
2019-09-04 23:12:37 +02:00
[ rewards . TYPE _MANY _DOWNLOADS , rewards . TYPE _FEATURED _DOWNLOAD , rewards . TYPE _DAILY _VIEW ] . forEach ( type => {
2019-04-03 23:34:07 +02:00
dispatch ( doClaimRewardType ( type , {
failSilently : true
} ) ) ;
} ) ;
}
} ;
}
function doClaimRewardClearError ( reward ) {
return dispatch => {
dispatch ( {
type : lbryRedux . ACTIONS . CLAIM _REWARD _CLEAR _ERROR ,
data : {
reward
}
} ) ;
} ;
}
function doFetchRewardedContent ( ) {
return dispatch => {
const success = nameToClaimId => {
dispatch ( {
type : lbryRedux . ACTIONS . FETCH _REWARD _CONTENT _COMPLETED ,
data : {
claimIds : Object . values ( nameToClaimId ) ,
success : true
}
} ) ;
} ;
const failure = ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . FETCH _REWARD _CONTENT _COMPLETED ,
data : {
claimIds : [ ] ,
success : false
}
} ) ;
} ;
Lbryio . call ( 'reward' , 'list_featured' ) . then ( success , failure ) ;
} ;
}
const PAGE _SIZE = 20 ;
//
const CHECK _SUBSCRIPTIONS _INTERVAL = 15 * 60 * 1000 ;
const doSetViewMode = viewMode => dispatch => dispatch ( {
type : SET _VIEW _MODE ,
data : viewMode
} ) ;
const setSubscriptionLatest = ( subscription , uri ) => dispatch => dispatch ( {
type : SET _SUBSCRIPTION _LATEST ,
data : {
subscription ,
uri
}
} ) ; // Populate a channels unread subscriptions or update the type
const doUpdateUnreadSubscriptions = ( channelUri , uris , type ) => ( dispatch , getState ) => {
const state = getState ( ) ;
const unreadByChannel = selectUnreadByChannel ( state ) ;
const currentUnreadForChannel = unreadByChannel [ channelUri ] ;
let newUris = [ ] ;
let newType = null ;
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 ;
}
dispatch ( {
type : UPDATE _SUBSCRIPTION _UNREADS ,
data : {
channel : channelUri ,
uris : newUris ,
type : newType
}
} ) ;
} ; // Remove multiple files (or all) from a channels unread subscriptions
const doRemoveUnreadSubscriptions = ( channelUri , readUris ) => ( dispatch , getState ) => {
const state = getState ( ) ;
const unreadByChannel = selectUnreadByChannel ( state ) ; // If no channel is passed in, remove all unread subscriptions from all channels
if ( ! channelUri ) {
return dispatch ( {
type : REMOVE _SUBSCRIPTION _UNREADS ,
data : {
channel : null
}
} ) ;
}
const currentChannelUnread = unreadByChannel [ channelUri ] ;
if ( ! currentChannelUnread || ! currentChannelUnread . uris ) {
// Channel passed in doesn't have any unreads
return null ;
} // For each uri passed in, remove it from the list of unread uris
// 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 ;
}
return dispatch ( {
type : REMOVE _SUBSCRIPTION _UNREADS ,
data : {
channel : channelUri ,
uris : newUris
}
} ) ;
} ; // Remove a single file from a channels unread subscriptions
const doRemoveUnreadSubscription = ( channelUri , readUri ) => dispatch => {
dispatch ( doRemoveUnreadSubscriptions ( channelUri , [ readUri ] ) ) ;
} ;
const doCheckSubscription = ( subscriptionUri , shouldNotify ) => ( dispatch , getState ) => {
// no dispatching FETCH_CHANNEL_CLAIMS_STARTED; causes loading issues on <SubscriptionsPage>
const state = getState ( ) ;
const savedSubscription = state . subscriptions . subscriptions . find ( sub => sub . uri === subscriptionUri ) ;
if ( ! savedSubscription ) {
throw Error ( ` Trying to find new content for ${ subscriptionUri } but it doesn't exist in your subscriptions ` ) ;
2019-05-21 20:40:29 +02:00
} // We may be duplicating calls here. Can this logic be baked into doFetchClaimsByChannel?
2019-04-03 23:34:07 +02:00
2019-04-27 20:57:03 +02:00
lbryRedux . Lbry . claim _search ( {
2019-07-22 20:12:54 +02:00
channel : subscriptionUri ,
2019-06-26 17:29:41 +02:00
valid _channel _signature : true ,
2019-08-29 18:58:30 +02:00
order _by : [ 'release_time' ] ,
page : 1 ,
page _size : PAGE _SIZE
} ) . then ( claimListByChannel => {
2019-04-03 23:34:07 +02:00
const {
2019-04-27 20:57:03 +02:00
items : claimsInChannel
2019-08-29 18:58:30 +02:00
} = claimListByChannel ; // may happen if subscribed to an abandoned channel or an empty channel
2019-04-03 23:34:07 +02:00
if ( ! claimsInChannel || ! claimsInChannel . length ) {
return ;
} // Determine if the latest subscription currently saved is actually the latest subscription
2019-08-29 18:58:30 +02:00
const latestIndex = claimsInChannel . findIndex ( claim => claim . permanent _url === savedSubscription . latest ) ; // If latest is -1, it is a newly subscribed channel or there have been 10+ claims published since last viewed
2019-04-03 23:34:07 +02:00
const latestIndexToNotify = latestIndex === - 1 ? 10 : latestIndex ; // If latest is 0, nothing has changed
// Do not download/notify about new content, it would download/notify 10 claims per channel
if ( latestIndex !== 0 && savedSubscription . latest ) {
let downloadCount = 0 ;
const newUnread = [ ] ;
claimsInChannel . slice ( 0 , latestIndexToNotify ) . forEach ( claim => {
2019-08-29 18:58:30 +02:00
const uri = claim . permanent _url ;
2019-04-03 23:34:07 +02:00
if ( shouldNotify ) {
newUnread . push ( uri ) ;
}
} ) ;
dispatch ( doUpdateUnreadSubscriptions ( subscriptionUri , newUnread , downloadCount > 0 ? DOWNLOADING : NOTIFY _ONLY ) ) ;
} // Set the latest piece of content for a channel
// This allows the app to know if there has been new content since it was last set
2019-08-29 18:58:30 +02:00
const latest = claimsInChannel [ 0 ] ;
2019-04-03 23:34:07 +02:00
dispatch ( setSubscriptionLatest ( {
2019-08-29 18:58:30 +02:00
channelName : latest . signing _channel . name ,
uri : latest . signing _channel . permanent _url
} , latest . permanent _url ) ) ; // calling FETCH_CHANNEL_CLAIMS_COMPLETED after not calling STARTED
2019-04-03 23:34:07 +02:00
// means it will delete a non-existant fetchingChannelClaims[uri]
dispatch ( {
type : FETCH _CHANNEL _CLAIMS _COMPLETED ,
data : {
uri : subscriptionUri ,
claims : claimsInChannel || [ ] ,
page : 1
}
} ) ;
} ) ;
} ;
const doChannelSubscribe = subscription => ( dispatch , getState ) => {
const {
settings : {
daemonSettings
}
} = getState ( ) ;
const isSharingData = daemonSettings ? daemonSettings . share _usage _data : true ;
const subscriptionUri = subscription . uri ;
if ( ! subscriptionUri . startsWith ( 'lbry://' ) ) {
throw Error ( ` Subscription uris must inclue the "lbry://" prefix. \n Tried to subscribe to ${ subscriptionUri } ` ) ;
}
dispatch ( {
type : CHANNEL _SUBSCRIBE ,
data : subscription
} ) ; // if the user isn't sharing data, keep the subscriptions entirely in the app
if ( isSharingData ) {
const {
2019-08-29 18:58:30 +02:00
channelClaimId
2019-04-03 23:34:07 +02:00
} = lbryRedux . parseURI ( subscription . uri ) ; // They are sharing data, we can store their subscriptions in our internal database
Lbryio . call ( 'subscription' , 'new' , {
channel _name : subscription . channelName ,
2019-08-29 18:58:30 +02:00
claim _id : channelClaimId
2019-04-03 23:34:07 +02:00
} ) ;
dispatch ( doClaimRewardType ( rewards . TYPE _SUBSCRIPTION , {
failSilently : true
} ) ) ;
}
dispatch ( doCheckSubscription ( subscription . uri , true ) ) ;
} ;
const doChannelUnsubscribe = subscription => ( dispatch , getState ) => {
const {
settings : {
daemonSettings
}
} = getState ( ) ;
const isSharingData = daemonSettings ? daemonSettings . share _usage _data : true ;
dispatch ( {
type : CHANNEL _UNSUBSCRIBE ,
data : subscription
} ) ;
if ( isSharingData ) {
const {
2019-08-29 18:58:30 +02:00
channelClaimId
2019-04-03 23:34:07 +02:00
} = lbryRedux . parseURI ( subscription . uri ) ;
Lbryio . call ( 'subscription' , 'delete' , {
2019-08-29 18:58:30 +02:00
claim _id : channelClaimId
2019-04-03 23:34:07 +02:00
} ) ;
}
} ;
const doCheckSubscriptions = ( ) => ( dispatch , getState ) => {
const state = getState ( ) ;
const subscriptions = selectSubscriptions ( state ) ;
subscriptions . forEach ( sub => {
dispatch ( doCheckSubscription ( sub . uri , true ) ) ;
} ) ;
} ;
const doFetchMySubscriptions = ( ) => ( dispatch , getState ) => {
const state = getState ( ) ;
const {
subscriptions : reduxSubscriptions
} = state . subscriptions ; // default to true if daemonSettings not found
const isSharingData = state . settings && state . settings . daemonSettings ? state . settings . daemonSettings . share _usage _data : true ;
if ( ! isSharingData && isSharingData !== undefined ) {
// They aren't sharing their data, subscriptions will be handled by persisted redux state
return ;
} // most of this logic comes from scenarios where the db isn't synced with redux
// this will happen if the user stops sharing data
dispatch ( {
type : FETCH _SUBSCRIPTIONS _START
} ) ;
Lbryio . call ( 'subscription' , 'list' ) . then ( dbSubscriptions => {
const storedSubscriptions = dbSubscriptions || [ ] ; // User has no subscriptions in db or redux
if ( ! storedSubscriptions . length && ( ! reduxSubscriptions || ! reduxSubscriptions . length ) ) {
return [ ] ;
} // There is some mismatch between redux state and db state
// If something is in the db, but not in redux, add it to redux
// If something is in redux, but not in the db, add it to the db
if ( storedSubscriptions . length !== reduxSubscriptions . length ) {
const dbSubMap = { } ;
const reduxSubMap = { } ;
const subsNotInDB = [ ] ;
const subscriptionsToReturn = reduxSubscriptions . slice ( ) ;
storedSubscriptions . forEach ( sub => {
dbSubMap [ sub . claim _id ] = 1 ;
} ) ;
reduxSubscriptions . forEach ( sub => {
const {
2019-08-29 18:58:30 +02:00
channelClaimId
2019-04-03 23:34:07 +02:00
} = lbryRedux . parseURI ( sub . uri ) ;
2019-08-29 18:58:30 +02:00
reduxSubMap [ channelClaimId ] = 1 ;
2019-04-03 23:34:07 +02:00
} ) ;
storedSubscriptions . forEach ( sub => {
if ( ! reduxSubMap [ sub . claim _id ] ) {
const uri = ` lbry:// ${ sub . channel _name } # ${ sub . claim _id } ` ;
subscriptionsToReturn . push ( {
uri ,
channelName : sub . channel _name
} ) ;
}
} ) ;
return Promise . all ( subsNotInDB . map ( payload => Lbryio . call ( 'subscription' , 'new' , payload ) ) ) . then ( ( ) => subscriptionsToReturn ) . catch ( ( ) => // let it fail, we will try again when the navigate to the subscriptions page
subscriptionsToReturn ) ;
} // DB is already synced, just return the subscriptions in redux
return reduxSubscriptions ;
} ) . then ( subscriptions => {
dispatch ( {
type : FETCH _SUBSCRIPTIONS _SUCCESS ,
data : subscriptions
} ) ;
dispatch ( lbryRedux . doResolveUris ( subscriptions . map ( ( {
uri
} ) => uri ) ) ) ;
dispatch ( doCheckSubscriptions ( ) ) ;
} ) . catch ( ( ) => {
dispatch ( {
type : FETCH _SUBSCRIPTIONS _FAIL
} ) ;
} ) ;
} ;
const doCheckSubscriptionsInit = ( ) => dispatch => {
// doCheckSubscriptionsInit is called by doDaemonReady
// setTimeout below is a hack to ensure redux is hydrated when subscriptions are checked
// this will be replaced with <PersistGate> which reqiures a package upgrade
setTimeout ( ( ) => dispatch ( doFetchMySubscriptions ( ) ) , 5000 ) ;
const checkSubscriptionsTimer = setInterval ( ( ) => dispatch ( doCheckSubscriptions ( ) ) , CHECK _SUBSCRIPTIONS _INTERVAL ) ;
dispatch ( {
type : CHECK _SUBSCRIPTIONS _SUBSCRIBE ,
data : {
checkSubscriptionsTimer
}
} ) ;
setInterval ( ( ) => dispatch ( doCheckSubscriptions ( ) ) , CHECK _SUBSCRIPTIONS _INTERVAL ) ;
} ;
const doFetchRecommendedSubscriptions = ( ) => dispatch => {
dispatch ( {
type : GET _SUGGESTED _SUBSCRIPTIONS _START
} ) ;
return Lbryio . call ( 'subscription' , 'suggest' ) . then ( suggested => dispatch ( {
type : GET _SUGGESTED _SUBSCRIPTIONS _SUCCESS ,
data : suggested
} ) ) . catch ( error => dispatch ( {
type : GET _SUGGESTED _SUBSCRIPTIONS _FAIL ,
error
} ) ) ;
} ;
const doCompleteFirstRun = ( ) => dispatch => dispatch ( {
type : SUBSCRIPTION _FIRST _RUN _COMPLETED
} ) ;
const doShowSuggestedSubs = ( ) => dispatch => dispatch ( {
type : VIEW _SUGGESTED _SUBSCRIPTIONS
} ) ;
const doChannelSubscriptionEnableNotifications = channelName => dispatch => dispatch ( {
type : CHANNEL _SUBSCRIPTION _ENABLE _NOTIFICATIONS ,
data : channelName
} ) ;
const doChannelSubscriptionDisableNotifications = channelName => dispatch => dispatch ( {
type : CHANNEL _SUBSCRIPTION _DISABLE _NOTIFICATIONS ,
data : channelName
} ) ;
function doFetchCostInfoForUri ( uri ) {
return ( dispatch , getState ) => {
const state = getState ( ) ;
const claim = lbryRedux . selectClaimsByUri ( state ) [ uri ] ;
if ( ! claim ) return ;
function resolve ( costInfo ) {
dispatch ( {
type : FETCH _COST _INFO _COMPLETED ,
data : {
uri ,
costInfo
}
} ) ;
}
2019-04-22 23:24:03 +02:00
const fee = claim . value ? claim . value . fee : undefined ;
2019-04-03 23:34:07 +02:00
if ( fee === undefined ) {
resolve ( {
cost : 0 ,
includesData : true
} ) ;
} else if ( fee . currency === 'LBC' ) {
resolve ( {
cost : fee . amount ,
includesData : true
} ) ;
} else {
Lbryio . getExchangeRates ( ) . then ( ( {
LBC _USD
} ) => {
resolve ( {
cost : fee . amount / LBC _USD ,
includesData : true
} ) ;
} ) ;
}
} ;
}
const CHECK _BLACK _LISTED _CONTENT _INTERVAL = 60 * 60 * 1000 ;
function doFetchBlackListedOutpoints ( ) {
return dispatch => {
dispatch ( {
type : FETCH _BLACK _LISTED _CONTENT _STARTED
} ) ;
const success = ( {
outpoints
} ) => {
const splitedOutpoints = [ ] ;
outpoints . forEach ( ( outpoint , index ) => {
const [ txid , nout ] = outpoint . split ( ':' ) ;
splitedOutpoints [ index ] = {
txid ,
nout : Number . parseInt ( nout , 10 )
} ;
} ) ;
dispatch ( {
type : FETCH _BLACK _LISTED _CONTENT _COMPLETED ,
data : {
outpoints : splitedOutpoints ,
success : true
}
} ) ;
} ;
const failure = ( {
error
} ) => {
dispatch ( {
type : FETCH _BLACK _LISTED _CONTENT _FAILED ,
data : {
error ,
success : false
}
} ) ;
} ;
Lbryio . call ( 'file' , 'list_blocked' ) . then ( success , failure ) ;
} ;
}
function doBlackListedOutpointsSubscribe ( ) {
return dispatch => {
dispatch ( doFetchBlackListedOutpoints ( ) ) ;
setInterval ( ( ) => dispatch ( doFetchBlackListedOutpoints ( ) ) , CHECK _BLACK _LISTED _CONTENT _INTERVAL ) ;
} ;
}
2019-07-09 16:20:01 +02:00
const CHECK _FILTERED _CONTENT _INTERVAL = 60 * 60 * 1000 ;
function doFetchFilteredOutpoints ( ) {
return dispatch => {
dispatch ( {
type : FETCH _FILTERED _CONTENT _STARTED
} ) ;
const success = ( {
outpoints
} ) => {
2019-07-11 02:44:15 +02:00
const formattedOutpoints = outpoints . map ( outpoint => {
2019-07-09 16:20:01 +02:00
const [ txid , nout ] = outpoint . split ( ':' ) ;
2019-07-11 02:44:15 +02:00
return {
2019-07-09 16:20:01 +02:00
txid ,
nout : Number . parseInt ( nout , 10 )
} ;
} ) ;
dispatch ( {
type : FETCH _FILTERED _CONTENT _COMPLETED ,
data : {
2019-07-11 02:44:15 +02:00
outpoints : formattedOutpoints
2019-07-09 16:20:01 +02:00
}
} ) ;
} ;
const failure = ( {
error
} ) => {
dispatch ( {
type : FETCH _FILTERED _CONTENT _FAILED ,
data : {
2019-07-11 02:44:15 +02:00
error
2019-07-09 16:20:01 +02:00
}
} ) ;
} ;
Lbryio . call ( 'file' , 'list_filtered' ) . then ( success , failure ) ;
} ;
}
function doFilteredOutpointsSubscribe ( ) {
return dispatch => {
dispatch ( doFetchFilteredOutpoints ( ) ) ;
setInterval ( ( ) => dispatch ( doFetchFilteredOutpoints ( ) ) , CHECK _FILTERED _CONTENT _INTERVAL ) ;
} ;
}
2019-04-03 23:34:07 +02:00
function doFetchFeaturedUris ( offloadResolve = false ) {
return dispatch => {
dispatch ( {
type : FETCH _FEATURED _CONTENT _STARTED
} ) ;
const success = ( {
Uris
} ) => {
let urisToResolve = [ ] ;
Object . keys ( Uris ) . forEach ( category => {
urisToResolve = [ ... urisToResolve , ... Uris [ category ] ] ;
} ) ;
const actions = [ {
type : FETCH _FEATURED _CONTENT _COMPLETED ,
data : {
uris : Uris ,
success : true
}
} ] ;
if ( urisToResolve . length && ! offloadResolve ) {
actions . push ( lbryRedux . doResolveUris ( urisToResolve ) ) ;
}
dispatch ( lbryRedux . batchActions ( ... actions ) ) ;
} ;
const failure = ( ) => {
dispatch ( {
type : FETCH _FEATURED _CONTENT _COMPLETED ,
data : {
uris : { }
}
} ) ;
} ;
Lbryio . call ( 'file' , 'list_homepage' ) . then ( success , failure ) ;
} ;
}
function doFetchTrendingUris ( ) {
return dispatch => {
dispatch ( {
type : FETCH _TRENDING _CONTENT _STARTED
} ) ;
const success = data => {
const urisToResolve = data . map ( uri => uri . url ) ;
const actions = [ lbryRedux . doResolveUris ( urisToResolve ) , {
type : FETCH _TRENDING _CONTENT _COMPLETED ,
data : {
uris : data ,
success : true
}
} ] ;
dispatch ( lbryRedux . batchActions ( ... actions ) ) ;
} ;
const failure = ( ) => {
dispatch ( {
type : FETCH _TRENDING _CONTENT _COMPLETED ,
data : {
uris : [ ]
}
} ) ;
} ;
Lbryio . call ( 'file' , 'list_trending' ) . then ( success , failure ) ;
} ;
}
//
const doFetchViewCount = claimId => dispatch => {
dispatch ( {
type : FETCH _VIEW _COUNT _STARTED
} ) ;
return Lbryio . call ( 'file' , 'view_count' , {
claim _id : claimId
} ) . then ( result => {
const viewCount = result [ 0 ] ;
dispatch ( {
type : FETCH _VIEW _COUNT _COMPLETED ,
data : {
claimId ,
viewCount
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : FETCH _VIEW _COUNT _FAILED ,
data : error
} ) ;
} ) ;
} ;
2019-04-18 10:02:11 +02:00
function doSetSync ( oldHash , newHash , data ) {
return dispatch => {
dispatch ( {
type : SET _SYNC _STARTED
} ) ;
Lbryio . call ( 'sync' , 'set' , {
old _hash : oldHash ,
new _hash : newHash ,
data
} , 'post' ) . then ( response => {
if ( ! response . hash ) {
return dispatch ( {
type : SET _SYNC _FAILED ,
data : {
error : 'No hash returned for sync/set.'
}
} ) ;
}
return dispatch ( {
type : SET _SYNC _COMPLETED ,
data : {
syncHash : response . hash
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : SET _SYNC _FAILED ,
data : {
error
}
} ) ;
} ) ;
} ;
}
2019-09-06 17:19:17 +02:00
function doSetDefaultAccount ( success , failure ) {
2019-05-10 16:45:56 +02:00
return dispatch => {
dispatch ( {
type : SET _DEFAULT _ACCOUNT
} ) ;
lbryRedux . Lbry . account _list ( ) . then ( accountList => {
const {
lbc _mainnet : accounts
} = accountList ;
let defaultId ;
2019-05-27 15:57:31 +02:00
for ( let i = 0 ; i < accounts . length ; ++ i ) {
2019-05-10 16:45:56 +02:00
if ( accounts [ i ] . satoshis > 0 ) {
defaultId = accounts [ i ] . id ;
break ;
}
} // In a case where there's no balance on either account
// assume the second (which is created after sync) as default
if ( ! defaultId && accounts . length > 1 ) {
defaultId = accounts [ 1 ] . id ;
} // Set the default account
if ( defaultId ) {
lbryRedux . Lbry . account _set ( {
account _id : defaultId ,
default : true
2019-09-06 17:19:17 +02:00
} ) . then ( ( ) => {
if ( success ) {
success ( ) ;
}
} ) . catch ( err => {
if ( failure ) {
failure ( err ) ;
}
2019-05-10 16:45:56 +02:00
} ) ;
2019-09-06 17:19:17 +02:00
} else {
// no default account to set
if ( failure ) {
failure ( 'Could not set a default account' ) ; // fail
}
}
} ) . catch ( err => {
if ( failure ) {
failure ( err ) ;
2019-05-10 16:45:56 +02:00
}
} ) ;
} ;
}
2019-04-18 10:02:11 +02:00
function doGetSync ( password ) {
return dispatch => {
dispatch ( {
type : GET _SYNC _STARTED
} ) ;
lbryRedux . Lbry . sync _hash ( ) . then ( hash => {
Lbryio . call ( 'sync' , 'get' , {
hash
} , 'post' ) . then ( response => {
const data = {
hasSyncedWallet : true
} ;
if ( response . changed ) {
const syncHash = response . hash ;
data . syncHash = syncHash ;
2019-05-27 15:57:31 +02:00
data . syncData = response . data ;
2019-04-18 10:02:11 +02:00
lbryRedux . Lbry . sync _apply ( {
password ,
data : response . data
} ) . then ( ( {
hash : walletHash ,
data : walletData
} ) => {
if ( walletHash !== syncHash ) {
// different local hash, need to synchronise
dispatch ( doSetSync ( syncHash , walletHash , walletData ) ) ;
2019-05-28 18:38:43 +02:00
}
2019-04-18 10:02:11 +02:00
} ) ;
}
dispatch ( {
type : GET _SYNC _COMPLETED ,
data
} ) ;
} ) . catch ( ( ) => {
// user doesn't have a synced wallet
dispatch ( {
type : GET _SYNC _COMPLETED ,
data : {
hasSyncedWallet : false ,
syncHash : null
}
} ) ; // call sync_apply to get data to sync
// first time sync. use any string for old hash
lbryRedux . Lbry . sync _apply ( {
password
} ) . then ( ( {
hash : walletHash ,
data
} ) => dispatch ( doSetSync ( null , walletHash , data ) ) ) ;
} ) ;
} ) ;
} ;
}
2019-05-27 15:57:31 +02:00
function doSyncApply ( syncHash , syncData , password ) {
return dispatch => {
dispatch ( {
type : SYNC _APPLY _STARTED
} ) ;
lbryRedux . Lbry . sync _apply ( {
password ,
data : syncData
} ) . then ( ( {
hash : walletHash ,
data : walletData
} ) => {
dispatch ( {
type : SYNC _APPLY _COMPLETED
} ) ;
if ( walletHash !== syncHash ) {
// different local hash, need to synchronise
dispatch ( doSetSync ( syncHash , walletHash , walletData ) ) ;
2019-05-28 18:38:43 +02:00
}
2019-05-27 15:57:31 +02:00
} ) . catch ( ( ) => {
dispatch ( {
type : SYNC _APPLY _FAILED ,
data : {
error : 'Invalid password specified. Please enter the password for your previously synchronised wallet.'
}
} ) ;
} ) ;
} ;
}
function doCheckSync ( ) {
return dispatch => {
dispatch ( {
type : GET _SYNC _STARTED
} ) ;
lbryRedux . Lbry . sync _hash ( ) . then ( hash => {
Lbryio . call ( 'sync' , 'get' , {
hash
} , 'post' ) . then ( response => {
const data = {
hasSyncedWallet : true ,
syncHash : response . hash ,
2019-08-16 03:33:07 +02:00
syncData : response . data ,
hashChanged : response . changed
2019-05-27 15:57:31 +02:00
} ;
dispatch ( {
type : GET _SYNC _COMPLETED ,
data
} ) ;
} ) . catch ( ( ) => {
// user doesn't have a synced wallet
dispatch ( {
type : GET _SYNC _COMPLETED ,
data : {
hasSyncedWallet : false ,
syncHash : null
}
} ) ;
} ) ;
} ) ;
} ;
}
2019-04-18 10:02:11 +02:00
2019-04-03 23:34:07 +02:00
const reducers = { } ;
const defaultState$1 = {
authenticating : false
} ;
reducers [ GENERATE _AUTH _TOKEN _FAILURE ] = state => Object . assign ( { } , state , {
authToken : null ,
authenticating : false
} ) ;
reducers [ GENERATE _AUTH _TOKEN _STARTED ] = state => Object . assign ( { } , state , {
authenticating : true
} ) ;
reducers [ GENERATE _AUTH _TOKEN _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
authToken : action . data . authToken ,
authenticating : false
} ) ;
function authReducer ( state = defaultState$1 , action ) {
const handler = reducers [ action . type ] ;
if ( handler ) return handler ( state , action ) ;
return state ;
}
const reducers$1 = { } ;
const defaultState$2 = {
fetching : false ,
claimedRewardsById : { } ,
// id => reward
unclaimedRewards : [ ] ,
claimPendingByType : { } ,
claimErrorsByType : { } ,
rewardedContentClaimIds : [ ]
} ;
reducers$1 [ lbryRedux . ACTIONS . FETCH _REWARDS _STARTED ] = state => Object . assign ( { } , state , {
fetching : true
} ) ;
reducers$1 [ lbryRedux . ACTIONS . FETCH _REWARDS _COMPLETED ] = ( state , action ) => {
const {
userRewards
} = action . data ;
const unclaimedRewards = [ ] ;
const claimedRewards = { } ;
userRewards . forEach ( reward => {
if ( reward . transaction _id ) {
claimedRewards [ reward . id ] = reward ;
} else {
unclaimedRewards . push ( reward ) ;
}
} ) ;
return Object . assign ( { } , state , {
claimedRewardsById : claimedRewards ,
unclaimedRewards ,
fetching : false
} ) ;
} ;
function setClaimRewardState ( state , reward , isClaiming , errorMessage = '' ) {
const newClaimPendingByType = Object . assign ( { } , state . claimPendingByType ) ;
const newClaimErrorsByType = Object . assign ( { } , state . claimErrorsByType ) ; // Currently, for multiple rewards of the same type, they will both show "claiming" when one is beacuse we track this by `reward_type`
// To fix this we will need to use `claim_code` instead, and change all selectors to match
if ( isClaiming ) {
newClaimPendingByType [ reward . reward _type ] = isClaiming ;
} else {
delete newClaimPendingByType [ reward . reward _type ] ;
}
if ( errorMessage ) {
newClaimErrorsByType [ reward . reward _type ] = errorMessage ;
} else {
delete newClaimErrorsByType [ reward . reward _type ] ;
}
return Object . assign ( { } , state , {
claimPendingByType : newClaimPendingByType ,
claimErrorsByType : newClaimErrorsByType
} ) ;
}
reducers$1 [ lbryRedux . ACTIONS . CLAIM _REWARD _STARTED ] = ( state , action ) => {
const {
reward
} = action . data ;
return setClaimRewardState ( state , reward , true , '' ) ;
} ;
reducers$1 [ lbryRedux . ACTIONS . CLAIM _REWARD _SUCCESS ] = ( state , action ) => {
const {
reward
} = action . data ;
const {
unclaimedRewards
} = state ;
const index = unclaimedRewards . findIndex ( ur => ur . claim _code === reward . claim _code ) ;
unclaimedRewards . splice ( index , 1 ) ;
const {
claimedRewardsById
} = state ;
claimedRewardsById [ reward . id ] = reward ;
const newState = { ... state ,
unclaimedRewards : [ ... unclaimedRewards ] ,
claimedRewardsById : { ... claimedRewardsById
}
} ;
return setClaimRewardState ( newState , reward , false , '' ) ;
} ;
reducers$1 [ lbryRedux . ACTIONS . CLAIM _REWARD _FAILURE ] = ( state , action ) => {
const {
reward ,
error
} = action . data ;
return setClaimRewardState ( state , reward , false , error ? error . message : '' ) ;
} ;
reducers$1 [ lbryRedux . ACTIONS . CLAIM _REWARD _CLEAR _ERROR ] = ( state , action ) => {
const {
reward
} = action . data ;
return setClaimRewardState ( state , reward , state . claimPendingByType [ reward . reward _type ] , '' ) ;
} ;
reducers$1 [ lbryRedux . ACTIONS . FETCH _REWARD _CONTENT _COMPLETED ] = ( state , action ) => {
const {
claimIds
} = action . data ;
return Object . assign ( { } , state , {
rewardedContentClaimIds : claimIds
} ) ;
} ;
function rewardsReducer ( state = defaultState$2 , action ) {
const handler = reducers$1 [ action . type ] ;
if ( handler ) return handler ( state , action ) ;
return state ;
}
const reducers$2 = { } ;
const defaultState$3 = {
authenticationIsPending : false ,
userIsPending : false ,
emailNewIsPending : false ,
emailNewErrorMessage : '' ,
emailToVerify : '' ,
inviteNewErrorMessage : '' ,
inviteNewIsPending : false ,
inviteStatusIsPending : false ,
invitesRemaining : undefined ,
invitees : undefined ,
user : undefined
} ;
reducers$2 [ lbryRedux . ACTIONS . AUTHENTICATION _STARTED ] = state => Object . assign ( { } , state , {
authenticationIsPending : true ,
userIsPending : true ,
user : defaultState$3 . user
} ) ;
reducers$2 [ lbryRedux . ACTIONS . AUTHENTICATION _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
authenticationIsPending : false ,
userIsPending : false ,
user : action . data . user
} ) ;
reducers$2 [ lbryRedux . ACTIONS . AUTHENTICATION _FAILURE ] = state => Object . assign ( { } , state , {
authenticationIsPending : false ,
userIsPending : false ,
user : null
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _FETCH _STARTED ] = state => Object . assign ( { } , state , {
2019-08-14 18:08:27 +02:00
userIsPending : true
2019-04-03 23:34:07 +02:00
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _FETCH _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
userIsPending : false ,
2019-09-13 16:38:40 +02:00
user : action . data . user ,
emailToVerify : action . data . user . has _verified _email ? null : state . emailToVerify
2019-04-03 23:34:07 +02:00
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _FETCH _FAILURE ] = state => Object . assign ( { } , state , {
userIsPending : true ,
user : null
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _NEW _STARTED ] = ( state , action ) => {
const user = Object . assign ( { } , state . user ) ;
user . country _code = action . data . country _code ;
return Object . assign ( { } , state , {
phoneNewIsPending : true ,
phoneNewErrorMessage : '' ,
user
} ) ;
} ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _NEW _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
phoneToVerify : action . data . phone ,
phoneNewIsPending : false
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _RESET ] = state => Object . assign ( { } , state , {
phoneToVerify : null
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
phoneNewIsPending : false ,
phoneNewErrorMessage : action . data . error
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
phoneVerifyIsPending : true ,
phoneVerifyErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _VERIFY _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
phoneToVerify : '' ,
phoneVerifyIsPending : false ,
user : action . data . user
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _PHONE _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
phoneVerifyIsPending : false ,
phoneVerifyErrorMessage : action . data . error
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _NEW _STARTED ] = state => Object . assign ( { } , state , {
emailNewIsPending : true ,
emailNewErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _NEW _SUCCESS ] = ( state , action ) => {
const user = Object . assign ( { } , state . user ) ;
user . primary _email = action . data . email ;
return Object . assign ( { } , state , {
emailToVerify : action . data . email ,
emailNewIsPending : false ,
user
} ) ;
} ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _NEW _EXISTS ] = ( state , action ) => Object . assign ( { } , state , {
emailToVerify : action . data . email ,
emailNewIsPending : false
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
emailNewIsPending : false ,
emailNewErrorMessage : action . data . error
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
emailVerifyIsPending : true ,
emailVerifyErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _VERIFY _SUCCESS ] = ( state , action ) => {
const user = Object . assign ( { } , state . user ) ;
user . primary _email = action . data . email ;
return Object . assign ( { } , state , {
emailToVerify : '' ,
emailVerifyIsPending : false ,
user
} ) ;
} ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
emailVerifyIsPending : false ,
emailVerifyErrorMessage : action . data . error
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _EMAIL _VERIFY _SET ] = ( state , action ) => Object . assign ( { } , state , {
emailToVerify : action . data . email
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
identityVerifyIsPending : true ,
identityVerifyErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
identityVerifyIsPending : false ,
identityVerifyErrorMessage : '' ,
user : action . data . user
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _IDENTITY _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
identityVerifyIsPending : false ,
identityVerifyErrorMessage : action . data . error
} ) ;
reducers$2 [ lbryRedux . ACTIONS . FETCH _ACCESS _TOKEN _SUCCESS ] = ( state , action ) => {
const {
token
} = action . data ;
return Object . assign ( { } , state , {
accessToken : token
} ) ;
} ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _STARTED ] = state => Object . assign ( { } , state , {
inviteStatusIsPending : true
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
inviteStatusIsPending : false ,
invitesRemaining : action . data . invitesRemaining ,
invitees : action . data . invitees ,
referralLink : action . data . referralLink
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _NEW _STARTED ] = state => Object . assign ( { } , state , {
inviteNewIsPending : true ,
inviteNewErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _NEW _SUCCESS ] = state => Object . assign ( { } , state , {
inviteNewIsPending : false ,
inviteNewErrorMessage : ''
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
inviteNewIsPending : false ,
inviteNewErrorMessage : action . data . error . message
} ) ;
reducers$2 [ lbryRedux . ACTIONS . USER _INVITE _STATUS _FETCH _FAILURE ] = state => Object . assign ( { } , state , {
inviteStatusIsPending : false ,
invitesRemaining : null ,
invitees : null
} ) ;
function userReducer ( state = defaultState$3 , action ) {
const handler = reducers$2 [ action . type ] ;
if ( handler ) return handler ( state , action ) ;
return state ;
}
const defaultState$4 = {
fetching : { } ,
byUri : { }
} ;
const costInfoReducer = handleActions ( {
[ FETCH _COST _INFO _STARTED ] : ( state , action ) => {
const {
uri
} = action . data ;
const newFetching = Object . assign ( { } , state . fetching ) ;
newFetching [ uri ] = true ;
return { ... state ,
fetching : newFetching
} ;
} ,
[ FETCH _COST _INFO _COMPLETED ] : ( state , action ) => {
const {
uri ,
costInfo
} = action . data ;
const newByUri = Object . assign ( { } , state . byUri ) ;
const newFetching = Object . assign ( { } , state . fetching ) ;
newByUri [ uri ] = costInfo ;
delete newFetching [ uri ] ;
return { ... state ,
byUri : newByUri ,
fetching : newFetching
} ;
}
} , defaultState$4 ) ;
const defaultState$5 = {
fetchingBlackListedOutpoints : false ,
fetchingBlackListedOutpointsSucceed : undefined ,
blackListedOutpoints : undefined
} ;
const blacklistReducer = handleActions ( {
[ FETCH _BLACK _LISTED _CONTENT _STARTED ] : state => ( { ... state ,
fetchingBlackListedOutpoints : true
} ) ,
[ FETCH _BLACK _LISTED _CONTENT _COMPLETED ] : ( state , action ) => {
const {
outpoints ,
success
} = action . data ;
return { ... state ,
fetchingBlackListedOutpoints : false ,
fetchingBlackListedOutpointsSucceed : success ,
blackListedOutpoints : outpoints
} ;
} ,
[ FETCH _BLACK _LISTED _CONTENT _FAILED ] : ( state , action ) => {
const {
error ,
success
} = action . data ;
return { ... state ,
fetchingBlackListedOutpoints : false ,
fetchingBlackListedOutpointsSucceed : success ,
fetchingBlackListedOutpointsError : error
} ;
}
} , defaultState$5 ) ;
const defaultState$6 = {
2019-07-11 02:44:15 +02:00
loading : false ,
2019-07-09 16:20:01 +02:00
filteredOutpoints : undefined
} ;
const filteredReducer = handleActions ( {
[ FETCH _FILTERED _CONTENT _STARTED ] : state => ( { ... state ,
2019-07-11 02:44:15 +02:00
loading : true
2019-07-09 16:20:01 +02:00
} ) ,
[ FETCH _FILTERED _CONTENT _COMPLETED ] : ( state , action ) => {
const {
2019-07-11 02:44:15 +02:00
outpoints
2019-07-09 16:20:01 +02:00
} = action . data ;
return { ... state ,
2019-07-11 02:44:15 +02:00
loading : false ,
2019-07-09 16:20:01 +02:00
filteredOutpoints : outpoints
} ;
} ,
[ FETCH _FILTERED _CONTENT _FAILED ] : ( state , action ) => {
const {
2019-07-11 02:44:15 +02:00
error
2019-07-09 16:20:01 +02:00
} = action . data ;
return { ... state ,
2019-07-11 02:44:15 +02:00
loading : false ,
2019-07-09 16:20:01 +02:00
fetchingFilteredOutpointsError : error
} ;
}
} , defaultState$6 ) ;
const defaultState$7 = {
2019-04-03 23:34:07 +02:00
fetchingFeaturedContent : false ,
fetchingFeaturedContentFailed : false ,
featuredUris : undefined ,
fetchingTrendingContent : false ,
fetchingTrendingContentFailed : false ,
trendingUris : undefined
} ;
const homepageReducer = handleActions ( {
[ FETCH _FEATURED _CONTENT _STARTED ] : state => ( { ... state ,
fetchingFeaturedContent : true
} ) ,
[ FETCH _FEATURED _CONTENT _COMPLETED ] : ( state , action ) => {
const {
uris ,
success
} = action . data ;
return { ... state ,
fetchingFeaturedContent : false ,
fetchingFeaturedContentFailed : ! success ,
featuredUris : uris
} ;
} ,
[ FETCH _TRENDING _CONTENT _STARTED ] : state => ( { ... state ,
fetchingTrendingContent : true
} ) ,
[ FETCH _TRENDING _CONTENT _COMPLETED ] : ( state , action ) => {
const {
uris ,
success
} = action . data ;
return { ... state ,
fetchingTrendingContent : false ,
fetchingTrendingContentFailed : ! success ,
trendingUris : uris
} ;
}
2019-07-09 16:20:01 +02:00
} , defaultState$7 ) ;
2019-04-03 23:34:07 +02:00
2019-07-09 16:20:01 +02:00
const defaultState$8 = {
2019-04-03 23:34:07 +02:00
fetchingViewCount : false ,
viewCountError : undefined ,
viewCountById : { }
} ;
const statsReducer = handleActions ( {
[ FETCH _VIEW _COUNT _STARTED ] : state => ( { ... state ,
fetchingViewCount : true
} ) ,
[ FETCH _VIEW _COUNT _FAILED ] : ( state , action ) => ( { ... state ,
viewCountError : action . data
} ) ,
[ FETCH _VIEW _COUNT _COMPLETED ] : ( state , action ) => {
const {
claimId ,
viewCount
} = action . data ;
const viewCountById = { ... state . viewCountById ,
[ claimId ] : viewCount
} ;
return { ... state ,
fetchingViewCount : false ,
viewCountById
} ;
}
2019-07-09 16:20:01 +02:00
} , defaultState$8 ) ;
2019-04-03 23:34:07 +02:00
2019-04-18 10:02:11 +02:00
const reducers$3 = { } ;
2019-07-09 16:20:01 +02:00
const defaultState$9 = {
2019-04-18 10:02:11 +02:00
hasSyncedWallet : false ,
syncHash : null ,
2019-05-27 15:57:31 +02:00
syncData : null ,
2019-04-18 10:02:11 +02:00
setSyncErrorMessage : null ,
2019-05-27 15:57:31 +02:00
syncApplyErrorMessage : '' ,
syncApplyIsPending : false ,
getSyncIsPending : false ,
2019-08-16 03:33:07 +02:00
setSyncIsPending : false ,
hashChanged : false
2019-04-18 10:02:11 +02:00
} ;
reducers$3 [ GET _SYNC _STARTED ] = state => Object . assign ( { } , state , {
2019-05-27 15:57:31 +02:00
getSyncIsPending : true
2019-04-18 10:02:11 +02:00
} ) ;
reducers$3 [ GET _SYNC _COMPLETED ] = ( state , action ) => Object . assign ( { } , state , {
syncHash : action . data . syncHash ,
2019-05-27 15:57:31 +02:00
syncData : action . data . syncData ,
2019-04-18 10:02:11 +02:00
hasSyncedWallet : action . data . hasSyncedWallet ,
2019-08-16 03:33:07 +02:00
getSyncIsPending : false ,
hashChanged : action . data . hashChanged
2019-04-18 10:02:11 +02:00
} ) ;
reducers$3 [ SET _SYNC _STARTED ] = state => Object . assign ( { } , state , {
2019-05-27 15:57:31 +02:00
setSyncIsPending : true ,
2019-04-18 10:02:11 +02:00
setSyncErrorMessage : null
} ) ;
reducers$3 [ SET _SYNC _FAILED ] = ( state , action ) => Object . assign ( { } , state , {
2019-05-27 15:57:31 +02:00
setSyncIsPending : false ,
2019-04-18 10:02:11 +02:00
setSyncErrorMessage : action . data . error
} ) ;
reducers$3 [ SET _SYNC _COMPLETED ] = ( state , action ) => Object . assign ( { } , state , {
2019-05-27 15:57:31 +02:00
setSyncIsPending : false ,
2019-04-18 10:02:11 +02:00
setSyncErrorMessage : null ,
hasSyncedWallet : true ,
// sync was successful, so the user has a synced wallet at this point
syncHash : action . data . syncHash
} ) ;
2019-05-27 15:57:31 +02:00
reducers$3 [ SYNC _APPLY _STARTED ] = state => Object . assign ( { } , state , {
syncApplyIsPending : true ,
syncApplyErrorMessage : ''
} ) ;
reducers$3 [ SYNC _APPLY _COMPLETED ] = state => Object . assign ( { } , state , {
syncApplyIsPending : false ,
syncApplyErrorMessage : ''
} ) ;
reducers$3 [ SYNC _APPLY _FAILED ] = ( state , action ) => Object . assign ( { } , state , {
syncApplyIsPending : false ,
syncApplyErrorMessage : action . data . error
} ) ;
2019-07-09 16:20:01 +02:00
function syncReducer ( state = defaultState$9 , action ) {
2019-04-18 10:02:11 +02:00
const handler = reducers$3 [ action . type ] ;
if ( handler ) return handler ( state , action ) ;
return state ;
}
2019-04-03 23:34:07 +02:00
const selectState$3 = state => state . auth || { } ;
const selectAuthToken = reselect . createSelector ( selectState$3 , state => state . authToken ) ;
const selectIsAuthenticating = reselect . createSelector ( selectState$3 , state => state . authenticating ) ;
const selectState$4 = state => state . costInfo || { } ;
const selectAllCostInfoByUri = reselect . createSelector ( selectState$4 , state => state . byUri || { } ) ;
const makeSelectCostInfoForUri = uri => reselect . createSelector ( selectAllCostInfoByUri , costInfos => costInfos && costInfos [ uri ] ) ;
const selectFetchingCostInfo = reselect . createSelector ( selectState$4 , state => state . fetching || { } ) ;
const makeSelectFetchingCostInfoForUri = uri => reselect . createSelector ( selectFetchingCostInfo , fetchingByUri => fetchingByUri && fetchingByUri [ uri ] ) ;
const selectState$5 = state => state . blacklist || { } ;
const selectBlackListedOutpoints = reselect . createSelector ( selectState$5 , state => state . blackListedOutpoints ) ;
2019-07-09 16:20:01 +02:00
const selectState$6 = state => state . filtered || { } ;
const selectFilteredOutpoints = reselect . createSelector ( selectState$6 , state => state . filteredOutpoints ) ;
const selectState$7 = state => state . homepage || { } ;
2019-04-03 23:34:07 +02:00
2019-07-09 16:20:01 +02:00
const selectFeaturedUris = reselect . createSelector ( selectState$7 , state => state . featuredUris ) ;
const selectFetchingFeaturedUris = reselect . createSelector ( selectState$7 , state => state . fetchingFeaturedContent ) ;
const selectTrendingUris = reselect . createSelector ( selectState$7 , state => state . trendingUris ) ;
const selectFetchingTrendingUris = reselect . createSelector ( selectState$7 , state => state . fetchingTrendingContent ) ;
2019-04-03 23:34:07 +02:00
2019-07-09 16:20:01 +02:00
const selectState$8 = state => state . stats || { } ;
2019-04-03 23:34:07 +02:00
2019-07-09 16:20:01 +02:00
const selectViewCount = reselect . createSelector ( selectState$8 , state => state . viewCountById ) ;
2019-04-03 23:34:07 +02:00
const makeSelectViewCountForUri = uri => reselect . createSelector ( lbryRedux . makeSelectClaimForUri ( uri ) , selectViewCount , ( claim , viewCountById ) => viewCountById [ claim . claim _id ] || 0 ) ;
2019-07-09 16:20:01 +02:00
const selectState$9 = state => state . sync || { } ;
2019-04-18 10:02:11 +02:00
2019-07-09 16:20:01 +02:00
const selectHasSyncedWallet = reselect . createSelector ( selectState$9 , state => state . hasSyncedWallet ) ;
const selectSyncHash = reselect . createSelector ( selectState$9 , state => state . syncHash ) ;
const selectSyncData = reselect . createSelector ( selectState$9 , state => state . syncData ) ;
const selectSetSyncErrorMessage = reselect . createSelector ( selectState$9 , state => state . setSyncErrorMessage ) ;
const selectGetSyncIsPending = reselect . createSelector ( selectState$9 , state => state . getSyncIsPending ) ;
const selectSetSyncIsPending = reselect . createSelector ( selectState$9 , state => state . setSyncIsPending ) ;
2019-08-16 03:33:07 +02:00
const selectHashChanged = reselect . createSelector ( selectState$9 , state => state . hashChanged ) ;
2019-07-09 16:20:01 +02:00
const selectSyncApplyIsPending = reselect . createSelector ( selectState$9 , state => state . syncApplyIsPending ) ;
const selectSyncApplyErrorMessage = reselect . createSelector ( selectState$9 , state => state . syncApplyErrorMessage ) ;
2019-04-18 10:02:11 +02:00
2019-04-03 23:34:07 +02:00
exports . LBRYINC _ACTIONS = action _types ;
exports . Lbryio = Lbryio ;
exports . authReducer = authReducer ;
exports . blacklistReducer = blacklistReducer ;
exports . costInfoReducer = costInfoReducer ;
exports . doAuthenticate = doAuthenticate ;
exports . doBlackListedOutpointsSubscribe = doBlackListedOutpointsSubscribe ;
exports . doChannelSubscribe = doChannelSubscribe ;
exports . doChannelSubscriptionDisableNotifications = doChannelSubscriptionDisableNotifications ;
exports . doChannelSubscriptionEnableNotifications = doChannelSubscriptionEnableNotifications ;
exports . doChannelUnsubscribe = doChannelUnsubscribe ;
exports . doCheckSubscription = doCheckSubscription ;
exports . doCheckSubscriptions = doCheckSubscriptions ;
exports . doCheckSubscriptionsInit = doCheckSubscriptionsInit ;
2019-05-27 15:57:31 +02:00
exports . doCheckSync = doCheckSync ;
2019-04-03 23:34:07 +02:00
exports . doClaimEligiblePurchaseRewards = doClaimEligiblePurchaseRewards ;
exports . doClaimRewardClearError = doClaimRewardClearError ;
exports . doClaimRewardType = doClaimRewardType ;
exports . doCompleteFirstRun = doCompleteFirstRun ;
exports . doFetchAccessToken = doFetchAccessToken ;
exports . doFetchCostInfoForUri = doFetchCostInfoForUri ;
exports . doFetchFeaturedUris = doFetchFeaturedUris ;
exports . doFetchInviteStatus = doFetchInviteStatus ;
exports . doFetchMySubscriptions = doFetchMySubscriptions ;
exports . doFetchRecommendedSubscriptions = doFetchRecommendedSubscriptions ;
exports . doFetchRewardedContent = doFetchRewardedContent ;
exports . doFetchTrendingUris = doFetchTrendingUris ;
exports . doFetchViewCount = doFetchViewCount ;
2019-07-09 16:20:01 +02:00
exports . doFilteredOutpointsSubscribe = doFilteredOutpointsSubscribe ;
2019-04-03 23:34:07 +02:00
exports . doGenerateAuthToken = doGenerateAuthToken ;
2019-04-18 10:02:11 +02:00
exports . doGetSync = doGetSync ;
2019-04-03 23:34:07 +02:00
exports . doInstallNew = doInstallNew ;
exports . doRemoveUnreadSubscription = doRemoveUnreadSubscription ;
exports . doRemoveUnreadSubscriptions = doRemoveUnreadSubscriptions ;
exports . doRewardList = doRewardList ;
2019-05-10 16:45:56 +02:00
exports . doSetDefaultAccount = doSetDefaultAccount ;
2019-04-18 10:02:11 +02:00
exports . doSetSync = doSetSync ;
2019-04-03 23:34:07 +02:00
exports . doSetViewMode = doSetViewMode ;
exports . doShowSuggestedSubs = doShowSuggestedSubs ;
2019-05-27 15:57:31 +02:00
exports . doSyncApply = doSyncApply ;
2019-04-03 23:34:07 +02:00
exports . doUpdateUnreadSubscriptions = doUpdateUnreadSubscriptions ;
exports . doUserCheckEmailVerified = doUserCheckEmailVerified ;
exports . doUserEmailNew = doUserEmailNew ;
exports . doUserEmailToVerify = doUserEmailToVerify ;
exports . doUserEmailVerify = doUserEmailVerify ;
exports . doUserEmailVerifyFailure = doUserEmailVerifyFailure ;
exports . doUserFetch = doUserFetch ;
exports . doUserIdentityVerify = doUserIdentityVerify ;
exports . doUserInviteNew = doUserInviteNew ;
exports . doUserPhoneNew = doUserPhoneNew ;
exports . doUserPhoneReset = doUserPhoneReset ;
exports . doUserPhoneVerify = doUserPhoneVerify ;
exports . doUserPhoneVerifyFailure = doUserPhoneVerifyFailure ;
exports . doUserResendVerificationEmail = doUserResendVerificationEmail ;
2019-07-09 16:20:01 +02:00
exports . filteredReducer = filteredReducer ;
2019-04-03 23:34:07 +02:00
exports . homepageReducer = homepageReducer ;
exports . makeSelectClaimRewardError = makeSelectClaimRewardError ;
exports . makeSelectCostInfoForUri = makeSelectCostInfoForUri ;
exports . makeSelectFetchingCostInfoForUri = makeSelectFetchingCostInfoForUri ;
exports . makeSelectIsNew = makeSelectIsNew ;
exports . makeSelectIsRewardClaimPending = makeSelectIsRewardClaimPending ;
exports . makeSelectIsSubscribed = makeSelectIsSubscribed ;
exports . makeSelectRewardAmountByType = makeSelectRewardAmountByType ;
exports . makeSelectRewardByType = makeSelectRewardByType ;
exports . makeSelectUnreadByChannel = makeSelectUnreadByChannel ;
exports . makeSelectViewCountForUri = makeSelectViewCountForUri ;
exports . rewards = rewards ;
exports . rewardsReducer = rewardsReducer ;
exports . selectAccessToken = selectAccessToken ;
exports . selectAllCostInfoByUri = selectAllCostInfoByUri ;
exports . selectAuthToken = selectAuthToken ;
exports . selectAuthenticationIsPending = selectAuthenticationIsPending ;
exports . selectBlackListedOutpoints = selectBlackListedOutpoints ;
exports . selectClaimErrorsByType = selectClaimErrorsByType ;
exports . selectClaimedRewards = selectClaimedRewards ;
exports . selectClaimedRewardsById = selectClaimedRewardsById ;
exports . selectClaimedRewardsByTransactionId = selectClaimedRewardsByTransactionId ;
exports . selectClaimsPendingByType = selectClaimsPendingByType ;
exports . selectEmailNewErrorMessage = selectEmailNewErrorMessage ;
exports . selectEmailNewIsPending = selectEmailNewIsPending ;
exports . selectEmailToVerify = selectEmailToVerify ;
exports . selectEmailVerifyErrorMessage = selectEmailVerifyErrorMessage ;
exports . selectEmailVerifyIsPending = selectEmailVerifyIsPending ;
exports . selectEnabledChannelNotifications = selectEnabledChannelNotifications ;
exports . selectFeaturedUris = selectFeaturedUris ;
exports . selectFetchingCostInfo = selectFetchingCostInfo ;
exports . selectFetchingFeaturedUris = selectFetchingFeaturedUris ;
exports . selectFetchingRewards = selectFetchingRewards ;
exports . selectFetchingTrendingUris = selectFetchingTrendingUris ;
2019-07-09 16:20:01 +02:00
exports . selectFilteredOutpoints = selectFilteredOutpoints ;
2019-04-03 23:34:07 +02:00
exports . selectFirstRunCompleted = selectFirstRunCompleted ;
2019-05-27 15:57:31 +02:00
exports . selectGetSyncIsPending = selectGetSyncIsPending ;
2019-04-18 10:02:11 +02:00
exports . selectHasSyncedWallet = selectHasSyncedWallet ;
2019-08-16 03:33:07 +02:00
exports . selectHashChanged = selectHashChanged ;
2019-04-03 23:34:07 +02:00
exports . selectIdentityVerifyErrorMessage = selectIdentityVerifyErrorMessage ;
exports . selectIdentityVerifyIsPending = selectIdentityVerifyIsPending ;
exports . selectIsAuthenticating = selectIsAuthenticating ;
exports . selectIsFetchingSubscriptions = selectIsFetchingSubscriptions ;
exports . selectIsFetchingSuggested = selectIsFetchingSuggested ;
exports . selectPhoneNewErrorMessage = selectPhoneNewErrorMessage ;
exports . selectPhoneNewIsPending = selectPhoneNewIsPending ;
exports . selectPhoneToVerify = selectPhoneToVerify ;
exports . selectPhoneVerifyErrorMessage = selectPhoneVerifyErrorMessage ;
exports . selectPhoneVerifyIsPending = selectPhoneVerifyIsPending ;
exports . selectReferralReward = selectReferralReward ;
exports . selectRewardContentClaimIds = selectRewardContentClaimIds ;
2019-04-18 10:02:11 +02:00
exports . selectSetSyncErrorMessage = selectSetSyncErrorMessage ;
2019-05-27 15:57:31 +02:00
exports . selectSetSyncIsPending = selectSetSyncIsPending ;
2019-04-03 23:34:07 +02:00
exports . selectShowSuggestedSubs = selectShowSuggestedSubs ;
exports . selectSubscriptionClaims = selectSubscriptionClaims ;
exports . selectSubscriptions = selectSubscriptions ;
exports . selectSubscriptionsBeingFetched = selectSubscriptionsBeingFetched ;
exports . selectSuggested = selectSuggested ;
exports . selectSuggestedChannels = selectSuggestedChannels ;
2019-05-27 15:57:31 +02:00
exports . selectSyncApplyErrorMessage = selectSyncApplyErrorMessage ;
exports . selectSyncApplyIsPending = selectSyncApplyIsPending ;
exports . selectSyncData = selectSyncData ;
2019-04-18 10:02:11 +02:00
exports . selectSyncHash = selectSyncHash ;
2019-04-03 23:34:07 +02:00
exports . selectTrendingUris = selectTrendingUris ;
exports . selectUnclaimedRewardValue = selectUnclaimedRewardValue ;
exports . selectUnclaimedRewards = selectUnclaimedRewards ;
exports . selectUnclaimedRewardsByType = selectUnclaimedRewardsByType ;
exports . selectUnreadAmount = selectUnreadAmount ;
exports . selectUnreadByChannel = selectUnreadByChannel ;
exports . selectUnreadSubscriptions = selectUnreadSubscriptions ;
exports . selectUser = selectUser ;
exports . selectUserCountryCode = selectUserCountryCode ;
exports . selectUserEmail = selectUserEmail ;
exports . selectUserInviteNewErrorMessage = selectUserInviteNewErrorMessage ;
exports . selectUserInviteNewIsPending = selectUserInviteNewIsPending ;
exports . selectUserInviteReferralLink = selectUserInviteReferralLink ;
exports . selectUserInviteStatusFailed = selectUserInviteStatusFailed ;
exports . selectUserInviteStatusIsPending = selectUserInviteStatusIsPending ;
exports . selectUserInvitees = selectUserInvitees ;
exports . selectUserInvitesRemaining = selectUserInvitesRemaining ;
exports . selectUserIsPending = selectUserIsPending ;
exports . selectUserIsRewardApproved = selectUserIsRewardApproved ;
exports . selectUserIsVerificationCandidate = selectUserIsVerificationCandidate ;
exports . selectUserPhone = selectUserPhone ;
2019-09-13 16:38:40 +02:00
exports . selectUserVerifiedEmail = selectUserVerifiedEmail ;
2019-04-03 23:34:07 +02:00
exports . selectViewMode = selectViewMode ;
exports . setSubscriptionLatest = setSubscriptionLatest ;
exports . statsReducer = statsReducer ;
exports . subscriptionsReducer = subscriptions ;
2019-04-18 10:02:11 +02:00
exports . syncReducer = syncReducer ;
2019-04-03 23:34:07 +02:00
exports . userReducer = userReducer ;
2019-09-16 22:12:43 +02:00
exports . userStateSyncMiddleware = userStateSyncMiddleware ;