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' ) ;
2019-10-02 06:15:24 +02:00
// User
2019-04-03 23:34:07 +02:00
const GENERATE _AUTH _TOKEN _FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE' ;
const GENERATE _AUTH _TOKEN _STARTED = 'GENERATE_AUTH_TOKEN_STARTED' ;
2019-10-02 06:15:24 +02:00
const GENERATE _AUTH _TOKEN _SUCCESS = 'GENERATE_AUTH_TOKEN_SUCCESS' ;
const AUTHENTICATION _STARTED = 'AUTHENTICATION_STARTED' ;
const AUTHENTICATION _SUCCESS = 'AUTHENTICATION_SUCCESS' ;
const AUTHENTICATION _FAILURE = 'AUTHENTICATION_FAILURE' ;
const USER _EMAIL _DECLINE = 'USER_EMAIL_DECLINE' ;
const USER _EMAIL _NEW _STARTED = 'USER_EMAIL_NEW_STARTED' ;
const USER _EMAIL _NEW _SUCCESS = 'USER_EMAIL_NEW_SUCCESS' ;
const USER _EMAIL _NEW _EXISTS = 'USER_EMAIL_NEW_EXISTS' ;
const USER _EMAIL _NEW _FAILURE = 'USER_EMAIL_NEW_FAILURE' ;
const USER _EMAIL _VERIFY _SET = 'USER_EMAIL_VERIFY_SET' ;
const USER _EMAIL _VERIFY _STARTED = 'USER_EMAIL_VERIFY_STARTED' ;
const USER _EMAIL _VERIFY _SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS' ;
const USER _EMAIL _VERIFY _FAILURE = 'USER_EMAIL_VERIFY_FAILURE' ;
2019-10-25 20:53:13 +02:00
const USER _EMAIL _VERIFY _RETRY _STARTED = 'USER_EMAIL_VERIFY_RETRY_STARTED' ;
const USER _EMAIL _VERIFY _RETRY _FAILURE = 'USER_EMAIL_VERIFY_RETRY_FAILURE' ;
const USER _EMAIL _VERIFY _RETRY _SUCCESS = 'USER_EMAIL_VERIFY_RETRY_SUCCESS' ;
2019-10-02 06:15:24 +02:00
const USER _PHONE _RESET = 'USER_PHONE_RESET' ;
const USER _PHONE _NEW _STARTED = 'USER_PHONE_NEW_STARTED' ;
const USER _PHONE _NEW _SUCCESS = 'USER_PHONE_NEW_SUCCESS' ;
const USER _PHONE _NEW _FAILURE = 'USER_PHONE_NEW_FAILURE' ;
const USER _PHONE _VERIFY _STARTED = 'USER_PHONE_VERIFY_STARTED' ;
const USER _PHONE _VERIFY _SUCCESS = 'USER_PHONE_VERIFY_SUCCESS' ;
const USER _PHONE _VERIFY _FAILURE = 'USER_PHONE_VERIFY_FAILURE' ;
const USER _IDENTITY _VERIFY _STARTED = 'USER_IDENTITY_VERIFY_STARTED' ;
const USER _IDENTITY _VERIFY _SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS' ;
const USER _IDENTITY _VERIFY _FAILURE = 'USER_IDENTITY_VERIFY_FAILURE' ;
const USER _FETCH _STARTED = 'USER_FETCH_STARTED' ;
const USER _FETCH _SUCCESS = 'USER_FETCH_SUCCESS' ;
const USER _FETCH _FAILURE = 'USER_FETCH_FAILURE' ;
const USER _INVITE _STATUS _FETCH _STARTED = 'USER_INVITE_STATUS_FETCH_STARTED' ;
const USER _INVITE _STATUS _FETCH _SUCCESS = 'USER_INVITE_STATUS_FETCH_SUCCESS' ;
const USER _INVITE _STATUS _FETCH _FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE' ;
const USER _INVITE _NEW _STARTED = 'USER_INVITE_NEW_STARTED' ;
const USER _INVITE _NEW _SUCCESS = 'USER_INVITE_NEW_SUCCESS' ;
const USER _INVITE _NEW _FAILURE = 'USER_INVITE_NEW_FAILURE' ;
const FETCH _ACCESS _TOKEN _SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS' ;
const USER _YOUTUBE _IMPORT _STARTED = 'USER_YOUTUBE_IMPORT_STARTED' ;
const USER _YOUTUBE _IMPORT _FAILURE = 'USER_YOUTUBE_IMPORT_FAILURE' ;
2020-01-08 22:58:07 +01:00
const USER _YOUTUBE _IMPORT _SUCCESS = 'USER_YOUTUBE_IMPORT_SUCCESS' ;
const USER _SET _REFERRER _STARTED = 'USER_SET_REFERRER_STARTED' ;
const USER _SET _REFERRER _SUCCESS = 'USER_SET_REFERRER_SUCCESS' ;
const USER _SET _REFERRER _FAILURE = 'USER_SET_REFERRER_FAILURE' ; // Claims
2019-04-03 23:34:07 +02:00
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' ;
2019-09-25 04:30:53 +02:00
const FETCH _COST _INFO _COMPLETED = 'FETCH_COST_INFO_COMPLETED' ; // Stats
2019-04-03 23:34:07 +02:00
const FETCH _VIEW _COUNT _STARTED = 'FETCH_VIEW_COUNT_STARTED' ;
const FETCH _VIEW _COUNT _FAILED = 'FETCH_VIEW_COUNT_FAILED' ;
2019-09-25 04:30:53 +02:00
const FETCH _VIEW _COUNT _COMPLETED = 'FETCH_VIEW_COUNT_COMPLETED' ;
const FETCH _SUB _COUNT _STARTED = 'FETCH_SUB_COUNT_STARTED' ;
const FETCH _SUB _COUNT _FAILED = 'FETCH_SUB_COUNT_FAILED' ;
const FETCH _SUB _COUNT _COMPLETED = 'FETCH_SUB_COUNT_COMPLETED' ; // Cross-device Sync
2019-04-18 10:02:11 +02:00
const GET _SYNC _STARTED = 'GET_SYNC_STARTED' ;
const GET _SYNC _COMPLETED = 'GET_SYNC_COMPLETED' ;
2019-10-02 06:15:24 +02:00
const GET _SYNC _FAILED = 'GET_SYNC_FAILED' ;
2019-04-18 10:02:11 +02:00
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-10-29 20:14:41 +01:00
const SYNC _APPLY _BAD _PASSWORD = 'SYNC_APPLY_BAD_PASSWORD' ;
2019-10-22 21:21:42 +02:00
const SYNC _RESET = 'SYNC_RESET' ; // Lbry.tv
const UPDATE _UPLOAD _PROGRESS = 'UPDATE_UPLOAD_PROGRESS' ;
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 ,
2019-10-02 06:15:24 +02:00
AUTHENTICATION _STARTED : AUTHENTICATION _STARTED ,
AUTHENTICATION _SUCCESS : AUTHENTICATION _SUCCESS ,
AUTHENTICATION _FAILURE : AUTHENTICATION _FAILURE ,
USER _EMAIL _DECLINE : USER _EMAIL _DECLINE ,
USER _EMAIL _NEW _STARTED : USER _EMAIL _NEW _STARTED ,
USER _EMAIL _NEW _SUCCESS : USER _EMAIL _NEW _SUCCESS ,
USER _EMAIL _NEW _EXISTS : USER _EMAIL _NEW _EXISTS ,
USER _EMAIL _NEW _FAILURE : USER _EMAIL _NEW _FAILURE ,
USER _EMAIL _VERIFY _SET : USER _EMAIL _VERIFY _SET ,
USER _EMAIL _VERIFY _STARTED : USER _EMAIL _VERIFY _STARTED ,
USER _EMAIL _VERIFY _SUCCESS : USER _EMAIL _VERIFY _SUCCESS ,
USER _EMAIL _VERIFY _FAILURE : USER _EMAIL _VERIFY _FAILURE ,
2019-10-25 20:53:13 +02:00
USER _EMAIL _VERIFY _RETRY _STARTED : USER _EMAIL _VERIFY _RETRY _STARTED ,
USER _EMAIL _VERIFY _RETRY _FAILURE : USER _EMAIL _VERIFY _RETRY _FAILURE ,
USER _EMAIL _VERIFY _RETRY _SUCCESS : USER _EMAIL _VERIFY _RETRY _SUCCESS ,
2019-10-02 06:15:24 +02:00
USER _PHONE _RESET : USER _PHONE _RESET ,
USER _PHONE _NEW _STARTED : USER _PHONE _NEW _STARTED ,
USER _PHONE _NEW _SUCCESS : USER _PHONE _NEW _SUCCESS ,
USER _PHONE _NEW _FAILURE : USER _PHONE _NEW _FAILURE ,
USER _PHONE _VERIFY _STARTED : USER _PHONE _VERIFY _STARTED ,
USER _PHONE _VERIFY _SUCCESS : USER _PHONE _VERIFY _SUCCESS ,
USER _PHONE _VERIFY _FAILURE : USER _PHONE _VERIFY _FAILURE ,
USER _IDENTITY _VERIFY _STARTED : USER _IDENTITY _VERIFY _STARTED ,
USER _IDENTITY _VERIFY _SUCCESS : USER _IDENTITY _VERIFY _SUCCESS ,
USER _IDENTITY _VERIFY _FAILURE : USER _IDENTITY _VERIFY _FAILURE ,
USER _FETCH _STARTED : USER _FETCH _STARTED ,
USER _FETCH _SUCCESS : USER _FETCH _SUCCESS ,
USER _FETCH _FAILURE : USER _FETCH _FAILURE ,
USER _INVITE _STATUS _FETCH _STARTED : USER _INVITE _STATUS _FETCH _STARTED ,
USER _INVITE _STATUS _FETCH _SUCCESS : USER _INVITE _STATUS _FETCH _SUCCESS ,
USER _INVITE _STATUS _FETCH _FAILURE : USER _INVITE _STATUS _FETCH _FAILURE ,
USER _INVITE _NEW _STARTED : USER _INVITE _NEW _STARTED ,
USER _INVITE _NEW _SUCCESS : USER _INVITE _NEW _SUCCESS ,
USER _INVITE _NEW _FAILURE : USER _INVITE _NEW _FAILURE ,
FETCH _ACCESS _TOKEN _SUCCESS : FETCH _ACCESS _TOKEN _SUCCESS ,
USER _YOUTUBE _IMPORT _STARTED : USER _YOUTUBE _IMPORT _STARTED ,
USER _YOUTUBE _IMPORT _FAILURE : USER _YOUTUBE _IMPORT _FAILURE ,
USER _YOUTUBE _IMPORT _SUCCESS : USER _YOUTUBE _IMPORT _SUCCESS ,
2020-01-08 22:58:07 +01:00
USER _SET _REFERRER _STARTED : USER _SET _REFERRER _STARTED ,
USER _SET _REFERRER _SUCCESS : USER _SET _REFERRER _SUCCESS ,
USER _SET _REFERRER _FAILURE : USER _SET _REFERRER _FAILURE ,
2019-04-03 23:34:07 +02:00
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 ,
2019-09-25 04:30:53 +02:00
FETCH _SUB _COUNT _STARTED : FETCH _SUB _COUNT _STARTED ,
FETCH _SUB _COUNT _FAILED : FETCH _SUB _COUNT _FAILED ,
FETCH _SUB _COUNT _COMPLETED : FETCH _SUB _COUNT _COMPLETED ,
2019-04-18 10:02:11 +02:00
GET _SYNC _STARTED : GET _SYNC _STARTED ,
GET _SYNC _COMPLETED : GET _SYNC _COMPLETED ,
2019-10-02 06:15:24 +02:00
GET _SYNC _FAILED : GET _SYNC _FAILED ,
2019-04-18 10:02:11 +02:00
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-10-02 22:22:51 +02:00
SYNC _APPLY _FAILED : SYNC _APPLY _FAILED ,
2019-10-29 20:14:41 +01:00
SYNC _APPLY _BAD _PASSWORD : SYNC _APPLY _BAD _PASSWORD ,
2019-10-22 21:21:42 +02:00
SYNC _RESET : SYNC _RESET ,
UPDATE _UPLOAD _PROGRESS : UPDATE _UPLOAD _PROGRESS
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
const NOT _TRANSFERRED = 'not_transferred' ;
const PENDING _TRANSFER = 'pending_transfer' ;
const COMPLETED _TRANSFER = 'completed_transfer' ;
var youtube = /*#__PURE__*/ Object . freeze ( {
NOT _TRANSFERRED : NOT _TRANSFERRED ,
PENDING _TRANSFER : PENDING _TRANSFER ,
COMPLETED _TRANSFER : COMPLETED _TRANSFER
} ) ;
2020-01-10 04:28:46 +01:00
const ALREADY _CLAIMED = 'once the invite reward has been claimed the referrer cannot be changed' ;
const REFERRER _NOT _FOUND = 'A lbry.tv account could not be found for the referrer you provided.' ;
var errors = /*#__PURE__*/ Object . freeze ( {
ALREADY _CLAIMED : ALREADY _CLAIMED ,
REFERRER _NOT _FOUND : REFERRER _NOT _FOUND
} ) ;
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 _REFERRAL = 'referral' ;
2020-01-08 22:58:07 +01:00
rewards . TYPE _REFEREE = 'referee' ;
2019-04-03 23:34:07 +02:00
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 ;
}
2020-01-03 20:20:14 +01:00
Lbryio . call ( 'reward' , 'claim' , params , 'post' ) . then ( reward => {
2019-04-03 23:34:07 +02:00
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-11-12 18:42:04 +01:00
lbryRedux . Lbry . channel _list ( {
page : 1 ,
page _size : 10
} ) . then ( claims => {
const claim = claims . items && claims . items . find ( foundClaim => foundClaim . name . length && foundClaim . name [ 0 ] === '@' && foundClaim . txid . length && foundClaim . type === 'claim' ) ;
2019-04-03 23:34:07 +02:00
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-11-12 18:42:04 +01:00
lbryRedux . Lbry . stream _list ( {
page : 1 ,
page _size : 10
} ) . then ( claims => {
const claim = claims . items && claims . items . find ( foundClaim => foundClaim . name . length && foundClaim . name [ 0 ] !== '@' && foundClaim . txid . length && foundClaim . type === 'claim' ) ;
2019-04-03 23:34:07 +02:00
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 : [ ] ,
2019-09-30 18:24:24 +02:00
latest : { } ,
2019-04-03 23:34:07 +02:00
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 ( ) ;
2020-01-10 04:28:46 +01:00
if ( ! newSubscriptions . some ( sub => sub . uri === newSubscription . uri ) ) {
newSubscriptions . unshift ( newSubscription ) ;
}
2019-04-03 23:34:07 +02:00
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
} ;
} ,
2019-09-30 18:24:24 +02:00
[ SET _SUBSCRIPTION _LATEST ] : ( state , action ) => {
const {
subscription ,
uri
} = action . data ;
const newLatest = Object . assign ( { } , state . latest ) ;
newLatest [ subscription . uri ] = uri ;
return { ... state ,
latest : newLatest
} ;
} ,
2019-04-03 23:34:07 +02:00
[ 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
2019-09-23 10:35:27 +02:00
} ) ,
[ lbryRedux . ACTIONS . USER _STATE _POPULATE ] : ( state , action ) => {
const {
subscriptions
} = action . data ;
let newSubscriptions ;
if ( ! subscriptions ) {
newSubscriptions = state . subscriptions ;
} else {
const parsedSubscriptions = subscriptions . map ( uri => {
const {
channelName
} = lbryRedux . parseURI ( uri ) ;
return {
uri ,
channelName : ` @ ${ channelName } `
} ;
} ) ;
if ( ! state . subscriptions || ! state . subscriptions . length ) {
newSubscriptions = parsedSubscriptions ;
} else {
const map = { } ;
newSubscriptions = parsedSubscriptions . concat ( state . subscriptions ) . filter ( sub => {
return map [ sub . uri ] ? false : map [ sub . uri ] = true ;
} , { } ) ;
}
}
return { ... state ,
subscriptions : newSubscriptions
} ;
}
2019-04-03 23:34:07 +02:00
} , 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-12-05 13:13:10 +01:00
const apiBaseUrl = 'https://www.transifex.com/api/2/project' ;
const resource = 'app-strings' ;
function doTransifexUpload ( contents , project , token , success , fail ) {
const url = ` ${ apiBaseUrl } / ${ project } /resources/ ` ;
const updateUrl = ` ${ apiBaseUrl } / ${ project } /resource/ ${ resource } /content/ ` ;
const headers = {
Authorization : ` Basic ${ Buffer . from ( ` api: ${ token } ` ) . toString ( 'base64' ) } ` ,
'Content-Type' : 'application/json'
} ;
const req = {
accept _translations : true ,
i18n _type : 'KEYVALUEJSON' ,
name : resource ,
slug : resource ,
content : contents
} ;
function handleResponse ( text ) {
let json ;
try {
// transifex api returns Python dicts for some reason.
// Any way to get the api to return valid JSON?
json = JSON . parse ( text ) ;
} catch ( e ) { // ignore
}
if ( success ) {
success ( json || text ) ;
}
}
function handleError ( err ) {
if ( fail ) {
fail ( err . message ? err . message : 'Could not upload strings resource to Transifex' ) ;
}
} // check if the resource exists
fetch ( updateUrl , {
headers
} ) . then ( response => response . json ( ) ) . then ( ( ) => {
// perform an update
fetch ( updateUrl , {
method : 'PUT' ,
headers ,
body : JSON . stringify ( {
content : contents
} )
} ) . then ( response => {
if ( response . status !== 200 && response . status !== 201 ) {
throw new Error ( 'failed to update transifex' ) ;
}
return response . text ( ) ;
} ) . then ( handleResponse ) . catch ( handleError ) ;
} ) . catch ( ( ) => {
// resource doesn't exist, create a fresh resource
fetch ( url , {
method : 'POST' ,
headers ,
body : JSON . stringify ( req )
} ) . then ( response => {
if ( response . status !== 200 && response . status !== 201 ) {
throw new Error ( 'failed to upload to transifex' ) ;
}
return response . text ( ) ;
} ) . then ( handleResponse ) . catch ( handleError ) ;
} ) ;
}
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-10-25 20:53:13 +02:00
const selectEmailAlreadyExists = reselect . createSelector ( selectState$2 , state => state . emailAlreadyExists ) ;
const selectResendingVerificationEmail = reselect . createSelector ( selectState$2 , state => state . resendingVerificationEmail ) ;
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-09-13 02:57:10 +02:00
const selectYoutubeChannels = reselect . createSelector ( selectUser , user => user ? user . youtube _channels : null ) ;
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 ) ;
2020-01-10 04:28:46 +01:00
const selectUserInviteReferralCode = reselect . createSelector ( selectState$2 , state => state . referralCode ? state . referralCode [ 0 ] : '' ) ;
2019-10-02 06:15:24 +02:00
const selectYouTubeImportPending = reselect . createSelector ( selectState$2 , state => state . youtubeChannelImportPending ) ;
const selectYouTubeImportError = reselect . createSelector ( selectState$2 , state => state . youtubeChannelImportErrorMessage ) ;
2020-01-10 04:44:03 +01:00
const selectSetReferrerPending = reselect . createSelector ( selectState$2 , state => state . referrerSetIsPending ) ;
const selectSetReferrerError = reselect . createSelector ( selectState$2 , state => state . referrerSetError ) ;
2019-10-02 06:15:24 +02:00
const selectYouTubeImportVideosComplete = reselect . createSelector ( selectState$2 , state => {
const total = state . youtubeChannelImportTotal ;
const complete = state . youtubeChannelImportComplete || 0 ;
if ( total ) {
return [ complete , total ] ;
}
} ) ;
2019-04-03 23:34:07 +02:00
function doFetchInviteStatus ( ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _STATUS _FETCH _STARTED
2019-04-03 23:34:07 +02:00
} ) ;
Promise . all ( [ Lbryio . call ( 'user' , 'invite_status' ) , Lbryio . call ( 'user_referral_code' , 'list' ) ] ) . then ( ( [ status , code ] ) => {
dispatch ( doRewardList ( ) ) ;
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _STATUS _FETCH _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
invitesRemaining : status . invites _remaining ? status . invites _remaining : 0 ,
invitees : status . invitees ,
2020-01-08 22:58:07 +01:00
referralLink : ` ${ Lbryio . CONNECTION _STRING } user/refer?r= ${ code } ` ,
referralCode : code
2019-04-03 23:34:07 +02:00
}
} ) ;
} ) . catch ( error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _STATUS _FETCH _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ) ;
} ) ;
} ;
}
2019-10-15 11:21:08 +02:00
function doInstallNew ( appVersion , os = null , firebaseToken = null ) {
2019-04-03 23:34:07 +02:00
const payload = {
app _version : appVersion
} ;
2019-10-15 11:21:08 +02:00
if ( firebaseToken ) {
payload . firebase _token = firebaseToken ;
}
2019-04-03 23:34:07 +02:00
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?
2019-10-15 11:21:08 +02:00
function doAuthenticate ( appVersion , os = null , firebaseToken = null ) {
2019-04-03 23:34:07 +02:00
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : AUTHENTICATION _STARTED
2019-04-03 23:34:07 +02:00
} ) ;
2020-01-14 21:40:07 +01:00
Lbryio . authenticate ( ) . then ( user => {
Lbryio . getAuthToken ( ) . then ( token => {
dispatch ( {
type : AUTHENTICATION _SUCCESS ,
data : {
user ,
accessToken : token
}
} ) ;
dispatch ( doRewardList ( ) ) ;
dispatch ( doFetchInviteStatus ( ) ) ;
doInstallNew ( appVersion , os , firebaseToken ) ;
2019-04-03 23:34:07 +02:00
} ) ;
} ) . catch ( error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : AUTHENTICATION _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ) ;
} ) ;
} ;
}
function doUserFetch ( ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _FETCH _STARTED
2019-04-03 23:34:07 +02:00
} ) ;
Lbryio . getCurrentUser ( ) . then ( user => {
dispatch ( doRewardList ( ) ) ;
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _FETCH _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
user
}
} ) ;
} ) . catch ( error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _FETCH _FAILURE ,
2019-04-03 23:34:07 +02:00
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 ( {
2019-10-02 06:15:24 +02:00
type : USER _FETCH _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
user
}
} ) ;
}
} ) ;
} ;
}
function doUserPhoneReset ( ) {
return {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _RESET
2019-04-03 23:34:07 +02:00
} ;
}
function doUserPhoneNew ( phone , countryCode ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _NEW _STARTED ,
2019-04-03 23:34:07 +02:00
data : {
phone ,
country _code : countryCode
}
} ) ;
const success = ( ) => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _NEW _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
phone
}
} ) ;
} ;
const failure = error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _NEW _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ) ;
} ;
Lbryio . call ( 'user' , 'phone_number_new' , {
phone _number : phone ,
country _code : countryCode
} , 'post' ) . then ( success , failure ) ;
} ;
}
function doUserPhoneVerifyFailure ( error ) {
return {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _VERIFY _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ;
}
function doUserPhoneVerify ( verificationCode ) {
return ( dispatch , getState ) => {
const phoneNumber = selectPhoneToVerify ( getState ( ) ) ;
const countryCode = selectUserCountryCode ( getState ( ) ) ;
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _VERIFY _STARTED ,
2019-04-03 23:34:07 +02:00
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 ( {
2019-10-02 06:15:24 +02:00
type : USER _PHONE _VERIFY _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
user
}
} ) ;
dispatch ( doClaimRewardType ( rewards . TYPE _NEW _USER ) ) ;
}
} ) . catch ( error => dispatch ( doUserPhoneVerifyFailure ( error ) ) ) ;
} ;
}
function doUserEmailToVerify ( email ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _VERIFY _SET ,
2019-04-03 23:34:07 +02:00
data : {
email
}
} ) ;
} ;
}
function doUserEmailNew ( email ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _NEW _STARTED ,
2019-04-03 23:34:07 +02:00
email
} ) ;
const success = ( ) => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _NEW _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
email
}
} ) ;
dispatch ( doUserFetch ( ) ) ;
} ;
const failure = error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _NEW _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ) ;
} ;
Lbryio . call ( 'user_email' , 'new' , {
email ,
send _verification _email : true
} , 'post' ) . catch ( error => {
if ( error . response && error . response . status === 409 ) {
2019-10-25 20:53:13 +02:00
dispatch ( {
type : USER _EMAIL _NEW _EXISTS
} ) ;
2019-04-03 23:34:07 +02:00
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 ( {
2019-10-25 20:53:13 +02:00
type : USER _EMAIL _VERIFY _RETRY _STARTED
2019-04-03 23:34:07 +02:00
} ) ;
const success = ( ) => {
dispatch ( {
2019-10-25 20:53:13 +02:00
type : USER _EMAIL _VERIFY _RETRY _SUCCESS
2019-04-03 23:34:07 +02:00
} ) ;
} ;
const failure = error => {
dispatch ( {
2019-10-25 20:53:13 +02:00
type : USER _EMAIL _VERIFY _RETRY _FAILURE ,
2019-04-03 23:34:07 +02:00
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 {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _VERIFY _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ;
}
function doUserEmailVerify ( verificationToken , recaptcha ) {
return ( dispatch , getState ) => {
const email = selectEmailToVerify ( getState ( ) ) ;
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _VERIFY _STARTED ,
2019-04-03 23:34:07 +02:00
code : verificationToken ,
recaptcha
} ) ;
Lbryio . call ( 'user_email' , 'confirm' , {
verification _token : verificationToken ,
email ,
recaptcha
} , 'post' ) . then ( userEmail => {
if ( userEmail . is _verified ) {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _EMAIL _VERIFY _SUCCESS ,
2019-04-03 23:34:07 +02:00
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 ( {
2019-10-02 06:15:24 +02:00
type : FETCH _ACCESS _TOKEN _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
token
}
} ) ;
Lbryio . getAuthToken ( ) . then ( success ) ;
} ;
}
function doUserIdentityVerify ( stripeToken ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _IDENTITY _VERIFY _STARTED ,
2019-04-03 23:34:07 +02:00
token : stripeToken
} ) ;
Lbryio . call ( 'user' , 'verify_identity' , {
stripe _token : stripeToken
} , 'post' ) . then ( user => {
if ( user . is _identity _verified ) {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _IDENTITY _VERIFY _SUCCESS ,
2019-04-03 23:34:07 +02:00
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 ( {
2019-10-02 06:15:24 +02:00
type : USER _IDENTITY _VERIFY _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error : error . toString ( )
}
} ) ;
} ) ;
} ;
}
function doUserInviteNew ( email ) {
return dispatch => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _NEW _STARTED
2019-04-03 23:34:07 +02:00
} ) ;
2020-01-08 22:58:07 +01:00
return Lbryio . call ( 'user' , 'invite' , {
2019-04-03 23:34:07 +02:00
email
2020-01-08 22:58:07 +01:00
} , 'post' ) . then ( success => {
2019-04-03 23:34:07 +02:00
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _NEW _SUCCESS ,
2019-04-03 23:34:07 +02:00
data : {
email
}
} ) ;
dispatch ( lbryRedux . doToast ( {
2019-10-26 22:56:01 +02:00
message : _ _ ( ` Invite sent to ${ email } ` )
2019-04-03 23:34:07 +02:00
} ) ) ;
dispatch ( doFetchInviteStatus ( ) ) ;
2020-01-08 22:58:07 +01:00
return success ;
2019-04-03 23:34:07 +02:00
} ) . catch ( error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _INVITE _NEW _FAILURE ,
2019-04-03 23:34:07 +02:00
data : {
error
}
} ) ;
} ) ;
} ;
}
2020-01-08 22:58:07 +01:00
function doUserSetReferrer ( referrer , shouldClaim ) {
2020-01-10 04:28:46 +01:00
return async ( dispatch , getState ) => {
2020-01-08 22:58:07 +01:00
dispatch ( {
type : USER _SET _REFERRER _STARTED
} ) ;
2020-01-10 04:28:46 +01:00
let claim ;
let referrerCode = referrer ;
const isClaim = lbryRedux . parseURI ( referrer ) . claimId ;
if ( isClaim ) {
const uri = ` lbry:// ${ referrer } ` ;
claim = lbryRedux . makeSelectClaimForUri ( uri ) ( getState ( ) ) ;
if ( ! claim ) {
try {
const response = await lbryRedux . Lbry . resolve ( {
urls : [ uri ]
} ) ;
claim = response && response [ uri ] ;
} catch ( error ) {
dispatch ( {
type : USER _SET _REFERRER _FAILURE ,
data : {
error
}
} ) ;
}
}
referrerCode = claim && claim . permanent _url . replace ( 'lbry://' , '' ) ;
}
try {
await Lbryio . call ( 'user' , 'referral' , {
referrer : referrerCode
} , 'post' ) ;
2020-01-08 22:58:07 +01:00
dispatch ( {
type : USER _SET _REFERRER _SUCCESS
2020-01-10 04:28:46 +01:00
} ) ;
2020-01-08 22:58:07 +01:00
if ( shouldClaim ) {
dispatch ( doClaimRewardType ( rewards . TYPE _REFEREE ) ) ;
dispatch ( doUserFetch ( ) ) ;
} else {
dispatch ( doUserFetch ( ) ) ;
}
2020-01-10 04:28:46 +01:00
} catch ( error ) {
2020-01-08 22:58:07 +01:00
dispatch ( {
type : USER _SET _REFERRER _FAILURE ,
data : {
error
}
} ) ;
2020-01-10 04:28:46 +01:00
}
2020-01-08 22:58:07 +01:00
} ;
}
2019-09-16 21:10:48 +02:00
function doClaimYoutubeChannels ( ) {
return dispatch => {
2019-09-17 23:01:10 +02:00
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _YOUTUBE _IMPORT _STARTED
2019-09-17 23:01:10 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
let transferResponse ;
2019-11-05 00:32:32 +01:00
return lbryRedux . Lbry . address _list ( {
page : 1 ,
page _size : 99999
} ) . then ( addressList => addressList . items . sort ( ( a , b ) => a . used _times - b . used _times ) [ 0 ] ) . then ( address => Lbryio . call ( 'yt' , 'transfer' , {
2019-09-17 23:01:10 +02:00
address : address . address ,
2019-09-23 15:07:43 +02:00
public _key : address . pubkey
2019-09-16 21:10:48 +02:00
} ) . then ( response => {
2019-10-02 06:15:24 +02:00
if ( response && response . length ) {
transferResponse = response ;
return Promise . all ( response . map ( channelMeta => {
2019-09-23 15:07:43 +02:00
if ( channelMeta && channelMeta . channel && channelMeta . channel . channel _certificate ) {
2019-09-16 21:10:48 +02:00
return lbryRedux . Lbry . channel _import ( {
channel _data : channelMeta . channel . channel _certificate
} ) ;
}
return null ;
2019-09-17 23:01:10 +02:00
} ) ) . then ( ( ) => {
const actions = [ {
2019-10-02 06:15:24 +02:00
type : USER _YOUTUBE _IMPORT _SUCCESS ,
data : transferResponse
2019-09-17 23:01:10 +02:00
} ] ;
actions . push ( doUserFetch ( ) ) ;
actions . push ( lbryRedux . doFetchChannelListMine ( ) ) ;
dispatch ( lbryRedux . batchActions ( ... actions ) ) ;
} ) ;
2019-09-16 21:10:48 +02:00
}
2019-09-17 23:01:10 +02:00
} ) ) . catch ( error => {
dispatch ( {
2019-10-02 06:15:24 +02:00
type : USER _YOUTUBE _IMPORT _FAILURE ,
data : String ( error )
} ) ;
} ) ;
} ;
}
function doCheckYoutubeTransfer ( ) {
return dispatch => {
dispatch ( {
type : USER _YOUTUBE _IMPORT _STARTED
} ) ;
return Lbryio . call ( 'yt' , 'transfer' ) . then ( response => {
if ( response && response . length ) {
dispatch ( {
type : USER _YOUTUBE _IMPORT _SUCCESS ,
data : response
} ) ;
} else {
throw new Error ( ) ;
}
} ) . catch ( error => {
dispatch ( {
type : USER _YOUTUBE _IMPORT _FAILURE ,
2019-09-17 23:01:10 +02:00
data : String ( error )
} ) ;
} ) ;
2019-09-16 21:10:48 +02:00
} ;
}
2019-04-03 23:34:07 +02:00
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-19 19:03:42 +02:00
if ( rewardType !== rewards . TYPE _REWARD _CODE || rewardType !== rewards . TYPE _CONFIRM _EMAIL || rewardType !== rewards . TYPE _DAILY _VIEW ) {
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 => {
2019-10-03 19:14:17 +02:00
// Temporary timeout to ensure the sdk has the correct balance after claiming a reward
setTimeout ( ( ) => {
dispatch ( lbryRedux . doUpdateBalance ( ) ) . then ( ( ) => {
dispatch ( {
type : lbryRedux . ACTIONS . CLAIM _REWARD _SUCCESS ,
data : {
reward : successReward
}
} ) ;
2019-04-03 23:34:07 +02:00
2019-10-03 19:14:17 +02:00
if ( successReward . reward _type === rewards . TYPE _NEW _USER && rewards . callbacks . claimFirstRewardSuccess ) {
rewards . callbacks . claimFirstRewardSuccess ( ) ;
} else if ( successReward . reward _type === rewards . TYPE _REFERRAL ) {
dispatch ( doFetchInviteStatus ( ) ) ;
}
2019-04-03 23:34:07 +02:00
2019-10-03 19:14:17 +02:00
dispatch ( doRewardList ( ) ) ;
2019-09-13 16:38:40 +02:00
2019-10-03 19:14:17 +02:00
if ( options . callback ) {
options . callback ( ) ;
}
} ) ;
2019-10-11 18:36:35 +02:00
} , 2000 ) ;
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
} ;
2019-10-02 22:22:51 +02:00
return rewards . claimReward ( rewardType , params ) . then ( success , failure ) ;
2019-04-03 23:34:07 +02:00
} ;
}
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-10-02 19:30:55 +02:00
[ rewards . TYPE _MANY _DOWNLOADS , 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 ) ;
2019-09-30 18:24:24 +02:00
const subscriptionLatest = state . subscriptions . latest [ subscriptionUri ] ;
2019-04-03 23:34:07 +02:00
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-09-30 18:24:24 +02:00
const latestIndex = claimsInChannel . findIndex ( claim => claim . permanent _url === subscriptionLatest ) ; // 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
2019-09-30 18:24:24 +02:00
if ( latestIndex !== 0 && subscriptionLatest ) {
2019-04-03 23:34:07 +02:00
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
} ) => {
2020-01-03 20:06:35 +01:00
const splitOutpoints = [ ] ;
if ( outpoints ) {
outpoints . forEach ( ( outpoint , index ) => {
const [ txid , nout ] = outpoint . split ( ':' ) ;
splitOutpoints [ index ] = {
txid ,
nout : Number . parseInt ( nout , 10 )
} ;
} ) ;
}
2019-04-03 23:34:07 +02:00
dispatch ( {
type : FETCH _BLACK _LISTED _CONTENT _COMPLETED ,
data : {
2020-01-03 20:06:35 +01:00
outpoints : splitOutpoints ,
2019-04-03 23:34:07 +02:00
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
} ) => {
2020-01-03 20:06:35 +01:00
let formattedOutpoints = [ ] ;
if ( outpoints ) {
formattedOutpoints = outpoints . map ( outpoint => {
const [ txid , nout ] = outpoint . split ( ':' ) ;
return {
txid ,
nout : Number . parseInt ( nout , 10 )
} ;
} ) ;
}
2019-07-09 16:20:01 +02:00
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-09-25 04:30:53 +02:00
const doFetchSubCount = claimId => dispatch => {
dispatch ( {
type : FETCH _SUB _COUNT _STARTED
} ) ;
return Lbryio . call ( 'subscription' , 'sub_count' , {
claim _id : claimId
} ) . then ( result => {
const subCount = result [ 0 ] ;
dispatch ( {
type : FETCH _SUB _COUNT _COMPLETED ,
data : {
claimId ,
subCount
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : FETCH _SUB _COUNT _FAILED ,
data : error
} ) ;
} ) ;
} ;
2019-04-03 23:34:07 +02:00
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-10-02 06:15:24 +02:00
} else if ( failure ) {
2019-09-06 17:19:17 +02:00
// no default account to set
2019-10-02 06:15:24 +02:00
failure ( 'Could not set a default account' ) ; // fail
2019-09-06 17:19:17 +02:00
}
} ) . catch ( err => {
if ( failure ) {
failure ( err ) ;
2019-05-10 16:45:56 +02:00
}
} ) ;
} ;
}
2019-10-04 18:52:28 +02:00
function doSetSync ( oldHash , newHash , data ) {
2019-10-02 06:15:24 +02:00
return dispatch => {
dispatch ( {
type : SET _SYNC _STARTED
} ) ;
2019-10-04 18:52:28 +02:00
return Lbryio . call ( 'sync' , 'set' , {
2019-10-02 06:15:24 +02:00
old _hash : oldHash ,
new _hash : newHash ,
data
} , 'post' ) . then ( response => {
if ( ! response . hash ) {
2019-10-04 18:52:28 +02:00
throw Error ( 'No hash returned for sync/set.' ) ;
2019-10-02 06:15:24 +02:00
}
return dispatch ( {
type : SET _SYNC _COMPLETED ,
data : {
syncHash : response . hash
}
} ) ;
} ) . catch ( error => {
dispatch ( {
type : SET _SYNC _FAILED ,
data : {
error
}
} ) ;
} ) ;
} ;
}
2019-10-15 05:21:17 +02:00
function doGetSync ( passedPassword , callback ) {
const password = passedPassword === null || passedPassword === undefined ? '' : passedPassword ;
2020-01-03 21:30:56 +01:00
function handleCallback ( error ) {
2019-10-15 05:07:41 +02:00
if ( callback ) {
if ( typeof callback !== 'function' ) {
throw new Error ( 'Second argument passed to "doGetSync" must be a function' ) ;
}
2020-01-03 21:30:56 +01:00
callback ( error ) ;
2019-10-15 05:07:41 +02:00
}
}
2019-04-18 10:02:11 +02:00
return dispatch => {
dispatch ( {
type : GET _SYNC _STARTED
} ) ;
2019-10-02 06:15:24 +02:00
const data = { } ;
2019-10-16 05:35:03 +02:00
lbryRedux . Lbry . wallet _status ( ) . then ( status => {
if ( status . is _locked ) {
return lbryRedux . Lbry . wallet _unlock ( {
password
} ) ;
}
} ) . then ( ( ) => lbryRedux . Lbry . sync _hash ( ) ) . then ( hash => Lbryio . call ( 'sync' , 'get' , {
hash
} , 'post' ) ) . then ( response => {
const syncHash = response . hash ;
data . syncHash = syncHash ;
data . syncData = response . data ;
data . hasSyncedWallet = true ;
if ( response . changed ) {
return lbryRedux . Lbry . sync _apply ( {
password ,
2020-01-07 23:01:26 +01:00
data : response . data ,
blocking : true
2019-10-16 05:35:03 +02:00
} ) ;
}
} ) . then ( response => {
if ( ! response ) {
dispatch ( {
type : GET _SYNC _COMPLETED ,
data
} ) ;
handleCallback ( ) ;
return ;
}
2019-10-02 06:15:24 +02:00
2019-10-16 05:35:03 +02:00
const {
hash : walletHash ,
data : walletData
} = response ;
if ( walletHash !== data . syncHash ) {
// different local hash, need to synchronise
dispatch ( doSetSync ( data . syncHash , walletHash , walletData ) ) ;
}
dispatch ( {
type : GET _SYNC _COMPLETED ,
data
2019-04-18 10:02:11 +02:00
} ) ;
2019-10-16 05:35:03 +02:00
handleCallback ( ) ;
2019-10-21 18:35:52 +02:00
} ) . catch ( ( ) => {
2019-10-16 05:35:03 +02:00
if ( data . hasSyncedWallet ) {
const error = 'Error getting synced wallet' ;
dispatch ( {
type : GET _SYNC _FAILED ,
data : {
error
}
2019-10-29 20:14:41 +01:00
} ) ; // Temp solution until we have a bad password error code
// Don't fail on blank passwords so we don't show a "password error" message
// before users have ever entered a password
if ( password !== '' ) {
dispatch ( {
type : SYNC _APPLY _BAD _PASSWORD
} ) ;
}
2019-10-16 05:35:03 +02:00
handleCallback ( error ) ;
} else {
// 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 : syncApplyData
} ) => {
dispatch ( doSetSync ( '' , walletHash , syncApplyData , password ) ) ;
handleCallback ( ) ;
2019-10-21 17:56:19 +02:00
} ) . catch ( error => {
handleCallback ( error ) ;
2019-10-16 05:35:03 +02:00
} ) ;
}
2019-04-18 10:02:11 +02:00
} ) ;
} ;
}
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-10-02 22:22:51 +02:00
function doResetSync ( ) {
return dispatch => new Promise ( resolve => {
dispatch ( {
type : SYNC _RESET
} ) ;
resolve ( ) ;
} ) ;
}
2019-10-17 06:00:43 +02:00
function doSyncEncryptAndDecrypt ( oldPassword , newPassword , encrypt ) {
2019-10-17 01:28:02 +02:00
return dispatch => {
2019-10-21 18:35:52 +02:00
const data = { } ;
return lbryRedux . Lbry . sync _hash ( ) . then ( hash => Lbryio . call ( 'sync' , 'get' , {
hash
} , 'post' ) ) . then ( syncGetResponse => {
2019-10-17 01:28:02 +02:00
data . oldHash = syncGetResponse . hash ;
return lbryRedux . Lbry . sync _apply ( {
password : oldPassword ,
data : syncGetResponse . data
} ) ;
2019-10-17 06:00:43 +02:00
} ) . then ( ( ) => {
if ( encrypt ) {
dispatch ( lbryRedux . doWalletEncrypt ( newPassword ) ) ;
} else {
dispatch ( lbryRedux . doWalletDecrypt ( ) ) ;
}
2019-10-17 01:28:02 +02:00
} ) . then ( ( ) => lbryRedux . Lbry . sync _apply ( {
password : newPassword
} ) ) . then ( syncApplyResponse => {
if ( syncApplyResponse . hash !== data . oldHash ) {
return dispatch ( doSetSync ( data . oldHash , syncApplyResponse . hash , syncApplyResponse . data ) ) ;
}
} ) . catch ( console . error ) ;
} ;
}
2019-04-18 10:02:11 +02:00
2019-10-22 21:21:42 +02:00
//
const doUpdateUploadProgress = ( progress , params , xhr ) => dispatch => dispatch ( {
type : UPDATE _UPLOAD _PROGRESS ,
data : {
progress ,
params ,
xhr
}
} ) ;
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 : '' ,
2019-10-25 20:53:13 +02:00
emailAlreadyExists : false ,
resendingVerificationEmail : false ,
2019-04-03 23:34:07 +02:00
inviteNewErrorMessage : '' ,
inviteNewIsPending : false ,
inviteStatusIsPending : false ,
invitesRemaining : undefined ,
invitees : undefined ,
2020-01-08 22:58:07 +01:00
referralLink : undefined ,
referralCode : undefined ,
2019-09-17 23:01:10 +02:00
user : undefined ,
2020-01-08 22:58:07 +01:00
accessToken : undefined ,
2019-10-02 06:15:24 +02:00
youtubeChannelImportPending : false ,
2020-01-08 22:58:07 +01:00
youtubeChannelImportErrorMessage : '' ,
2020-01-10 04:44:03 +01:00
referrerSetIsPending : false ,
referrerSetError : ''
2019-04-03 23:34:07 +02:00
} ;
2019-10-02 06:15:24 +02:00
reducers$2 [ AUTHENTICATION _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
authenticationIsPending : true ,
userIsPending : true ,
2020-01-08 22:58:07 +01:00
accessToken : defaultState$3 . accessToken
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ AUTHENTICATION _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
authenticationIsPending : false ,
userIsPending : false ,
2020-01-14 21:40:07 +01:00
accessToken : action . data . accessToken ,
user : action . data . user
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ AUTHENTICATION _FAILURE ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
authenticationIsPending : false ,
userIsPending : false ,
user : null
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ 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
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _FETCH _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
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
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _FETCH _FAILURE ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
userIsPending : true ,
user : null
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _NEW _STARTED ] = ( state , action ) => {
2019-04-03 23:34:07 +02:00
const user = Object . assign ( { } , state . user ) ;
user . country _code = action . data . country _code ;
return Object . assign ( { } , state , {
phoneNewIsPending : true ,
phoneNewErrorMessage : '' ,
user
} ) ;
} ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _NEW _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneToVerify : action . data . phone ,
phoneNewIsPending : false
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _RESET ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneToVerify : null
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneNewIsPending : false ,
phoneNewErrorMessage : action . data . error
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneVerifyIsPending : true ,
phoneVerifyErrorMessage : ''
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _VERIFY _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneToVerify : '' ,
phoneVerifyIsPending : false ,
user : action . data . user
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _PHONE _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
phoneVerifyIsPending : false ,
phoneVerifyErrorMessage : action . data . error
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _NEW _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
emailNewIsPending : true ,
2019-10-25 20:53:13 +02:00
emailNewErrorMessage : '' ,
emailAlreadyExists : false
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _NEW _SUCCESS ] = ( state , action ) => {
2019-04-03 23:34:07 +02:00
const user = Object . assign ( { } , state . user ) ;
user . primary _email = action . data . email ;
return Object . assign ( { } , state , {
emailToVerify : action . data . email ,
emailNewIsPending : false ,
user
} ) ;
} ;
2019-10-25 20:53:13 +02:00
reducers$2 [ USER _EMAIL _NEW _EXISTS ] = state => Object . assign ( { } , state , {
emailAlreadyExists : true
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
emailNewIsPending : false ,
emailNewErrorMessage : action . data . error
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
emailVerifyIsPending : true ,
emailVerifyErrorMessage : ''
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _VERIFY _SUCCESS ] = ( state , action ) => {
2019-04-03 23:34:07 +02:00
const user = Object . assign ( { } , state . user ) ;
user . primary _email = action . data . email ;
return Object . assign ( { } , state , {
emailToVerify : '' ,
emailVerifyIsPending : false ,
user
} ) ;
} ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
emailVerifyIsPending : false ,
emailVerifyErrorMessage : action . data . error
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _EMAIL _VERIFY _SET ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
emailToVerify : action . data . email
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _IDENTITY _VERIFY _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
identityVerifyIsPending : true ,
identityVerifyErrorMessage : ''
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _IDENTITY _VERIFY _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
identityVerifyIsPending : false ,
identityVerifyErrorMessage : '' ,
user : action . data . user
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _IDENTITY _VERIFY _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
identityVerifyIsPending : false ,
identityVerifyErrorMessage : action . data . error
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ FETCH _ACCESS _TOKEN _SUCCESS ] = ( state , action ) => {
2019-04-03 23:34:07 +02:00
const {
token
} = action . data ;
return Object . assign ( { } , state , {
accessToken : token
} ) ;
} ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _STATUS _FETCH _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteStatusIsPending : true
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _STATUS _FETCH _SUCCESS ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteStatusIsPending : false ,
invitesRemaining : action . data . invitesRemaining ,
invitees : action . data . invitees ,
2020-01-08 22:58:07 +01:00
referralLink : action . data . referralLink ,
referralCode : action . data . referralCode
2019-04-03 23:34:07 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _NEW _STARTED ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteNewIsPending : true ,
inviteNewErrorMessage : ''
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _NEW _SUCCESS ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteNewIsPending : false ,
inviteNewErrorMessage : ''
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _NEW _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteNewIsPending : false ,
inviteNewErrorMessage : action . data . error . message
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _INVITE _STATUS _FETCH _FAILURE ] = state => Object . assign ( { } , state , {
2019-04-03 23:34:07 +02:00
inviteStatusIsPending : false ,
invitesRemaining : null ,
invitees : null
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _YOUTUBE _IMPORT _STARTED ] = state => Object . assign ( { } , state , {
youtubeChannelImportPending : true ,
youtubeChannelImportErrorMessage : ''
2019-09-17 23:01:10 +02:00
} ) ;
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _YOUTUBE _IMPORT _SUCCESS ] = ( state , action ) => {
const total = action . data . reduce ( ( acc , value ) => acc + value . total _published _videos , 0 ) ;
const complete = action . data . reduce ( ( acc , value ) => acc + value . total _transferred , 0 ) ;
return Object . assign ( { } , state , {
youtubeChannelImportPending : false ,
youtubeChannelImportErrorMessage : '' ,
youtubeChannelImportTotal : total ,
youtubeChannelImportComplete : complete
} ) ;
} ;
2019-09-17 23:01:10 +02:00
2019-10-02 06:15:24 +02:00
reducers$2 [ USER _YOUTUBE _IMPORT _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
youtubeChannelImportPending : false ,
youtubeChannelImportErrorMessage : action . data
2019-09-17 23:01:10 +02:00
} ) ;
2019-10-25 20:53:13 +02:00
reducers$2 [ USER _EMAIL _VERIFY _RETRY _STARTED ] = state => Object . assign ( { } , state , {
resendingVerificationEmail : true
} ) ;
reducers$2 [ USER _EMAIL _VERIFY _RETRY _SUCCESS ] = state => Object . assign ( { } , state , {
resendingVerificationEmail : false
} ) ;
reducers$2 [ USER _EMAIL _VERIFY _RETRY _FAILURE ] = state => Object . assign ( { } , state , {
resendingVerificationEmail : false
} ) ;
2020-01-08 22:58:07 +01:00
reducers$2 [ USER _SET _REFERRER _STARTED ] = state => Object . assign ( { } , state , {
2020-01-10 04:44:03 +01:00
referrerSetIsPending : true ,
referrerSetError : defaultState$3 . referrerSetError
2020-01-08 22:58:07 +01:00
} ) ;
reducers$2 [ USER _SET _REFERRER _SUCCESS ] = state => Object . assign ( { } , state , {
2020-01-10 04:44:03 +01:00
referrerSetIsPending : false ,
referrerSetError : defaultState$3 . referrerSetError
2020-01-08 22:58:07 +01:00
} ) ;
reducers$2 [ USER _SET _REFERRER _FAILURE ] = ( state , action ) => Object . assign ( { } , state , {
2020-01-10 04:44:03 +01:00
referrerSetIsPending : false ,
referrerSetError : action . data . error . message
2020-01-08 22:58:07 +01:00
} ) ;
2019-04-03 23:34:07 +02:00
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 ,
2019-09-25 04:30:53 +02:00
viewCountById : { } ,
fetchingSubCount : false ,
subCountError : undefined ,
subCountById : { }
2019-04-03 23:34:07 +02:00
} ;
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-09-25 04:30:53 +02:00
} ,
[ FETCH _SUB _COUNT _STARTED ] : state => ( { ... state ,
fetchingSubCount : true
} ) ,
[ FETCH _SUB _COUNT _FAILED ] : ( state , action ) => ( { ... state ,
subCountError : action . data
} ) ,
[ FETCH _SUB _COUNT _COMPLETED ] : ( state , action ) => {
const {
claimId ,
subCount
} = action . data ;
const subCountById = { ... state . subCountById ,
[ claimId ] : subCount
} ;
return { ... state ,
fetchingSubCount : false ,
subCountById
} ;
2019-04-03 23:34:07 +02:00
}
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-10-02 06:15:24 +02:00
getSyncErrorMessage : null ,
2019-05-27 15:57:31 +02:00
syncApplyErrorMessage : '' ,
syncApplyIsPending : false ,
2019-10-29 20:14:41 +01:00
syncApplyPasswordError : false ,
2019-05-27 15:57:31 +02:00
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-10-02 06:15:24 +02:00
getSyncIsPending : true ,
getSyncErrorMessage : null
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
} ) ;
2019-10-02 06:15:24 +02:00
reducers$3 [ GET _SYNC _FAILED ] = ( state , action ) => Object . assign ( { } , state , {
getSyncIsPending : false ,
getSyncErrorMessage : action . data . error
} ) ;
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 , {
2019-10-29 20:14:41 +01:00
syncApplyPasswordError : false ,
2019-05-27 15:57:31 +02:00
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-10-29 20:14:41 +01:00
reducers$3 [ SYNC _APPLY _BAD _PASSWORD ] = state => Object . assign ( { } , state , {
syncApplyPasswordError : true
} ) ;
2019-10-02 22:22:51 +02:00
reducers$3 [ SYNC _RESET ] = ( ) => defaultState$9 ;
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-10-22 21:21:42 +02:00
//
/ *
test mock :
currentUploads : {
'test#upload' : {
progress : 50 ,
params : {
name : 'steve' ,
thumbnail _url : 'https://dev2.spee.ch/4/KMNtoSZ009fawGz59VG8PrID.jpeg' ,
} ,
} ,
} ,
* /
const reducers$4 = { } ;
const defaultState$a = {
currentUploads : { }
} ;
reducers$4 [ UPDATE _UPLOAD _PROGRESS ] = ( state , action ) => {
const {
progress ,
params ,
xhr
} = action . data ;
const key = params . channel ? ` ${ params . name } # ${ params . channel } ` : ` ${ params . name } #anonymous ` ;
let currentUploads ;
if ( ! progress ) {
currentUploads = Object . assign ( { } , state . currentUploads ) ;
Object . keys ( currentUploads ) . forEach ( k => {
if ( k === key ) {
delete currentUploads [ key ] ;
}
} ) ;
} else {
currentUploads = Object . assign ( { } , state . currentUploads ) ;
currentUploads [ key ] = {
progress ,
params ,
xhr
} ;
}
return { ... state ,
currentUploads
} ;
} ;
function lbrytvReducer ( state = defaultState$a , action ) {
const handler = reducers$4 [ 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-09-25 04:30:53 +02:00
const selectSubCount = reselect . createSelector ( selectState$8 , state => state . subCountById ) ;
2019-12-20 08:45:03 +01:00
const makeSelectViewCountForUri = uri => reselect . createSelector ( lbryRedux . makeSelectClaimForUri ( uri ) , selectViewCount , ( claim , viewCountById ) => claim ? viewCountById [ claim . claim _id ] || 0 : 0 ) ;
const makeSelectSubCountForUri = uri => reselect . createSelector ( lbryRedux . makeSelectClaimForUri ( uri ) , selectSubCount , ( claim , subCountById ) => claim ? subCountById [ claim . claim _id ] || 0 : 0 ) ;
2019-04-03 23:34:07 +02:00
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 ) ;
2019-10-02 06:15:24 +02:00
const selectGetSyncErrorMessage = reselect . createSelector ( selectState$9 , state => state . getSyncErrorMessage ) ;
2019-07-09 16:20:01 +02:00
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-10-29 20:14:41 +01:00
const selectSyncApplyPasswordError = reselect . createSelector ( selectState$9 , state => state . syncApplyPasswordError ) ;
2019-04-18 10:02:11 +02:00
2019-10-22 21:21:42 +02:00
const selectState$a = state => state . lbrytv || { } ;
const selectCurrentUploads = reselect . createSelector ( selectState$a , state => state . currentUploads ) ;
const selectUploadCount = reselect . createSelector ( selectCurrentUploads , currentUploads => currentUploads && Object . keys ( currentUploads ) . length ) ;
2020-01-10 04:28:46 +01:00
exports . ERRORS = errors ;
2019-04-03 23:34:07 +02:00
exports . LBRYINC _ACTIONS = action _types ;
exports . Lbryio = Lbryio ;
2019-10-02 06:15:24 +02:00
exports . YOUTUBE _STATUSES = youtube ;
2019-04-03 23:34:07 +02:00
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-10-02 06:15:24 +02:00
exports . doCheckYoutubeTransfer = doCheckYoutubeTransfer ;
2019-04-03 23:34:07 +02:00
exports . doClaimEligiblePurchaseRewards = doClaimEligiblePurchaseRewards ;
exports . doClaimRewardClearError = doClaimRewardClearError ;
exports . doClaimRewardType = doClaimRewardType ;
2019-09-16 21:10:48 +02:00
exports . doClaimYoutubeChannels = doClaimYoutubeChannels ;
2019-04-03 23:34:07 +02:00
exports . doCompleteFirstRun = doCompleteFirstRun ;
exports . doFetchAccessToken = doFetchAccessToken ;
exports . doFetchCostInfoForUri = doFetchCostInfoForUri ;
exports . doFetchFeaturedUris = doFetchFeaturedUris ;
exports . doFetchInviteStatus = doFetchInviteStatus ;
exports . doFetchMySubscriptions = doFetchMySubscriptions ;
exports . doFetchRecommendedSubscriptions = doFetchRecommendedSubscriptions ;
exports . doFetchRewardedContent = doFetchRewardedContent ;
2019-09-25 04:30:53 +02:00
exports . doFetchSubCount = doFetchSubCount ;
2019-04-03 23:34:07 +02:00
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 ;
2019-10-02 22:22:51 +02:00
exports . doResetSync = doResetSync ;
2019-04-03 23:34:07 +02:00
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-10-17 06:00:43 +02:00
exports . doSyncEncryptAndDecrypt = doSyncEncryptAndDecrypt ;
2019-12-05 13:13:10 +01:00
exports . doTransifexUpload = doTransifexUpload ;
2019-04-03 23:34:07 +02:00
exports . doUpdateUnreadSubscriptions = doUpdateUnreadSubscriptions ;
2019-10-22 21:21:42 +02:00
exports . doUpdateUploadProgress = doUpdateUploadProgress ;
2019-04-03 23:34:07 +02:00
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 ;
2020-01-08 22:58:07 +01:00
exports . doUserSetReferrer = doUserSetReferrer ;
2019-07-09 16:20:01 +02:00
exports . filteredReducer = filteredReducer ;
2019-04-03 23:34:07 +02:00
exports . homepageReducer = homepageReducer ;
2019-10-22 21:21:42 +02:00
exports . lbrytvReducer = lbrytvReducer ;
2019-04-03 23:34:07 +02:00
exports . makeSelectClaimRewardError = makeSelectClaimRewardError ;
exports . makeSelectCostInfoForUri = makeSelectCostInfoForUri ;
exports . makeSelectFetchingCostInfoForUri = makeSelectFetchingCostInfoForUri ;
exports . makeSelectIsNew = makeSelectIsNew ;
exports . makeSelectIsRewardClaimPending = makeSelectIsRewardClaimPending ;
exports . makeSelectIsSubscribed = makeSelectIsSubscribed ;
exports . makeSelectRewardAmountByType = makeSelectRewardAmountByType ;
exports . makeSelectRewardByType = makeSelectRewardByType ;
2019-09-25 04:30:53 +02:00
exports . makeSelectSubCountForUri = makeSelectSubCountForUri ;
2019-04-03 23:34:07 +02:00
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 ;
2019-10-22 21:21:42 +02:00
exports . selectCurrentUploads = selectCurrentUploads ;
2019-10-25 20:53:13 +02:00
exports . selectEmailAlreadyExists = selectEmailAlreadyExists ;
2019-04-03 23:34:07 +02:00
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-10-02 06:15:24 +02:00
exports . selectGetSyncErrorMessage = selectGetSyncErrorMessage ;
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 ;
2019-10-25 20:53:13 +02:00
exports . selectResendingVerificationEmail = selectResendingVerificationEmail ;
2019-04-03 23:34:07 +02:00
exports . selectRewardContentClaimIds = selectRewardContentClaimIds ;
2020-01-08 22:58:07 +01:00
exports . selectSetReferrerError = selectSetReferrerError ;
exports . selectSetReferrerPending = selectSetReferrerPending ;
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 ;
2019-10-29 20:14:41 +01:00
exports . selectSyncApplyPasswordError = selectSyncApplyPasswordError ;
2019-05-27 15:57:31 +02:00
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 ;
2019-10-22 21:21:42 +02:00
exports . selectUploadCount = selectUploadCount ;
2019-04-03 23:34:07 +02:00
exports . selectUser = selectUser ;
exports . selectUserCountryCode = selectUserCountryCode ;
exports . selectUserEmail = selectUserEmail ;
exports . selectUserInviteNewErrorMessage = selectUserInviteNewErrorMessage ;
exports . selectUserInviteNewIsPending = selectUserInviteNewIsPending ;
2020-01-08 22:58:07 +01:00
exports . selectUserInviteReferralCode = selectUserInviteReferralCode ;
2019-04-03 23:34:07 +02:00
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 ;
2019-10-02 06:15:24 +02:00
exports . selectYouTubeImportError = selectYouTubeImportError ;
exports . selectYouTubeImportPending = selectYouTubeImportPending ;
exports . selectYouTubeImportVideosComplete = selectYouTubeImportVideosComplete ;
2019-09-13 02:57:10 +02:00
exports . selectYoutubeChannels = selectYoutubeChannels ;
2019-04-03 23:34:07 +02:00
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 ;