Compare commits

...
Sign in to create a new pull request.

275 commits

Author SHA1 Message Date
infiinte-persistence
0b4e41ef90
doFetchViewCount: support multiple claimIds
## Issue
Show content view counts on channel pages (https://github.com/lbryio/lbry-desktop/issues/3587)

## Changes
Updated the action and reducer to handle CSV input. This wouldn't affect existing clients as it is backward compatible with a single claimId.

In the unlikely event that requested count !== results count, we just fail silently for now.
2021-09-09 13:41:56 +08:00
mayeaux
6fa738e3b8 Update README.md 2021-06-14 11:12:17 -04:00
Thomas Zarebczan
8f9a58bfc8
Merge pull request from lbryio/ip/blacklist-build
Update build for blacklist speed-up
2021-04-15 01:23:37 -04:00
infiinte-persistence
560b97e9a5
Update build for blacklist speed-up 2021-04-15 11:00:51 +08:00
Sean Yesmunt
c0cadee18d
Merge pull request from lbryio/fix-blacklistMap
fix blacklist performance
2021-04-14 12:59:34 -04:00
zeppi
f5a0df82fc fix blacklist performance 2021-04-14 12:53:13 -04:00
Sean Yesmunt
7faea40d87 update build 2021-03-09 16:46:23 -05:00
Sean Yesmunt
767ffe90b0
Update youtube.js 2021-03-09 16:45:57 -05:00
Sean Yesmunt
eee2cb730e
Merge pull request from lbryio/feat-authTakesLanguage
auth takes language for user new
2020-11-13 13:23:25 -05:00
jessop
57b8625454 auth takes language for user new 2020-11-12 14:27:58 -05:00
Sean Yesmunt
2a9d04b2ef omit auth_token for file/list_filtered and file/list_blocked 2020-11-11 15:13:02 -05:00
Sean Yesmunt
9371b3181f
Merge pull request from lbryio/fix-domainAppid
pass domain into appid for user new
2020-11-10 10:23:47 -05:00
jessop
904e630d43 pass domain into appid for user new 2020-11-09 14:56:56 -05:00
Sean Yesmunt
801f159059 remove unused type 2020-11-09 13:29:05 -05:00
Sean Yesmunt
9bdf18eef6 remove extra type 2020-10-30 15:57:13 -04:00
Sean Yesmunt
d913ca0344 remove old subscription types 2020-10-30 15:53:57 -04:00
Sean Yesmunt
517c28a183 only call sync_apply if sync_get fails with 'no wallet found for this user' 2020-10-23 21:15:58 -04:00
Sean Yesmunt
d91b971bfe update build 2020-10-23 20:50:10 -04:00
Sean Yesmunt
1b6f280371 don't call user/new if user/me returns 500 2020-10-23 20:49:37 -04:00
Sean Yesmunt
316e42f7b7 Revert "remove sync code from 'lbryinc'"
This reverts commit 886f5f8f70.
2020-10-23 20:49:02 -04:00
Sean Yesmunt
886f5f8f70 remove sync code from 'lbryinc' 2020-10-01 12:25:36 -04:00
Sean Yesmunt
db0663fcc4
Merge pull request from lbryio/sync-password-error
propagate sync password error
2020-09-21 12:57:48 -04:00
Sean Yesmunt
c78d416e16 Revert "remove app_id on user/new call"
This reverts commit 478b428a0f.
2020-09-21 12:57:03 -04:00
jessop
4834749423 propagate sync password error 2020-09-18 13:09:50 -04:00
Sean Yesmunt
478b428a0f remove app_id on user/new call 2020-09-16 13:13:36 -04:00
Sean Yesmunt
9440717a00
Merge pull request from lbryio/doAuth-changes
doAuth changes
2020-09-09 10:39:38 -04:00
jessop
35df87d1e6 doAuth changes 2020-09-07 08:52:35 -04:00
Sean Yesmunt
c8f3fe0511 fix typo 2020-09-03 14:10:11 -04:00
Sean Yesmunt
1404901313 add youtube sync constants 2020-09-01 13:30:56 -04:00
Sean Yesmunt
b96561477a
Merge pull request from lbryio/fix-filterMapSelectors
bugfix
2020-08-18 10:20:54 -04:00
jessop
6217edccf7 bugfix 2020-08-17 15:54:03 -04:00
Sean Yesmunt
c1a08e2e97
Merge pull request from lbryio/feat-filteredSelectors
selectors for blocklist objects
2020-08-14 13:20:23 -04:00
jessop
63acb48182 selectors for blocklist objects 2020-08-13 13:53:49 -04:00
Sean Yesmunt
cff5dd6093 delete old flow type 2020-07-07 16:41:18 -04:00
Sean Yesmunt
9a9bc951db remove old flow type 2020-06-30 01:58:36 -04:00
Sean Yesmunt
0f6fd2c338
Merge pull request from lbryio/remove-user-and-rewards
remove user/rewards code from lbryinc so they can be added to the desktop repo
2020-06-29 15:07:36 -04:00
Sean Yesmunt
72eee35f51 remove user/rewards code from lbryinc so they can be added to the desktop repo 2020-06-15 16:29:48 -04:00
jessopb
3ceb09549c
Merge pull request from lbryio/install_id
customize web install_/app_ids for domains
2020-06-11 13:23:40 -04:00
jessop
41e94d4ce8 customize web app_ids for domains 2020-06-10 11:11:28 -04:00
jessopb
ca5984cd79
Merge pull request from lbryio/feat-installNewDomain
add domain to install new
2020-06-05 10:11:28 -04:00
jessop
9c4f620ec0 add domain to install new 2020-06-03 20:13:32 -04:00
Sean Yesmunt
c21bc3075c fix build 2020-06-02 10:32:11 -04:00
Sean Yesmunt
cb8ffc86a4 decouple doUserFetch and doRewardList 2020-06-02 10:12:20 -04:00
Sean Yesmunt
13068eca5c
Merge pull request from lbryio/country
add country to User and create doUserSetCountry
2020-06-01 13:03:52 -04:00
Sean Yesmunt
0529fb4635 add country to User and create doUserSetCountry 2020-06-01 12:27:07 -04:00
Sean Yesmunt
39510e8b21 remove address sort for youtube transfer so it doesn't accidentally grab the wrong address 2020-05-29 11:15:16 -04:00
Sean Yesmunt
9c2939ab37
Merge pull request from lbryio/renameTvToWeb 2020-05-26 10:41:21 -04:00
jessop
8bdf1ac44d rename lbrytv to web 2020-05-23 13:56:29 -04:00
Sean Yesmunt
6a52f8026c
Merge pull request from lbryio/reward-fix 2020-05-20 11:53:55 -04:00
Sean Yesmunt
132455395e fix for rewards 2020-05-20 11:52:59 -04:00
Sean Yesmunt
efde3e6914 fix typo 2020-05-20 11:12:46 -04:00
Sean Yesmunt
31c51b804f add paid_content reward type 2020-05-20 11:01:36 -04:00
Sean Yesmunt
cc62a4eec1 allow users to signin after they abandoned a previous signup 2020-04-23 14:14:43 -04:00
Sean Yesmunt
edd43c8dff add latest_claimed_email to User 2020-04-20 16:45:21 -04:00
Sean Yesmunt
43fadef68d
Merge pull request from lbryio/signup
trigger signup email if user doesn't have a password
2020-04-16 10:54:03 -04:00
Sean Yesmunt
7b1973dbad trigger signup email if user doesn't have a password 2020-04-16 10:52:52 -04:00
Sean Yesmunt
11ebc51ab6 add promise to userSignUp 2020-04-15 12:07:43 -04:00
Sean Yesmunt
12aefaa143
Merge pull request from lbryio/fixes
password sign in cleanup
2020-04-13 13:45:01 -04:00
Sean Yesmunt
deb0303f62 password sign in cleanup 2020-04-13 13:43:15 -04:00
Sean Yesmunt
75f992ef02
Merge pull request from lbryio/passwords
password support
2020-04-13 11:06:43 -04:00
Sean Yesmunt
b411291da7 new signin/signup methods with password support 2020-04-13 09:40:25 -04:00
Sean Yesmunt
0addc624db
Merge pull request from lbryio/window
check if window exists before using
2020-04-08 12:49:35 -04:00
Sean Yesmunt
546ecd1f77 check if window exists before using 2020-04-08 12:17:40 -04:00
Thomas Zarebczan
19260fac56
fix: claim code from params 2020-03-27 17:13:21 -04:00
Sean Yesmunt
e75f009af4
Merge pull request from lbryio/add-claim-code
add claim code selector
2020-03-26 15:19:06 -04:00
Thomas Zarebczan
402a9a199f
add claim code selector
fix export
2020-03-26 14:50:21 -04:00
Akinwale Ariwodola
e2bba80797 new_android reward 2020-03-24 10:31:58 -04:00
Sean Yesmunt
9259233c6f
Merge pull request from lbryio/changed-callback
include if sync data has changed in response callback
2020-03-19 13:50:37 -04:00
seanyesmunt
49eb8a4df3 include if sync data has changed in response callback 2020-03-19 13:49:47 -04:00
Akinwale Ariwodola
54906cb768
add flag for dispatching doInstallNew from doAuthenticate ()
* add doInstallNewWithParams action
* return dispatch for doInstallNewWithParams
2020-03-19 08:55:45 +01:00
Sean Yesmunt
f82ef0e5cc
Merge pull request from lbryio/status-callback
add callback param for doAuthenticate that returns the status
2020-03-16 18:01:03 -04:00
seanyesmunt
a53cffb0d8 update variable name 2020-03-16 18:00:46 -04:00
Sean Yesmunt
b27a99aaa3 add callback param for doAuthenticate that returns the status 2020-03-12 12:19:42 -04:00
Sean Yesmunt
275f35b31e
Merge pull request from lbryio/stop-install-new
allow preventing lbryinc calls on authenticate
2020-02-24 12:06:29 -05:00
Sean Yesmunt
3fc6530531 allow preventing lbryinc calls on authenticate 2020-02-24 12:02:43 -05:00
Jeremy Kauffman
0dc8829a31
Merge pull request from ykris45/patch-1
Update LICENSE
2020-02-03 15:00:26 -05:00
YULIUS KURNIAWAN KRISTIANTO
7813853736
Update LICENSE 2020-02-03 04:38:56 +07:00
Sean Yesmunt
1932c30a36
trigger sync error correctly with locked wallets ()
trigger sync error correctly with locked wallets
2020-01-28 12:31:39 -05:00
Sean Yesmunt
6a59102c52 trigger sync error correctly with locked wallets 2020-01-23 17:11:07 -05:00
Thomas Zarebczan
138a053754 fix: referral name 2020-01-18 15:56:35 -05:00
Sean Yesmunt
bd48a138c9
improves ux around referrals ()
improves ux around referrals
2020-01-17 11:21:51 -05:00
jessop
1b19fdf56a improve referral ux
provide for resetting setReferrerErrors
fix bugs in referrer resolve logic
2020-01-16 20:59:47 -05:00
Jeremy Kauffman
866a80a552
Merge pull request from lbryio/user-fix
add back user to state when calling doAuthenticate
2020-01-15 10:34:11 -05:00
Sean Yesmunt
1912aa1834 add back user to state when calling doAuthenticate 2020-01-14 15:40:07 -05:00
jessopb
e3520f5216
Merge pull request from lbryio/new_referrals
new referrals
2020-01-14 14:47:42 -05:00
jessop
e7e800b2d2 remove setReferrer Toast 2020-01-10 17:56:47 -05:00
jessop
018d149fb4 rename setReferrerPending and Error 2020-01-09 22:44:03 -05:00
jessop
54ca3fa8a7 referral improvements:
resolve canonical urls before claiming
some error handling
bugfixes
2020-01-09 22:28:46 -05:00
jessop
81dd94572d new referrals
provides referral code
setting referrers
claim referee reward
fixes accessToken state
2020-01-08 16:58:07 -05:00
jessopb
174465878b
Merge pull request from lbryio/fix-nullList
fix null listBlocked response and non-peer lbry-redux dependency
2020-01-08 16:52:33 -05:00
Sean Yesmunt
6042c6f7bb add blocking param for sync_apply call 2020-01-07 17:01:26 -05:00
Sean Yesmunt
37b09fcce1
Merge pull request from lbryio/password
pass error back to sync callback
2020-01-03 15:33:50 -05:00
Sean Yesmunt
dd4d01b42b pass error back to sync callback 2020-01-03 15:30:56 -05:00
Sean Yesmunt
4cb26d8184 reward/new => reward/claim 2020-01-03 14:20:14 -05:00
jessop
9fa349f3c1 fix error when listBlocked response is null and remove unneccesary lbry-redux non-peer dependency 2020-01-03 14:06:35 -05:00
Akinwale Ariwodola
053ca52f4f fix issue with null claims in stats selectors 2019-12-20 08:45:03 +01:00
Sean Yesmunt
1e897d2c91 update user type 2019-12-05 11:01:25 -05:00
Akinwale Ariwodola
9ffb883cc1
Transifex upload ()
* add utility method to upload translation strings
* use update url when the resource exists
* pass token as a parameter to the upload method
2019-12-05 13:13:10 +01:00
Sean Yesmunt
9738f36bf2
Merge pull request from lbryio/0.45-support
Fix: pagination support
2019-11-13 16:32:17 -05:00
Thomas Zarebczan
2aedf5a188 Fix: pagination support 2019-11-12 12:42:04 -05:00
Sean Yesmunt
d4829073e1
add values for existingUser/resendingVerificationEmail ()
add values for existingUser/resendingVerificationEmail
2019-11-05 19:24:05 -05:00
Sean Yesmunt
31299530d0 add bad password action 2019-11-05 13:57:54 -05:00
Sean Yesmunt
5e0bb245ed add values for existingUser/resendingVerificationEmail 2019-11-05 13:57:54 -05:00
Sean Yesmunt
fcf02a2bfa
Merge pull request from lbryio/0.44-support
fix: SDK response support
2019-11-05 13:56:44 -05:00
Thomas Zarebczan
896fafccef fix: SDK response support 2019-11-04 18:32:32 -05:00
Thomas Zarebczan
27b6fcb839 fix: invite notification 2019-10-26 16:56:01 -04:00
Sean Yesmunt
8d9d244d67
Merge pull request from lbryio/lbrytvReducer
lbrytv reducer: uploads
2019-10-22 16:33:31 -04:00
Sean Yesmunt
061c782ff4 update build 2019-10-22 15:21:42 -04:00
jessop
c8b39b5d10 lbrytv reducer: uploads 2019-10-22 14:33:42 -04:00
Sean Yesmunt
b4063b7684
add: sync encrypt and decrypt ()
add: sync encrypt and decrypt
2019-10-21 12:37:46 -04:00
Sean Yesmunt
2b968526c8 remove console logs 2019-10-21 12:35:52 -04:00
Thomas Zarebczan
6e5729afd2 fix: encryption and decryption! 2019-10-21 12:17:40 -04:00
Sean Yesmunt
0d32654e2e for tom 2019-10-21 12:17:40 -04:00
Sean Yesmunt
6e1daf43d0
Merge pull request from lbryio/sync-unlock
unlock wallet if needed before syncing
2019-10-21 12:16:18 -04:00
Sean Yesmunt
f731973f8f add additional catch for second sync_apply 2019-10-21 11:56:19 -04:00
Sean Yesmunt
fb2e73ab31 unlock wallet if needed before syncing 2019-10-15 23:35:03 -04:00
Sean Yesmunt
aebad10a9c
Add callbacks to getSync ()
Add callbacks to `getSync`
2019-10-15 10:32:28 -04:00
Sean Yesmunt
fc55460f2e fix to prevent callback being called twice 2019-10-15 10:32:05 -04:00
Akinwale Ariwodola
367d987e1f
Merge pull request from lbryio/fcm
add firebaseToken argument
2019-10-15 10:22:14 +01:00
Akinwale Ariwodola
7faaca45b9 add firebaseToken argument 2019-10-15 10:21:08 +01:00
Sean Yesmunt
b8e1708ee4 better default password handling 2019-10-14 23:21:17 -04:00
Sean Yesmunt
e31a50478e add callbacks to 'doGetSync' 2019-10-14 23:07:41 -04:00
Sean Yesmunt
699dc63459 update reward timeout to 2 seconds 2019-10-11 12:36:35 -04:00
Sean Yesmunt
02d8571cd7
removed type featured download from reward claim type issue 2872… ()
removed type featured download from reward claim type issue 2872 libr…
2019-10-09 14:05:34 -04:00
priyapande
8a827c5e3a removed type featured download from reward claim type issue 2872 libry-desktop 2019-10-09 14:05:13 -04:00
Sean Yesmunt
a29dd15c88
bump year in license ()
bump year in license
2019-10-09 13:57:57 -04:00
Nikita Titov
7e5192b053
bump year in license 2019-10-08 23:47:09 +03:00
Sean Yesmunt
5547bfeae4
Changes needed for additional youtube transfer UI ()
Changes needed for additional youtube transfer UI
2019-10-06 22:40:01 -04:00
Sean Yesmunt
d1dba98bb6 require flag to set the default account after calling getSync 2019-10-04 12:52:28 -04:00
Sean Yesmunt
11205c5338
update link instructions 2019-10-03 15:05:42 -04:00
Sean Yesmunt
44b6373ada wait to call account_balance to ensure sdk returns proper balance after claiming a reward 2019-10-03 13:14:17 -04:00
Sean Yesmunt
5aba3127c8 update balance after claiming reward and add action for clearing sync state 2019-10-02 16:22:51 -04:00
Sean Yesmunt
7c94a38683 changes for youtube sync onboarding 2019-10-02 00:15:24 -04:00
Akinwale Ariwodola
d99232ebc7
Merge pull request from lbryio/latest-subscription
move subscription latest to separate property
2019-09-30 21:20:30 +01:00
Akinwale Ariwodola
c55a2c98ab move subscription latest to separate property 2019-09-30 17:24:24 +01:00
Sean Yesmunt
4c00df007b
Merge pull request from lbryio/sub-counts
feat: add sub counts
2019-09-26 23:38:59 -04:00
Akinwale Ariwodola
67bb3e215b fix doSetSync call for a first-time user sync flow 2019-09-25 23:09:04 +01:00
Thomas Zarebczan
4a1647a41e feat: add sub counts 2019-09-24 22:30:59 -04:00
Sean Yesmunt
d250096a6f
Merge pull request from lbryio/user-state-populate
update subscriptions reducer to handle USER_STATE_POPULATE action
2019-09-23 11:19:16 -04:00
Akinwale Ariwodola
32f8ded652 update subscriptions reducer to handle USER_STATE_POPULATE action 2019-09-23 11:18:57 -04:00
Sean Yesmunt
ebc8122c99
Merge pull request from lbryio/youtubeChannels
related to claiming youtube channels
2019-09-23 11:18:27 -04:00
Thomas Zarebczan
3b2776395b fix: pub key / cert check
And selection of address.
fix: check for cert
2019-09-23 11:18:08 -04:00
jessop
34b91fca23 redux housekeeping for yt import pending and errors 2019-09-23 11:17:57 -04:00
jessop
1890985bec sync transfer and import 2019-09-23 11:17:41 -04:00
jessop
afdba5fd5d user youtubeChannels selector 2019-09-23 11:16:48 -04:00
Sean Yesmunt
f8bba34b34
Merge pull request from lbryio/daily_reward
add DAILY_VIEW award to whitelist
2019-09-19 13:05:37 -04:00
Sean Yesmunt
e17aa9d1be add DAILY_VIEW award to whitelist 2019-09-19 13:03:42 -04:00
Sean Yesmunt
d87e594fe9
Merge pull request from lbryio/onboarding
onboarding updates
2019-09-17 10:33:15 -04:00
Sean Yesmunt
09c9a6ca2b add User type and allow lbryinc types to be used by apps 2019-09-16 16:12:43 -04:00
Sean Yesmunt
66a719ebfb onboarding updates 2019-09-16 13:48:32 -04:00
dependabot[bot]
f6c017de77 Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-09-13 11:05:43 -04:00
Akinwale Ariwodola
b9f354ae50
Merge pull request from lbryio/fix-canonical-url
fix: canonical url stuff
2019-09-06 16:21:58 +01:00
Akinwale Ariwodola
c580288e35
Merge pull request from lbryio/set-default-callback
add callbacks to setDefaultAccount method
2019-09-06 16:21:42 +01:00
Akinwale Ariwodola
8da2a86f39 add callbacks to setDefaultAccount method 2019-09-06 16:19:17 +01:00
Thomas Zarebczan
534f02e54a
Merge pull request from lbryio/check-daily-view
feat: check daily view reward when claiming
2019-09-04 17:22:27 -04:00
Thomas Zarebczan
5cd0fdff9b feat: check daily view reward when claiming 2019-09-04 17:12:37 -04:00
Sean Yesmunt
2df8868fcf
Merge pull request from lbryio/dailyView
daily_view reward
2019-09-04 12:56:45 -04:00
jessop
f2dd7434db daily_view reward 2019-09-04 12:41:17 -04:00
Thomas Zarebczan
35ca4fbc3d fix: canonical url stuff 2019-08-29 12:58:30 -04:00
Akinwale Ariwodola
396e8fff4f
Merge pull request from lbryio/builduri-warnings
fix for buildURI warnings in setSubscriptionsLatest
2019-08-27 16:26:04 +01:00
Akinwale Ariwodola
4c76108499 fix for buildURI warnings in setSubscriptionsLatest 2019-08-26 20:32:55 +01:00
Akinwale Ariwodola
3035cbdde6 replace one more instance of contentName with claimName 2019-08-26 19:19:56 +01:00
Akinwale Ariwodola
3fa1ed2796 fix: use claimName instead of contentName in buildURI 2019-08-26 19:02:46 +01:00
jessopb
ea72da47df
Merge pull request from lbryio/syncHasChanged
adds hashChanged from sync get response
2019-08-19 10:46:15 -04:00
jessop
aeac92275c adds hashChanged from sync get response 2019-08-15 21:33:07 -04:00
Sean Yesmunt
1ce266b3c5
Merge pull request from lbryio/user
don't clear user during fetch
2019-08-14 12:11:53 -04:00
Sean Yesmunt
f372015bb2 don't clear user during fetch 2019-08-14 12:08:27 -04:00
Sean Yesmunt
1c2188ff21 remove extra lodash entry in yarn.lock 2019-08-06 14:12:36 -04:00
Sean Yesmunt
5f94bb6bc9 update deps 2019-08-06 14:11:46 -04:00
Sean Yesmunt
17868d948a
Merge pull request from lbryio/dependabot/npm_and_yarn/js-yaml-3.13.1
Bump js-yaml from 3.12.0 to 3.13.1
2019-08-06 14:05:50 -04:00
Sean Yesmunt
039d03dba8
Merge pull request from lbryio/dependabot/npm_and_yarn/fstream-1.0.12
Bump fstream from 1.0.11 to 1.0.12
2019-08-06 14:05:24 -04:00
dependabot[bot]
1152826ccb
Bump js-yaml from 3.12.0 to 3.13.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-05 18:49:52 +00:00
dependabot[bot]
a5e9b559b8
Bump fstream from 1.0.11 to 1.0.12
Bumps [fstream](https://github.com/npm/fstream) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/npm/fstream/releases)
- [Commits](https://github.com/npm/fstream/compare/v1.0.11...v1.0.12)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-05 18:49:49 +00:00
Akinwale Ariwodola
430c280789
Merge pull request from lbryio/fix_claim_search
fix: claim search uses channel, not channel name
2019-07-22 19:15:10 +01:00
Thomas Zarebczan
c00e7355cf fix: claim search uses channel, not channel name 2019-07-22 14:12:54 -04:00
Thomas Zarebczan
a93596c51c
Merge pull request from lbryio/redlist
provides file list_filtered api
2019-07-16 23:11:13 -04:00
jessop
69f9562b01 modifications 2019-07-10 20:44:15 -04:00
jessop
284cff48c2 provides file list_filtered api 2019-07-09 18:11:20 -04:00
Thomas Zarebczan
2cc861145e
Merge pull request from lbryio/claim-search-038
fix: 0.38 claim search changes
2019-06-26 11:32:16 -04:00
Thomas Zarebczan
2d2755e914 fix: claim_search
rename param
2019-06-26 11:29:41 -04:00
Thomas Zarebczan
eecbbfb121 fix: remove controlling, check valid
Controlling means claims, not channels. We do want to make sure they are valid though.
2019-06-11 11:38:18 -04:00
Thomas Zarebczan
a85b77b4bc fix: 0.38 claim search changes 2019-06-09 16:10:33 -04:00
Akinwale Ariwodola
c7b677279a do not set the default account after every sync_apply call 2019-05-28 17:38:43 +01:00
Akinwale Ariwodola
5bffcaf83d
Merge pull request from lbryio/claim-search-fix
fix: claim search
2019-05-27 14:58:05 +01:00
Akinwale Ariwodola
dcba831c6b
add doCheckSync action to check if user has a synced wallet ()
* add doCheckSync action to check if user has a synced wallet
* add doSyncApply action. rename some state properties.
2019-05-27 14:57:31 +01:00
Thomas Zarebczan
52c10ad71d fix: claim search
to use channel uri instead of claim id (support for vanity resolution)
2019-05-21 14:40:29 -04:00
Akinwale Ariwodola
7ba14f1d88
Merge pull request from lbryio/sync-default-account
set the default account upon successful /sync/get call
2019-05-14 15:57:22 +01:00
Akinwale Ariwodola
793c9c1084 set the default account upon successful /sync/get call 2019-05-10 15:45:56 +01:00
Sean Yesmunt
43d382d9b7
Merge pull request from lbryio/claimlist
changes claim_list_mine to claim_list
2019-05-07 14:31:47 -04:00
Sean Yesmunt
9cbf3a9892 update build 2019-05-07 14:30:06 -04:00
jessop
145e936cfc changes claim_list_mine to claim_list 2019-05-02 16:22:36 -04:00
Akinwale Ariwodola
a8fd592c46
Merge pull request from lbryio/sdk-0.36-changes
replace claim_list_by_channel with claim_search
2019-04-29 10:29:50 +01:00
Akinwale Ariwodola
bec7ce1fba update package.json 2019-04-27 20:34:17 +01:00
Akinwale Ariwodola
2c4d5d2e7e update package.json 2019-04-27 20:33:12 +01:00
Akinwale Ariwodola
9994c9ba24 replace claim_list_by_channel with claim_search 2019-04-27 19:57:03 +01:00
Sean Yesmunt
bb6be90560
Merge pull request from lbryio/sdk
fix for v0.36 sdk
2019-04-23 10:35:58 -04:00
Sean Yesmunt
9665f2d1c8 fix for new sdk 2019-04-22 17:24:03 -04:00
Akinwale Ariwodola
7f6bf155b7
updates for cross-device sync ()
* add sync actions, reducer and selectors
2019-04-18 09:02:11 +01:00
Shawn K
4f2d4a5098
Merge pull request from lbryio/rollup-and-cleanup
Add rollup es build, major cleanup
2019-04-07 23:30:45 -05:00
Shawn
120d3bf6df Add rollup es build, major cleanup 2019-04-03 16:34:07 -05:00
Sean Yesmunt
d9f9035113
Merge pull request from lbryio/routing
remove selectCostForCurrentPageUri
2019-03-27 14:46:44 -04:00
Sean Yesmunt
c30084da57 remove selectCostForCurrentPageUri 2019-03-27 14:45:19 -04:00
Sean Yesmunt
437260f3da update to lbry.com 2019-03-21 13:22:27 -04:00
Sean Yesmunt
c85059398b
Merge pull request from lbryio/stats
add view count stats
2019-03-15 10:51:27 -04:00
Sean Yesmunt
351d0a0880 add viewcount stats 2019-03-14 14:39:39 -04:00
Sean Yesmunt
e8411a0718
Merge pull request from lbryio/externals
actually treat lbry-redux as a peerDependency
2019-03-14 11:13:27 -04:00
Sean Yesmunt
636f014f42 actually treat lbry-redux as a peerDependency 2019-03-13 01:06:43 -04:00
Sean Yesmunt
4f16f81017
Merge pull request from lbryio/lbryredux
[BREAKING CHANGE] add lbry-redux as peer dependency
2019-03-12 14:18:26 -04:00
Sean Yesmunt
b54e90f3d4 add lbry-redux as a peer dependency 2019-03-10 22:02:17 -04:00
Akinwale Ariwodola
f590ddc077 update bundle 2019-02-21 17:01:19 +01:00
Sean Yesmunt
ec26a1ff9c
Merge pull request from lbryio/referral-link
add referral link
2019-02-20 14:16:56 -05:00
Sean Yesmunt
2334ad53e8 add referral link 2019-02-20 11:14:42 -05:00
Akinwale Ariwodola
c95a1a922e update lbry-redux commit hash in package.json 2019-02-20 15:03:14 +01:00
Akinwale Ariwodola
fff1a8979f
Merge pull request from lbryio/mobile-auth-tweak
some tweaks to mobile auth for new email verification
2019-02-17 09:15:38 +01:00
Akinwale Ariwodola
60cae0a8f4 some tweaks to mobile auth for new email verification 2019-02-17 09:13:34 +01:00
Akinwale Ariwodola
4fca4fabb8
Common subscriptions implementation ()
* add subscriptions actions, reducer and selectors, with related methods
2019-02-15 10:02:34 +01:00
Sean Yesmunt
60d8040189
Merge pull request from lbryio/auth-fix
fix: typo
2019-02-05 09:18:27 -05:00
Sean Yesmunt
60fe5519dc fix: typo 2019-02-05 01:11:17 -05:00
Sean Yesmunt
49fc5249b1
Merge pull request from lbryio/invite
Changes for invite api
2019-02-04 14:27:07 -05:00
Sean Yesmunt
da78018f72 call rewardList after invite status so rewards are updated based on invites 2019-02-04 12:03:26 -05:00
Sean Yesmunt
2515fcf15d
Merge pull request from lbryio/user-me
fix: prevent multiple user/me calls for new users
2019-02-03 23:24:22 -05:00
Sean Yesmunt
d970ba5372 fix: prevent multiple user/me calls for new users 2019-02-03 22:48:42 -05:00
Sean Yesmunt
375cc397d8 show error snackbar instead of modal for reward fail 2019-02-03 22:30:32 -05:00
Sean Yesmunt
0cc1b6d78d add selectReferralReward selector 2019-02-03 22:21:44 -05:00
Sean Yesmunt
faf8271cac update: call doFetchInviteStatus after claiming referral reward 2019-02-01 12:19:45 -05:00
Sean Yesmunt
83c275da7a
Merge pull request from lbryio/rewards-fix
fix: allow claiming rewards with multiple of the same type
2019-01-18 11:26:40 -05:00
Sean Yesmunt
dc67185a72 update: pass claim_code to 'reward/new' 2019-01-17 11:44:45 -05:00
Sean Yesmunt
cb47ccb925 fix: allow claiming rewards with multiple of the same type 2019-01-17 01:22:39 -05:00
Sean Yesmunt
1627e26525
Merge pull request from lbryio/email-verification
add doUserCheckEmailVerified instead of using doFetchUser
2019-01-09 17:04:55 -05:00
Sean Yesmunt
b3bb8c6774 add doUserCheckEmailVerified instead of using doFetchUser 2019-01-08 23:59:29 -05:00
Sean Yesmunt
cee70d482c
Merge pull request from lbryio/email-verification
Add `fetchSilently` param for `doUserFetch`
2019-01-07 15:46:35 -05:00
Sean Yesmunt
50373001a9 add fetchSilently param for doFetchUser 2019-01-03 14:46:20 -05:00
Sean Yesmunt
68c8ce6b76 remove console.log 2018-12-04 13:49:35 -05:00
Sean Yesmunt
ba3df4749d fix typo 2018-12-04 13:44:15 -05:00
Sean Yesmunt
2ffed3c768 add setLocalApi method 2018-12-04 13:43:49 -05:00
Sean Yesmunt
64068e13f9
Merge pull request from lbryio/rewards
Add callback for claimRewardSuccess
2018-12-04 13:26:08 -05:00
Sean Yesmunt
32a02f397a
Merge pull request from lbryio/local-api
add setLocalApi method
2018-12-04 11:08:44 -05:00
Sean Yesmunt
4b610b9f3b add setLocalApi method 2018-12-04 11:08:20 -05:00
Sean Yesmunt
e2a0375f80 add callback for claimRewardSuccess 2018-11-29 15:52:32 -05:00
Sean Yesmunt
26adc910bf
Merge pull request from lbryio/bump
update lbry-redux
2018-11-29 01:08:44 -05:00
Sean Yesmunt
01ed21e5d8 update lbry-redux 2018-11-29 01:07:43 -05:00
Sean Yesmunt
50da4e2efd
Merge pull request from lbryio/modals
Strip out modal code
2018-11-28 18:23:20 -05:00
Sean Yesmunt
ef1c440b4a use new notification logic and remove modals from lbryinc 2018-11-28 10:36:40 -05:00
Sean Yesmunt
14a1612607 update lbry-redux 2018-11-27 20:34:13 -05:00
Sean Yesmunt
e9508e259f
Merge pull request from lbryio/remove-reversal
remove reversal
2018-11-27 10:55:15 -05:00
Sean Yesmunt
cbeb8ad918 update build 2018-11-27 10:53:44 -05:00
Thomas Zarebczan
be023e0627 remove reversal
the claims now come in ordered correctly.
2018-11-27 09:57:53 -05:00
Sean Yesmunt
82308ece97
Merge pull request from lbryio/0.30-updates
updates for new daemon
2018-11-12 14:23:57 -05:00
Sean Yesmunt
5ad9d079a1 chore: update build 2018-11-12 14:19:33 -05:00
Thomas Zarebczan
b0b8a2c809
updates for new daemon
change wallet_unused_address > address_unused and category > type
2018-11-12 13:23:50 -05:00
Sean Yesmunt
7a458ea13c
Merge pull request from lbryio/lbrynet30
update lbry-redux
2018-10-26 14:11:30 -04:00
Sean Yesmunt
6d636e4c12 update lbry-redux 2018-10-26 14:10:50 -04:00
Sean Yesmunt
3f34af546e
Merge pull request from lbryio/typo
fix reward typo
2018-10-18 13:28:45 -04:00
Sean Yesmunt
597ca492a6 fix reward typo 2018-10-18 13:28:01 -04:00
Sean Yesmunt
514807ef70
Merge pull request from jimmiehansson/master
#ISSUE-2043 Add logic lost in code refactor for silent fail on rewards
2018-10-18 13:17:00 -04:00
Sean Yesmunt
d8e95e23b1 update build 2018-10-18 12:36:55 -04:00
Jimmie Hansson
d968bebf7f Add logic lost in code refactor 2018-10-18 09:57:28 +02:00
Akinwale Ariwodola
7c726b4851
Merge pull request from lbryio/refresh-reward-list
dispatch doRewardList after a reward is successfully claimed
2018-10-07 13:53:07 +01:00
Akinwale Ariwodola
904d37d6f0 dispatch doRewardList after a reward is successfully claimed 2018-10-04 14:08:28 +01:00
Akinwale Ariwodola
e35b93013f fix bundle 2018-10-02 04:07:13 +01:00
Sean Yesmunt
de7ff05560
Merge pull request from lbryio/reward-codes
add logic for reward codes
2018-10-01 20:47:57 -04:00
Sean Yesmunt
a818633ea2 add logic for reward codes 2018-10-01 20:38:16 -04:00
Sean Yesmunt
c09aa2645e
Merge pull request from lbryio/app-updates
updates for desktop app to use lbryinc
2018-09-23 21:04:43 -04:00
Sean Yesmunt
7d4b02ad64 updates for desktop app to use lbryinc 2018-09-18 17:56:12 -04:00
Akinwale Ariwodola
acf7654451
Merge pull request from lbryio/fetch-rewarded-content
add action/reducer/selector for fetching rewarded content
2018-09-04 05:17:02 +01:00
Akinwale Ariwodola
c53bef489c add action/reducer/selector for fetching rewarded content 2018-09-04 05:15:53 +01:00
Akinwale Ariwodola
f2fff2a331 remove deviceId parameter and add an os parameter for os_system override 2018-09-03 19:50:43 +01:00
Akinwale Ariwodola
9132de92f6
Merge pull request from lbryio/phone-verification
modifications for phone verification
2018-09-03 19:43:31 +01:00
Akinwale Ariwodola
7910b565d7 modifications for phone verification 2018-08-31 20:51:00 +01:00
Akinwale Ariwodola
3ee7571617 chore: update bundle 2018-08-29 20:57:48 +01:00
Akinwale Ariwodola
678c5098e2 add first reward message for mobile 2018-08-27 16:36:02 +01:00
Akinwale Ariwodola
fb7c79d594 chore: update bundle 2018-08-27 16:26:35 +01:00
Akinwale Ariwodola
fe79a833c3
Merge pull request from lbryio/rewards
export rewards module
2018-08-24 13:31:12 +01:00
Akinwale Ariwodola
f5d23dc5ee export rewards module 2018-08-24 11:35:11 +01:00
Akinwale Ariwodola
62f0b58073
fixes and updates for authentication flow ()
* fixes and updates for authentication flow
* add action and reducer for setting emailToVerify in the state
2018-08-17 19:10:52 +01:00
51 changed files with 9277 additions and 10586 deletions

View file

@ -1,4 +1,6 @@
{ {
"presets": ["env", "stage-2"], "presets": ["@babel/preset-env"],
"plugins": ["transform-flow-comments"] "plugins": [
"@babel/plugin-transform-flow-strip-types"
]
} }

View file

@ -22,9 +22,13 @@
"__": true "__": true
}, },
"rules": { "rules": {
"consistent-return": 0,
"import/extensions": 0,
"import/no-commonjs": "warn", "import/no-commonjs": "warn",
"import/no-amd": "warn", "import/no-amd": "warn",
"import/prefer-default-export": "ignore", "import/prefer-default-export": "ignore",
"func-names": ["warn", "as-needed"] "flowtype/generic-spacing": 0,
"func-names": ["warn", "as-needed"],
"no-plusplus": 0
} }
} }

View file

@ -1,4 +1,5 @@
[ignore] [ignore]
node_modules/
[include] [include]

3
.gitignore vendored
View file

@ -1,2 +1,5 @@
/node_modules /node_modules
yarn-error.log yarn-error.log
# Jetbrains
.idea/

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2017-2018 LBRY Inc Copyright (c) 2017-2020 LBRY Inc
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,

View file

@ -9,14 +9,17 @@ Add `lbryinc` as a dependency to your `package.json` file.
If you intend to make changes to the module and test immediately, you can use `npm link` to add the package to your `node_modules` folder. This will create a symlink to the folder where `lbry-redux` was cloned to. If you intend to make changes to the module and test immediately, you can use `npm link` to add the package to your `node_modules` folder. This will create a symlink to the folder where `lbry-redux` was cloned to.
``` ```
cd lbryinc cd lbryinc
sudo npm link yarn link
cd /<path>/<to>/<project>/node_modules cd /<path>/<to>/<project> (ex: cd ~/lbry-desktop)
npm link lbryinc yarn link lbryinc
```` ````
### Build ### Build
Run `$ yarn build`. If the symlink does not work, just build the file and move the `bundle.js` file in to the `node_modules/` folder. Run `$ yarn build`. If the symlink does not work, just build the file and move the `bundle.js` file in to the `node_modules/` folder.
### Automatic rebuild
To have the code automatically rebuild upon changes you can run `$ yarn dev` which will use `rollup` to watch the files and build upon detection of updated source code.
## License ## License
[MIT © LBRY](LICENSE) [MIT © LBRY](LICENSE)

1611
dist/bundle.es.js vendored Normal file

File diff suppressed because it is too large Load diff

11730
dist/bundle.js vendored

File diff suppressed because it is too large Load diff

View file

@ -19,23 +19,30 @@
"email": "hello@lbry.io" "email": "hello@lbry.io"
}, },
"main": "dist/bundle.js", "main": "dist/bundle.js",
"module": "dist/bundle.es.js",
"scripts": { "scripts": {
"build": "webpack", "build": "rollup --config && webpack",
"dev": "rollup --config --watch",
"precommit": "lint-staged", "precommit": "lint-staged",
"preinstall": "yarn cache clean lbry-redux",
"lint": "eslint 'src/**/*.js' --fix", "lint": "eslint 'src/**/*.js' --fix",
"format": "prettier 'src/**/*.{js,json}' --write" "format": "prettier 'src/**/*.{js,json}' --write"
}, },
"dependencies": { "dependencies": {
"lbry-redux": "lbryio/lbry-redux",
"reselect": "^3.0.0" "reselect": "^3.0.0"
}, },
"peerDependencies": {
"lbry-redux": "lbryio/lbry-redux"
},
"devDependencies": { "devDependencies": {
"babel-core": "^6.26.0", "@babel/core": "^7.4.3",
"@babel/plugin-transform-flow-strip-types": "^7.4.0",
"@babel/preset-env": "^7.4.3",
"@babel/preset-stage-2": "^7.0.0",
"babel-eslint": "^8.0.3", "babel-eslint": "^8.0.3",
"babel-loader": "^7.1.4", "babel-loader": "^8.0.5",
"babel-plugin-module-resolver": "^3.0.0", "babel-plugin-module-resolver": "^3.0.0",
"babel-preset-env": "^1.6.1", "cross-env": "^5.2.0",
"babel-preset-stage-2": "^6.18.0",
"eslint": "^4.19.1", "eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0", "eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0", "eslint-config-prettier": "^2.9.0",
@ -43,14 +50,19 @@
"eslint-plugin-flowtype": "^2.40.1", "eslint-plugin-flowtype": "^2.40.1",
"eslint-plugin-import": "^2.10.0", "eslint-plugin-import": "^2.10.0",
"eslint-plugin-prettier": "^2.4.0", "eslint-plugin-prettier": "^2.4.0",
"flow-babel-webpack-plugin": "^1.1.1",
"flow-bin": "^0.69.0", "flow-bin": "^0.69.0",
"flow-typed": "^2.4.0", "flow-typed": "^2.4.0",
"husky": "^0.14.3", "husky": "^0.14.3",
"lint-staged": "^7.0.4", "lint-staged": "^7.0.4",
"prettier": "^1.4.2", "prettier": "^1.4.2",
"rollup": "^1.8.0",
"rollup-plugin-alias": "^2.0.0",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-copy": "^3.1.0",
"rollup-plugin-flow": "^1.1.1",
"rollup-plugin-includepaths": "^0.2.3",
"webpack": "^4.5.0", "webpack": "^4.5.0",
"webpack-cli": "^2.0.14" "webpack-cli": "^3.3.7"
}, },
"engines": { "engines": {
"yarn": "^1.3" "yarn": "^1.3"

38
rollup.config.js Normal file
View file

@ -0,0 +1,38 @@
import babel from 'rollup-plugin-babel';
import flow from 'rollup-plugin-flow';
import includePaths from 'rollup-plugin-includepaths';
import copy from 'rollup-plugin-copy';
import alias from 'rollup-plugin-alias';
let includePathOptions = {
include: {},
paths: ['src'],
external: [],
extensions: ['.js'],
};
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.es.js',
format: 'cjs',
},
plugins: [
alias({
entries: [
{
find: 'flow-typed',
replacement: './flow-typed',
},
],
}),
flow({ all: true }),
includePaths(includePathOptions),
babel({
babelrc: false,
presets: [],
}),
copy({ targets: [{ src: './flow-typed', dest: 'dist' }] }),
],
external: ['lbry-redux'],
};

View file

@ -1,3 +1,97 @@
// Claims
export const FETCH_FEATURED_CONTENT_STARTED = 'FETCH_FEATURED_CONTENT_STARTED';
export const FETCH_FEATURED_CONTENT_COMPLETED = 'FETCH_FEATURED_CONTENT_COMPLETED';
export const FETCH_TRENDING_CONTENT_STARTED = 'FETCH_TRENDING_CONTENT_STARTED';
export const FETCH_TRENDING_CONTENT_COMPLETED = 'FETCH_TRENDING_CONTENT_COMPLETED';
export const RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED';
export const RESOLVE_URIS_COMPLETED = 'RESOLVE_URIS_COMPLETED';
export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED';
export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED';
export const FETCH_CHANNEL_CLAIM_COUNT_STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED';
export const FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED';
export const FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED';
export const FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED';
export const ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED';
export const ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED';
export const FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED';
export const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED';
export const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED';
export const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED';
export const PUBLISH_STARTED = 'PUBLISH_STARTED';
export const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED';
export const PUBLISH_FAILED = 'PUBLISH_FAILED';
export const SET_PLAYING_URI = 'SET_PLAYING_URI';
export const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION';
export const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED';
export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI';
export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL';
// Subscriptions
export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE';
export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE';
export const CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS =
'CHANNEL_SUBSCRIPTION_ENABLE_NOTIFICATIONS';
export const CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS =
'CHANNEL_SUBSCRIPTION_DISABLE_NOTIFICATIONS';
export const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS';
export const SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST';
export const UPDATE_SUBSCRIPTION_UNREADS = 'UPDATE_SUBSCRIPTION_UNREADS';
export const REMOVE_SUBSCRIPTION_UNREADS = 'REMOVE_SUBSCRIPTION_UNREADS';
export const CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED';
export const CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED';
export const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE';
export const FETCH_SUBSCRIPTIONS_START = 'FETCH_SUBSCRIPTIONS_START';
export const FETCH_SUBSCRIPTIONS_FAIL = 'FETCH_SUBSCRIPTIONS_FAIL';
export const FETCH_SUBSCRIPTIONS_SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS';
export const SET_VIEW_MODE = 'SET_VIEW_MODE';
export const GET_SUGGESTED_SUBSCRIPTIONS_START = 'GET_SUGGESTED_SUBSCRIPTIONS_START';
export const GET_SUGGESTED_SUBSCRIPTIONS_SUCCESS = 'GET_SUGGESTED_SUBSCRIPTIONS_SUCCESS';
export const GET_SUGGESTED_SUBSCRIPTIONS_FAIL = 'GET_SUGGESTED_SUBSCRIPTIONS_FAIL';
export const SUBSCRIPTION_FIRST_RUN_COMPLETED = 'SUBSCRIPTION_FIRST_RUN_COMPLETED';
export const VIEW_SUGGESTED_SUBSCRIPTIONS = 'VIEW_SUGGESTED_SUBSCRIPTIONS';
// Blacklist
export const FETCH_BLACK_LISTED_CONTENT_STARTED = 'FETCH_BLACK_LISTED_CONTENT_STARTED';
export const FETCH_BLACK_LISTED_CONTENT_COMPLETED = 'FETCH_BLACK_LISTED_CONTENT_COMPLETED';
export const FETCH_BLACK_LISTED_CONTENT_FAILED = 'FETCH_BLACK_LISTED_CONTENT_FAILED';
export const BLACK_LISTED_CONTENT_SUBSCRIBE = 'BLACK_LISTED_CONTENT_SUBSCRIBE';
// Filtered list
export const FETCH_FILTERED_CONTENT_STARTED = 'FETCH_FILTERED_CONTENT_STARTED';
export const FETCH_FILTERED_CONTENT_COMPLETED = 'FETCH_FILTERED_CONTENT_COMPLETED';
export const FETCH_FILTERED_CONTENT_FAILED = 'FETCH_FILTERED_CONTENT_FAILED';
export const FILTERED_CONTENT_SUBSCRIBE = 'FILTERED_CONTENT_SUBSCRIBE';
// Cost Info
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED';
export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED';
// Stats
export const FETCH_VIEW_COUNT_STARTED = 'FETCH_VIEW_COUNT_STARTED';
export const FETCH_VIEW_COUNT_FAILED = 'FETCH_VIEW_COUNT_FAILED';
export const FETCH_VIEW_COUNT_COMPLETED = 'FETCH_VIEW_COUNT_COMPLETED';
export const FETCH_SUB_COUNT_STARTED = 'FETCH_SUB_COUNT_STARTED';
export const FETCH_SUB_COUNT_FAILED = 'FETCH_SUB_COUNT_FAILED';
export const FETCH_SUB_COUNT_COMPLETED = 'FETCH_SUB_COUNT_COMPLETED';
// Cross-device Sync
export const GET_SYNC_STARTED = 'GET_SYNC_STARTED';
export const GET_SYNC_COMPLETED = 'GET_SYNC_COMPLETED';
export const GET_SYNC_FAILED = 'GET_SYNC_FAILED';
export const SET_SYNC_STARTED = 'SET_SYNC_STARTED';
export const SET_SYNC_FAILED = 'SET_SYNC_FAILED';
export const SET_SYNC_COMPLETED = 'SET_SYNC_COMPLETED';
export const SET_DEFAULT_ACCOUNT = 'SET_DEFAULT_ACCOUNT';
export const SYNC_APPLY_STARTED = 'SYNC_APPLY_STARTED';
export const SYNC_APPLY_COMPLETED = 'SYNC_APPLY_COMPLETED';
export const SYNC_APPLY_FAILED = 'SYNC_APPLY_FAILED';
export const SYNC_APPLY_BAD_PASSWORD = 'SYNC_APPLY_BAD_PASSWORD';
export const SYNC_RESET = 'SYNC_RESET';
// Lbry.tv
export const UPDATE_UPLOAD_PROGRESS = 'UPDATE_UPLOAD_PROGRESS';
// User
export const GENERATE_AUTH_TOKEN_FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE'; export const GENERATE_AUTH_TOKEN_FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE';
export const GENERATE_AUTH_TOKEN_STARTED = 'GENERATE_AUTH_TOKEN_STARTED'; export const GENERATE_AUTH_TOKEN_STARTED = 'GENERATE_AUTH_TOKEN_STARTED';
export const GENERATE_AUTH_TOKEN_SUCCESS = 'GENERATE_AUTH_TOKEN_SUCCESS'; export const GENERATE_AUTH_TOKEN_SUCCESS = 'GENERATE_AUTH_TOKEN_SUCCESS';

5
src/constants/claim.js Normal file
View file

@ -0,0 +1,5 @@
export const MINIMUM_PUBLISH_BID = 0.00000001;
export const CHANNEL_ANONYMOUS = 'anonymous';
export const CHANNEL_NEW = 'new';
export const PAGE_SIZE = 20;

4
src/constants/errors.js Normal file
View file

@ -0,0 +1,4 @@
export const ALREADY_CLAIMED =
'once the invite reward has been claimed the referrer cannot be changed';
export const REFERRER_NOT_FOUND =
'A lbry.tv account could not be found for the referrer you provided.';

11
src/constants/youtube.js Normal file
View file

@ -0,0 +1,11 @@
export const YOUTUBE_SYNC_NOT_TRANSFERRED = 'not_transferred';
export const YOUTUBE_SYNC_PENDING = 'pending';
export const YOUTUBE_SYNC_PENDING_EMAIL = 'pendingemail';
export const YOUTUBE_SYNC_PENDING_TRANSFER = 'pending_transfer';
export const YOUTUBE_SYNC_COMPLETED_TRANSFER = 'completed_transfer';
export const YOUTUBE_SYNC_QUEUED = 'queued';
export const YOUTUBE_SYNC_SYNCING = 'syncing';
export const YOUTUBE_SYNC_SYNCED = 'synced';
export const YOUTUBE_SYNC_FAILED = 'failed';
export const YOUTUBE_SYNC_PENDINGUPGRADE = 'pendingupgrade';
export const YOUTUBE_SYNC_ABANDONDED = 'abandoned';

View file

@ -1,71 +1,79 @@
import * as LBRYINC_ACTIONS from 'constants/action_types'; import * as LBRYINC_ACTIONS from 'constants/action_types';
import * as YOUTUBE_STATUSES from 'constants/youtube';
import * as ERRORS from 'constants/errors';
import Lbryio from 'lbryio'; import Lbryio from 'lbryio';
// constants
export { LBRYINC_ACTIONS };
// Lbryio
export { Lbryio }; export { Lbryio };
// constants
export { LBRYINC_ACTIONS, YOUTUBE_STATUSES, ERRORS };
// utils
export { doTransifexUpload } from 'util/transifex-upload';
// actions // actions
export { doGenerateAuthToken } from 'redux/actions/auth'; export { doGenerateAuthToken } from 'redux/actions/auth';
export { doFetchCostInfoForUri } from 'redux/actions/cost_info';
export { doBlackListedOutpointsSubscribe } from 'redux/actions/blacklist';
export { doFilteredOutpointsSubscribe } from 'redux/actions/filtered';
export { doFetchFeaturedUris, doFetchTrendingUris } from 'redux/actions/homepage';
export { doFetchViewCount, doFetchSubCount } from 'redux/actions/stats';
export { export {
doRewardList, doCheckSync,
doClaimRewardType, doGetSync,
doClaimEligiblePurchaseRewards, doSetSync,
doClaimRewardClearError, doSetDefaultAccount,
} from 'redux/actions/rewards'; doSyncApply,
export { doFetchInviteStatus, doInstallNew, doAuthenticate, doUserFetch } from 'redux/actions/user'; doResetSync,
doSyncEncryptAndDecrypt,
} from 'redux/actions/sync';
export { doUpdateUploadProgress } from 'redux/actions/web';
// reducers // reducers
export { authReducer } from 'redux/reducers/auth'; export { authReducer } from 'redux/reducers/auth';
export { rewardsReducer } from 'redux/reducers/rewards'; export { costInfoReducer } from 'redux/reducers/cost_info';
export { userReducer } from 'redux/reducers/user'; export { blacklistReducer } from 'redux/reducers/blacklist';
export { filteredReducer } from 'redux/reducers/filtered';
export { homepageReducer } from 'redux/reducers/homepage';
export { statsReducer } from 'redux/reducers/stats';
export { syncReducer } from 'redux/reducers/sync';
export { webReducer } from 'redux/reducers/web';
// selectors // selectors
export { selectAuthToken } from 'redux/selectors/auth'; export { selectAuthToken, selectIsAuthenticating } from 'redux/selectors/auth';
export { export {
makeSelectClaimRewardError, makeSelectFetchingCostInfoForUri,
makeSelectIsRewardClaimPending, makeSelectCostInfoForUri,
makeSelectRewardAmountByType, selectAllCostInfoByUri,
makeSelectRewardByType, selectFetchingCostInfo,
selectUnclaimedRewardsByType, } from 'redux/selectors/cost_info';
selectClaimedRewardsById,
selectClaimedRewards,
selectClaimedRewardsByTransactionId,
selectUnclaimedRewards,
selectFetchingRewards,
selectUnclaimedRewardValue,
selectClaimsPendingByType,
selectIsClaimRewardPending,
selectClaimErrorsByType,
selectClaimRewardError,
selectRewardByType,
} from 'redux/selectors/rewards';
export { export {
selectAuthenticationIsPending, selectBlackListedOutpoints,
selectUserIsPending, selectBlacklistedOutpointMap,
selectUser, } from 'redux/selectors/blacklist';
selectUserEmail, export { selectFilteredOutpoints, selectFilteredOutpointMap } from 'redux/selectors/filtered';
selectUserPhone, export {
selectUserCountryCode, selectFeaturedUris,
selectEmailToVerify, selectFetchingFeaturedUris,
selectPhoneToVerify, selectTrendingUris,
selectUserIsRewardApproved, selectFetchingTrendingUris,
selectEmailNewIsPending, } from 'redux/selectors/homepage';
selectEmailNewErrorMessage, export {
selectPhoneNewErrorMessage, selectViewCount,
selectEmailVerifyIsPending, makeSelectViewCountForUri,
selectEmailVerifyErrorMessage, makeSelectSubCountForUri,
selectPhoneVerifyErrorMessage, } from 'redux/selectors/stats';
selectIdentityVerifyIsPending, export {
selectIdentityVerifyErrorMessage, selectHasSyncedWallet,
selectUserIsVerificationCandidate, selectSyncData,
selectAccessToken, selectSyncHash,
selectUserInviteStatusIsPending, selectSetSyncErrorMessage,
selectUserInvitesRemaining, selectGetSyncErrorMessage,
selectUserInvitees, selectGetSyncIsPending,
selectUserInviteStatusFailed, selectSetSyncIsPending,
selectUserInviteNewIsPending, selectSyncApplyIsPending,
selectUserInviteNewErrorMessage, selectHashChanged,
} from 'redux/selectors/user'; selectSyncApplyErrorMessage,
selectSyncApplyPasswordError,
} from 'redux/selectors/sync';
export { selectCurrentUploads, selectUploadCount } from 'redux/selectors/web';

View file

@ -1,15 +1,22 @@
import * as ACTIONS from 'constants/action_types';
import { Lbry } from 'lbry-redux'; import { Lbry } from 'lbry-redux';
import { doGenerateAuthToken } from 'redux/actions/auth';
import querystring from 'querystring'; import querystring from 'querystring';
const Lbryio = { const Lbryio = {
enabled: true, enabled: true,
authenticationPromise: null, authenticationPromise: null,
exchangePromise: null,
exchangeLastFetched: null,
CONNECTION_STRING: 'https://api.lbry.com/',
}; };
const CONNECTION_STRING = process.env.LBRY_APP_API_URL const EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000;
? process.env.LBRY_APP_API_URL.replace(/\/*$/, '/') // exactly one slash at the end const INTERNAL_APIS_DOWN = 'internal_apis_down';
: 'https://api.lbry.io/';
// 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') => { Lbryio.call = (resource, action, params = {}, method = 'get') => {
if (!Lbryio.enabled) { if (!Lbryio.enabled) {
@ -24,16 +31,22 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => {
if (response.status >= 200 && response.status < 300) { if (response.status >= 200 && response.status < 300) {
return response.json(); return response.json();
} }
return response.json().then(json => {
let error; if (response.status === 500) {
if (json.error) { return Promise.reject(INTERNAL_APIS_DOWN);
error = new Error(json.error); }
} else {
error = new Error('Unknown API error signature'); if (response)
} return response.json().then(json => {
error.response = response; // This is primarily a hack used in actions/user.js let error;
return Promise.reject(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) { function makeRequest(url, options) {
@ -42,8 +55,15 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => {
return Lbryio.getAuthToken().then(token => { return Lbryio.getAuthToken().then(token => {
const fullParams = { auth_token: token, ...params }; const fullParams = { auth_token: token, ...params };
Object.keys(fullParams).forEach(key => {
const value = fullParams[key];
if (typeof value === 'object') {
fullParams[key] = JSON.stringify(value);
}
});
const qs = querystring.stringify(fullParams); const qs = querystring.stringify(fullParams);
let url = `${CONNECTION_STRING}${resource}/${action}?${qs}`; let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`;
let options = { let options = {
method: 'GET', method: 'GET',
@ -57,7 +77,7 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => {
}, },
body: qs, body: qs,
}; };
url = `${CONNECTION_STRING}${resource}/${action}`; url = `${Lbryio.CONNECTION_STRING}${resource}/${action}`;
} }
return makeRequest(url, options).then(response => response.data); return makeRequest(url, options).then(response => response.data);
@ -70,7 +90,11 @@ Lbryio.getAuthToken = () =>
new Promise(resolve => { new Promise(resolve => {
if (Lbryio.authToken) { if (Lbryio.authToken) {
resolve(Lbryio.authToken); resolve(Lbryio.authToken);
} else { } else if (Lbryio.overrides.getAuthToken) {
Lbryio.overrides.getAuthToken().then(token => {
resolve(token);
});
} else if (typeof window !== 'undefined') {
const { store } = window; const { store } = window;
if (store) { if (store) {
const state = store.getState(); const state = store.getState();
@ -79,23 +103,27 @@ Lbryio.getAuthToken = () =>
resolve(token); resolve(token);
} }
resolve(null);
} else {
resolve(null); resolve(null);
} }
}); });
Lbryio.getCurrentUser = () => Lbryio.call('user', 'me'); Lbryio.getCurrentUser = () => Lbryio.call('user', 'me');
Lbryio.authenticate = () => { Lbryio.authenticate = (domain, language) => {
if (!Lbryio.enabled) { if (!Lbryio.enabled) {
const params = {
id: 1,
primary_email: 'disabled@lbry.io',
has_verified_email: true,
is_identity_verified: true,
is_reward_approved: false,
language: language || 'en',
};
return new Promise(resolve => { return new Promise(resolve => {
resolve({ resolve(params);
id: 1,
language: 'en',
primary_email: 'disabled@lbry.io',
has_verified_email: true,
is_identity_verified: true,
is_reward_approved: false,
});
}); });
} }
@ -109,23 +137,66 @@ Lbryio.authenticate = () => {
// check that token works // check that token works
return Lbryio.getCurrentUser() return Lbryio.getCurrentUser()
.then(() => true) .then(user => user)
.catch(() => false); .catch(error => {
if (error === INTERNAL_APIS_DOWN) {
throw new Error('Internal APIS down');
}
return false;
});
}) })
.then(isTokenValid => { .then(user => {
if (isTokenValid) { if (user) {
return reject; return user;
} }
return Lbry.status().then(status => { return Lbry.status()
const { store } = window; .then(
if (store) { status =>
store.dispatch(doGenerateAuthToken(status.installation_id)); new Promise((res, rej) => {
return resolve(); const appId =
} domain && domain !== 'lbry.tv'
? (domain.replace(/[.]/gi, '') + status.installation_id).slice(0, 66)
: status.installation_id;
Lbryio.call(
'user',
'new',
{
auth_token: '',
language: language || 'en',
app_id: appId,
},
'post'
)
.then(response => {
if (!response.auth_token) {
throw new Error('auth_token was not set in the response');
}
return reject(); const { store } = window;
}); if (Lbryio.overrides.setAuthToken) {
Lbryio.overrides.setAuthToken(response.auth_token);
}
if (store) {
store.dispatch({
type: ACTIONS.GENERATE_AUTH_TOKEN_SUCCESS,
data: { authToken: response.auth_token },
});
}
Lbryio.authToken = response.auth_token;
return res(response);
})
.catch(error => rej(error));
})
)
.then(newUser => {
if (!newUser) {
return Lbryio.getCurrentUser();
}
return newUser;
});
}) })
.then(resolve, reject); .then(resolve, reject);
}); });
@ -135,8 +206,33 @@ Lbryio.authenticate = () => {
}; };
Lbryio.getStripeToken = () => Lbryio.getStripeToken = () =>
CONNECTION_STRING.startsWith('http://localhost:') Lbryio.CONNECTION_STRING.startsWith('http://localhost:')
? 'pk_test_NoL1JWL7i1ipfhVId5KfDZgo' ? 'pk_test_NoL1JWL7i1ipfhVId5KfDZgo'
: 'pk_live_e8M4dRNnCCbmpZzduEUZBgJO'; : '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;
};
export default Lbryio; export default Lbryio;

View file

@ -0,0 +1,52 @@
import Lbryio from 'lbryio';
import * as ACTIONS from 'constants/action_types';
const CHECK_BLACK_LISTED_CONTENT_INTERVAL = 60 * 60 * 1000;
export function doFetchBlackListedOutpoints() {
return dispatch => {
dispatch({
type: ACTIONS.FETCH_BLACK_LISTED_CONTENT_STARTED,
});
const success = ({ outpoints }) => {
const splitOutpoints = [];
if (outpoints) {
outpoints.forEach((outpoint, index) => {
const [txid, nout] = outpoint.split(':');
splitOutpoints[index] = { txid, nout: Number.parseInt(nout, 10) };
});
}
dispatch({
type: ACTIONS.FETCH_BLACK_LISTED_CONTENT_COMPLETED,
data: {
outpoints: splitOutpoints,
success: true,
},
});
};
const failure = ({ error }) => {
dispatch({
type: ACTIONS.FETCH_BLACK_LISTED_CONTENT_FAILED,
data: {
error,
success: false,
},
});
};
Lbryio.call('file', 'list_blocked', {
auth_token: '',
}).then(success, failure);
};
}
export function doBlackListedOutpointsSubscribe() {
return dispatch => {
dispatch(doFetchBlackListedOutpoints());
setInterval(() => dispatch(doFetchBlackListedOutpoints()), CHECK_BLACK_LISTED_CONTENT_INTERVAL);
};
}

View file

@ -0,0 +1,35 @@
import * as ACTIONS from 'constants/action_types';
import Lbryio from 'lbryio';
import { selectClaimsByUri } from 'lbry-redux';
// eslint-disable-next-line import/prefer-default-export
export function doFetchCostInfoForUri(uri) {
return (dispatch, getState) => {
const state = getState();
const claim = selectClaimsByUri(state)[uri];
if (!claim) return;
function resolve(costInfo) {
dispatch({
type: ACTIONS.FETCH_COST_INFO_COMPLETED,
data: {
uri,
costInfo,
},
});
}
const fee = claim.value ? claim.value.fee : undefined;
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 });
});
}
};
}

View file

@ -0,0 +1,47 @@
import Lbryio from 'lbryio';
import * as ACTIONS from 'constants/action_types';
const CHECK_FILTERED_CONTENT_INTERVAL = 60 * 60 * 1000;
export function doFetchFilteredOutpoints() {
return dispatch => {
dispatch({
type: ACTIONS.FETCH_FILTERED_CONTENT_STARTED,
});
const success = ({ outpoints }) => {
let formattedOutpoints = [];
if (outpoints) {
formattedOutpoints = outpoints.map(outpoint => {
const [txid, nout] = outpoint.split(':');
return { txid, nout: Number.parseInt(nout, 10) };
});
}
dispatch({
type: ACTIONS.FETCH_FILTERED_CONTENT_COMPLETED,
data: {
outpoints: formattedOutpoints,
},
});
};
const failure = ({ error }) => {
dispatch({
type: ACTIONS.FETCH_FILTERED_CONTENT_FAILED,
data: {
error,
},
});
};
Lbryio.call('file', 'list_filtered', { auth_token: '' }).then(success, failure);
};
}
export function doFilteredOutpointsSubscribe() {
return dispatch => {
dispatch(doFetchFilteredOutpoints());
setInterval(() => dispatch(doFetchFilteredOutpoints()), CHECK_FILTERED_CONTENT_INTERVAL);
};
}

View file

@ -0,0 +1,78 @@
import Lbryio from 'lbryio';
import { batchActions, doResolveUris } from 'lbry-redux';
import * as ACTIONS from 'constants/action_types';
export function doFetchFeaturedUris(offloadResolve = false) {
return dispatch => {
dispatch({
type: ACTIONS.FETCH_FEATURED_CONTENT_STARTED,
});
const success = ({ Uris }) => {
let urisToResolve = [];
Object.keys(Uris).forEach(category => {
urisToResolve = [...urisToResolve, ...Uris[category]];
});
const actions = [
{
type: ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED,
data: {
uris: Uris,
success: true,
},
},
];
if (urisToResolve.length && !offloadResolve) {
actions.push(doResolveUris(urisToResolve));
}
dispatch(batchActions(...actions));
};
const failure = () => {
dispatch({
type: ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED,
data: {
uris: {},
},
});
};
Lbryio.call('file', 'list_homepage').then(success, failure);
};
}
export function doFetchTrendingUris() {
return dispatch => {
dispatch({
type: ACTIONS.FETCH_TRENDING_CONTENT_STARTED,
});
const success = data => {
const urisToResolve = data.map(uri => uri.url);
const actions = [
doResolveUris(urisToResolve),
{
type: ACTIONS.FETCH_TRENDING_CONTENT_COMPLETED,
data: {
uris: data,
success: true,
},
},
];
dispatch(batchActions(...actions));
};
const failure = () => {
dispatch({
type: ACTIONS.FETCH_TRENDING_CONTENT_COMPLETED,
data: {
uris: [],
},
});
};
Lbryio.call('file', 'list_trending').then(success, failure);
};
}

View file

@ -1,113 +0,0 @@
import Lbryio from 'lbryio';
import { doNotify, ACTIONS, MODALS } from 'lbry-redux';
import { selectUnclaimedRewards } from 'redux/selectors/rewards';
import { selectUserIsRewardApproved } from 'redux/selectors/user';
import rewards from 'rewards';
export function doRewardList() {
return dispatch => {
dispatch({
type: ACTIONS.FETCH_REWARDS_STARTED,
});
Lbryio.call('reward', 'list', { multiple_rewards_per_type: true })
.then(userRewards => {
dispatch({
type: ACTIONS.FETCH_REWARDS_COMPLETED,
data: { userRewards },
});
})
.catch(() => {
dispatch({
type: ACTIONS.FETCH_REWARDS_COMPLETED,
data: { userRewards: [] },
});
});
};
}
export function doClaimRewardType(rewardType, options) {
return (dispatch, getState) => {
const state = getState();
const unclaimedRewards = selectUnclaimedRewards(state);
const reward = unclaimedRewards.find(ur => ur.reward_type === rewardType);
const userIsRewardApproved = selectUserIsRewardApproved(state);
if (!reward || reward.transaction_id) {
// already claimed or doesn't exist, do nothing
return;
}
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
const action = doNotify({
id: MODALS.REWARD_APPROVAL_REQUIRED,
isError: false,
});
dispatch(action);
return;
}
dispatch({
type: ACTIONS.CLAIM_REWARD_STARTED,
data: { reward },
});
const success = successReward => {
dispatch({
type: ACTIONS.CLAIM_REWARD_SUCCESS,
data: {
reward: successReward,
},
});
if (successReward.reward_type === rewards.TYPE_NEW_USER) {
const action = doNotify({
id: MODALS.FIRST_REWARD,
isError: false,
});
dispatch(action);
}
};
const failure = error => {
dispatch({
type: ACTIONS.CLAIM_REWARD_FAILURE,
data: {
reward,
error: !options || !options.failSilently ? error : undefined,
},
});
};
rewards.claimReward(rewardType).then(success, failure);
};
}
export 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 {
[rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_FEATURED_DOWNLOAD].forEach(type => {
dispatch(doClaimRewardType(type, { failSilently: true }));
});
}
};
}
export function doClaimRewardClearError(reward) {
return dispatch => {
dispatch({
type: ACTIONS.CLAIM_REWARD_CLEAR_ERROR,
data: { reward },
});
};
}

View file

@ -0,0 +1,32 @@
// @flow
import Lbryio from 'lbryio';
import * as ACTIONS from 'constants/action_types';
export const doFetchViewCount = (claimIdCsv: string) => dispatch => {
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_STARTED });
return Lbryio.call('file', 'view_count', { claim_id: claimIdCsv })
.then((result: Array<number>) => {
const viewCounts = result;
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_COMPLETED, data: { claimIdCsv, viewCounts } });
})
.catch(error => {
dispatch({ type: ACTIONS.FETCH_VIEW_COUNT_FAILED, data: error });
});
};
export const doFetchSubCount = (claimId: string) => dispatch => {
dispatch({ type: ACTIONS.FETCH_SUB_COUNT_STARTED });
return Lbryio.call('subscription', 'sub_count', { claim_id: claimId })
.then((result: Array<number>) => {
const subCount = result[0];
dispatch({
type: ACTIONS.FETCH_SUB_COUNT_COMPLETED,
data: { claimId, subCount },
});
})
.catch(error => {
dispatch({ type: ACTIONS.FETCH_SUB_COUNT_FAILED, data: error });
});
};

288
src/redux/actions/sync.js Normal file
View file

@ -0,0 +1,288 @@
import * as ACTIONS from 'constants/action_types';
import Lbryio from 'lbryio';
import { Lbry, doWalletEncrypt, doWalletDecrypt } from 'lbry-redux';
const NO_WALLET_ERROR = 'no wallet found for this user';
export function doSetDefaultAccount(success, failure) {
return dispatch => {
dispatch({
type: ACTIONS.SET_DEFAULT_ACCOUNT,
});
Lbry.account_list()
.then(accountList => {
const { lbc_mainnet: accounts } = accountList;
let defaultId;
for (let i = 0; i < accounts.length; ++i) {
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) {
Lbry.account_set({ account_id: defaultId, default: true })
.then(() => {
if (success) {
success();
}
})
.catch(err => {
if (failure) {
failure(err);
}
});
} else if (failure) {
// no default account to set
failure('Could not set a default account'); // fail
}
})
.catch(err => {
if (failure) {
failure(err);
}
});
};
}
export function doSetSync(oldHash, newHash, data) {
return dispatch => {
dispatch({
type: ACTIONS.SET_SYNC_STARTED,
});
return Lbryio.call('sync', 'set', { old_hash: oldHash, new_hash: newHash, data }, 'post')
.then(response => {
if (!response.hash) {
throw Error('No hash returned for sync/set.');
}
return dispatch({
type: ACTIONS.SET_SYNC_COMPLETED,
data: { syncHash: response.hash },
});
})
.catch(error => {
dispatch({
type: ACTIONS.SET_SYNC_FAILED,
data: { error },
});
});
};
}
export function doGetSync(passedPassword, callback) {
const password = passedPassword === null || passedPassword === undefined ? '' : passedPassword;
function handleCallback(error, hasNewData) {
if (callback) {
if (typeof callback !== 'function') {
throw new Error('Second argument passed to "doGetSync" must be a function');
}
callback(error, hasNewData);
}
}
return dispatch => {
dispatch({
type: ACTIONS.GET_SYNC_STARTED,
});
const data = {};
Lbry.wallet_status()
.then(status => {
if (status.is_locked) {
return Lbry.wallet_unlock({ password });
}
// Wallet is already unlocked
return true;
})
.then(isUnlocked => {
if (isUnlocked) {
return Lbry.sync_hash();
}
data.unlockFailed = true;
throw new Error();
})
.then(hash => Lbryio.call('sync', 'get', { hash }, 'post'))
.then(response => {
const syncHash = response.hash;
data.syncHash = syncHash;
data.syncData = response.data;
data.changed = response.changed;
data.hasSyncedWallet = true;
if (response.changed) {
return Lbry.sync_apply({ password, data: response.data, blocking: true });
}
})
.then(response => {
if (!response) {
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
handleCallback(null, data.changed);
return;
}
const { hash: walletHash, data: walletData } = response;
if (walletHash !== data.syncHash) {
// different local hash, need to synchronise
dispatch(doSetSync(data.syncHash, walletHash, walletData));
}
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
handleCallback(null, data.changed);
})
.catch(syncAttemptError => {
if (data.unlockFailed) {
dispatch({ type: ACTIONS.GET_SYNC_FAILED, data: { error: syncAttemptError } });
if (password !== '') {
dispatch({ type: ACTIONS.SYNC_APPLY_BAD_PASSWORD });
}
handleCallback(syncAttemptError);
} else if (data.hasSyncedWallet) {
const error =
(syncAttemptError && syncAttemptError.message) || 'Error getting synced wallet';
dispatch({
type: ACTIONS.GET_SYNC_FAILED,
data: {
error,
},
});
// 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: ACTIONS.SYNC_APPLY_BAD_PASSWORD });
}
handleCallback(error);
} else {
// user doesn't have a synced wallet
dispatch({
type: ACTIONS.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
if (syncAttemptError.message === NO_WALLET_ERROR) {
Lbry.sync_apply({ password })
.then(({ hash: walletHash, data: syncApplyData }) => {
dispatch(doSetSync('', walletHash, syncApplyData, password));
handleCallback();
})
.catch(syncApplyError => {
handleCallback(syncApplyError);
});
}
}
});
};
}
export function doSyncApply(syncHash, syncData, password) {
return dispatch => {
dispatch({
type: ACTIONS.SYNC_APPLY_STARTED,
});
Lbry.sync_apply({ password, data: syncData })
.then(({ hash: walletHash, data: walletData }) => {
dispatch({
type: ACTIONS.SYNC_APPLY_COMPLETED,
});
if (walletHash !== syncHash) {
// different local hash, need to synchronise
dispatch(doSetSync(syncHash, walletHash, walletData));
}
})
.catch(() => {
dispatch({
type: ACTIONS.SYNC_APPLY_FAILED,
data: {
error:
'Invalid password specified. Please enter the password for your previously synchronised wallet.',
},
});
});
};
}
export function doCheckSync() {
return dispatch => {
dispatch({
type: ACTIONS.GET_SYNC_STARTED,
});
Lbry.sync_hash().then(hash => {
Lbryio.call('sync', 'get', { hash }, 'post')
.then(response => {
const data = {
hasSyncedWallet: true,
syncHash: response.hash,
syncData: response.data,
hashChanged: response.changed,
};
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
})
.catch(() => {
// user doesn't have a synced wallet
dispatch({
type: ACTIONS.GET_SYNC_COMPLETED,
data: { hasSyncedWallet: false, syncHash: null },
});
});
});
};
}
export function doResetSync() {
return dispatch =>
new Promise(resolve => {
dispatch({ type: ACTIONS.SYNC_RESET });
resolve();
});
}
export function doSyncEncryptAndDecrypt(oldPassword, newPassword, encrypt) {
return dispatch => {
const data = {};
return Lbry.sync_hash()
.then(hash => Lbryio.call('sync', 'get', { hash }, 'post'))
.then(syncGetResponse => {
data.oldHash = syncGetResponse.hash;
return Lbry.sync_apply({ password: oldPassword, data: syncGetResponse.data });
})
.then(() => {
if (encrypt) {
dispatch(doWalletEncrypt(newPassword));
} else {
dispatch(doWalletDecrypt());
}
})
.then(() => Lbry.sync_apply({ password: newPassword }))
.then(syncApplyResponse => {
if (syncApplyResponse.hash !== data.oldHash) {
return dispatch(doSetSync(data.oldHash, syncApplyResponse.hash, syncApplyResponse.data));
}
})
.catch(console.error);
};
}

View file

@ -1,93 +0,0 @@
import { ACTIONS, MODALS, Lbry, doNotify } from 'lbry-redux';
import { doRewardList } from 'redux/actions/rewards';
import Lbryio from 'lbryio';
export function doFetchInviteStatus() {
return dispatch => {
dispatch({
type: ACTIONS.USER_INVITE_STATUS_FETCH_STARTED,
});
Lbryio.call('user', 'invite_status')
.then(status => {
dispatch({
type: ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS,
data: {
invitesRemaining: status.invites_remaining ? status.invites_remaining : 0,
invitees: status.invitees,
},
});
})
.catch(error => {
dispatch({
type: ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE,
data: { error },
});
});
};
}
export function doInstallNew(appVersion, deviceId = null) {
const payload = { app_version: appVersion, device_id: deviceId };
Lbry.status().then(status => {
payload.app_id = status.installation_id;
payload.node_id = status.lbry_id;
Lbry.version().then(version => {
payload.daemon_version = version.lbrynet_version;
payload.operating_system = 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 deviceId params?
export function doAuthenticate(appVersion, deviceId = null) {
return dispatch => {
dispatch({
type: ACTIONS.AUTHENTICATION_STARTED,
});
Lbryio.authenticate()
.then(user => {
// analytics.setUser(user);
dispatch({
type: ACTIONS.AUTHENTICATION_SUCCESS,
data: { user },
});
dispatch(doRewardList());
dispatch(doFetchInviteStatus());
doInstallNew(appVersion, deviceId);
})
.catch(error => {
dispatch(doNotify({ id: MODALS.AUTHENTICATION_FAILURE }));
dispatch({
type: ACTIONS.AUTHENTICATION_FAILURE,
data: { error },
});
});
};
}
export function doUserFetch() {
return dispatch => {
dispatch({
type: ACTIONS.USER_FETCH_STARTED,
});
Lbryio.getCurrentUser()
.then(user => {
// analytics.setUser(user);
dispatch(doRewardList());
dispatch({
type: ACTIONS.USER_FETCH_SUCCESS,
data: { user },
});
})
.catch(error => {
dispatch({
type: ACTIONS.USER_FETCH_FAILURE,
data: { error },
});
});
};
}

12
src/redux/actions/web.js Normal file
View file

@ -0,0 +1,12 @@
// @flow
import * as ACTIONS from 'constants/action_types';
export const doUpdateUploadProgress = (
progress: string,
params: { [key: string]: any },
xhr: any
) => (dispatch: Dispatch) =>
dispatch({
type: ACTIONS.UPDATE_UPLOAD_PROGRESS,
data: { progress, params, xhr },
});

View file

@ -18,7 +18,7 @@ reducers[ACTIONS.GENERATE_AUTH_TOKEN_STARTED] = state =>
reducers[ACTIONS.GENERATE_AUTH_TOKEN_SUCCESS] = (state, action) => reducers[ACTIONS.GENERATE_AUTH_TOKEN_SUCCESS] = (state, action) =>
Object.assign({}, state, { Object.assign({}, state, {
authToken: action.authToken, authToken: action.data.authToken,
authenticating: false, authenticating: false,
}); });

View file

@ -0,0 +1,37 @@
import * as ACTIONS from 'constants/action_types';
import { handleActions } from 'util/redux-utils';
const defaultState = {
fetchingBlackListedOutpoints: false,
fetchingBlackListedOutpointsSucceed: undefined,
blackListedOutpoints: undefined,
};
export const blacklistReducer = handleActions(
{
[ACTIONS.FETCH_BLACK_LISTED_CONTENT_STARTED]: state => ({
...state,
fetchingBlackListedOutpoints: true,
}),
[ACTIONS.FETCH_BLACK_LISTED_CONTENT_COMPLETED]: (state, action) => {
const { outpoints, success } = action.data;
return {
...state,
fetchingBlackListedOutpoints: false,
fetchingBlackListedOutpointsSucceed: success,
blackListedOutpoints: outpoints,
};
},
[ACTIONS.FETCH_BLACK_LISTED_CONTENT_FAILED]: (state, action) => {
const { error, success } = action.data;
return {
...state,
fetchingBlackListedOutpoints: false,
fetchingBlackListedOutpointsSucceed: success,
fetchingBlackListedOutpointsError: error,
};
},
},
defaultState
);

View file

@ -0,0 +1,38 @@
import { handleActions } from 'util/redux-utils';
import * as ACTIONS from 'constants/action_types';
const defaultState = {
fetching: {},
byUri: {},
};
export const costInfoReducer = handleActions(
{
[ACTIONS.FETCH_COST_INFO_STARTED]: (state, action) => {
const { uri } = action.data;
const newFetching = Object.assign({}, state.fetching);
newFetching[uri] = true;
return {
...state,
fetching: newFetching,
};
},
[ACTIONS.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
);

View file

@ -0,0 +1,34 @@
import * as ACTIONS from 'constants/action_types';
import { handleActions } from 'util/redux-utils';
const defaultState = {
loading: false,
filteredOutpoints: undefined,
};
export const filteredReducer = handleActions(
{
[ACTIONS.FETCH_FILTERED_CONTENT_STARTED]: state => ({
...state,
loading: true,
}),
[ACTIONS.FETCH_FILTERED_CONTENT_COMPLETED]: (state, action) => {
const { outpoints } = action.data;
return {
...state,
loading: false,
filteredOutpoints: outpoints,
};
},
[ACTIONS.FETCH_FILTERED_CONTENT_FAILED]: (state, action) => {
const { error } = action.data;
return {
...state,
loading: false,
fetchingFilteredOutpointsError: error,
};
},
},
defaultState
);

View file

@ -0,0 +1,48 @@
import { handleActions } from 'util/redux-utils';
import * as ACTIONS from 'constants/action_types';
const defaultState = {
fetchingFeaturedContent: false,
fetchingFeaturedContentFailed: false,
featuredUris: undefined,
fetchingTrendingContent: false,
fetchingTrendingContentFailed: false,
trendingUris: undefined,
};
export const homepageReducer = handleActions(
{
[ACTIONS.FETCH_FEATURED_CONTENT_STARTED]: state => ({
...state,
fetchingFeaturedContent: true,
}),
[ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED]: (state, action) => {
const { uris, success } = action.data;
return {
...state,
fetchingFeaturedContent: false,
fetchingFeaturedContentFailed: !success,
featuredUris: uris,
};
},
[ACTIONS.FETCH_TRENDING_CONTENT_STARTED]: state => ({
...state,
fetchingTrendingContent: true,
}),
[ACTIONS.FETCH_TRENDING_CONTENT_COMPLETED]: (state, action) => {
const { uris, success } = action.data;
return {
...state,
fetchingTrendingContent: false,
fetchingTrendingContentFailed: !success,
trendingUris: uris,
};
},
},
defaultState
);

View file

@ -1,98 +0,0 @@
import { ACTIONS } from 'lbry-redux';
const reducers = {};
const defaultState = {
fetching: false,
claimedRewardsById: {}, // id => reward
unclaimedRewards: [],
claimPendingByType: {},
claimErrorsByType: {},
};
reducers[ACTIONS.FETCH_REWARDS_STARTED] = state =>
Object.assign({}, state, {
fetching: true,
});
reducers[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);
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[ACTIONS.CLAIM_REWARD_STARTED] = (state, action) => {
const { reward } = action.data;
return setClaimRewardState(state, reward, true, '');
};
reducers[ACTIONS.CLAIM_REWARD_SUCCESS] = (state, action) => {
const { reward } = action.data;
const { unclaimedRewards } = state;
const index = unclaimedRewards.findIndex(ur => ur.reward_type === reward.reward_type);
unclaimedRewards.splice(index, 1);
const { claimedRewardsById } = state;
claimedRewardsById[reward.id] = reward;
const newState = {
...state,
unclaimedRewards: [...unclaimedRewards],
claimedRewardsById: { ...claimedRewardsById },
};
return setClaimRewardState(newState, reward, false, '');
};
reducers[ACTIONS.CLAIM_REWARD_FAILURE] = (state, action) => {
const { reward, error } = action.data;
return setClaimRewardState(state, reward, false, error ? error.message : '');
};
reducers[ACTIONS.CLAIM_REWARD_CLEAR_ERROR] = (state, action) => {
const { reward } = action.data;
return setClaimRewardState(state, reward, state.claimPendingByType[reward.reward_type], '');
};
export function rewardsReducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -0,0 +1,55 @@
import { handleActions } from 'util/redux-utils';
import * as ACTIONS from 'constants/action_types';
const defaultState = {
fetchingViewCount: false,
viewCountError: undefined,
viewCountById: {},
fetchingSubCount: false,
subCountError: undefined,
subCountById: {},
};
export const statsReducer = handleActions(
{
[ACTIONS.FETCH_VIEW_COUNT_STARTED]: state => ({ ...state, fetchingViewCount: true }),
[ACTIONS.FETCH_VIEW_COUNT_FAILED]: (state, action) => ({
...state,
viewCountError: action.data,
}),
[ACTIONS.FETCH_VIEW_COUNT_COMPLETED]: (state, action) => {
const { claimIdCsv, viewCounts } = action.data;
const viewCountById = Object.assign({}, state.viewCountById);
const claimIds = claimIdCsv.split(',');
if (claimIds.length === viewCounts.length) {
claimIds.forEach((claimId, index) => {
viewCountById[claimId] = viewCounts[index];
});
}
return {
...state,
fetchingViewCount: false,
viewCountById,
};
},
[ACTIONS.FETCH_SUB_COUNT_STARTED]: state => ({ ...state, fetchingSubCount: true }),
[ACTIONS.FETCH_SUB_COUNT_FAILED]: (state, action) => ({
...state,
subCountError: action.data,
}),
[ACTIONS.FETCH_SUB_COUNT_COMPLETED]: (state, action) => {
const { claimId, subCount } = action.data;
const subCountById = { ...state.subCountById, [claimId]: subCount };
return {
...state,
fetchingSubCount: false,
subCountById,
};
},
},
defaultState
);

View file

@ -0,0 +1,89 @@
import * as ACTIONS from 'constants/action_types';
const reducers = {};
const defaultState = {
hasSyncedWallet: false,
syncHash: null,
syncData: null,
setSyncErrorMessage: null,
getSyncErrorMessage: null,
syncApplyErrorMessage: '',
syncApplyIsPending: false,
syncApplyPasswordError: false,
getSyncIsPending: false,
setSyncIsPending: false,
hashChanged: false,
};
reducers[ACTIONS.GET_SYNC_STARTED] = state =>
Object.assign({}, state, {
getSyncIsPending: true,
getSyncErrorMessage: null,
});
reducers[ACTIONS.GET_SYNC_COMPLETED] = (state, action) =>
Object.assign({}, state, {
syncHash: action.data.syncHash,
syncData: action.data.syncData,
hasSyncedWallet: action.data.hasSyncedWallet,
getSyncIsPending: false,
hashChanged: action.data.hashChanged,
});
reducers[ACTIONS.GET_SYNC_FAILED] = (state, action) =>
Object.assign({}, state, {
getSyncIsPending: false,
getSyncErrorMessage: action.data.error,
});
reducers[ACTIONS.SET_SYNC_STARTED] = state =>
Object.assign({}, state, {
setSyncIsPending: true,
setSyncErrorMessage: null,
});
reducers[ACTIONS.SET_SYNC_FAILED] = (state, action) =>
Object.assign({}, state, {
setSyncIsPending: false,
setSyncErrorMessage: action.data.error,
});
reducers[ACTIONS.SET_SYNC_COMPLETED] = (state, action) =>
Object.assign({}, state, {
setSyncIsPending: false,
setSyncErrorMessage: null,
hasSyncedWallet: true, // sync was successful, so the user has a synced wallet at this point
syncHash: action.data.syncHash,
});
reducers[ACTIONS.SYNC_APPLY_STARTED] = state =>
Object.assign({}, state, {
syncApplyPasswordError: false,
syncApplyIsPending: true,
syncApplyErrorMessage: '',
});
reducers[ACTIONS.SYNC_APPLY_COMPLETED] = state =>
Object.assign({}, state, {
syncApplyIsPending: false,
syncApplyErrorMessage: '',
});
reducers[ACTIONS.SYNC_APPLY_FAILED] = (state, action) =>
Object.assign({}, state, {
syncApplyIsPending: false,
syncApplyErrorMessage: action.data.error,
});
reducers[ACTIONS.SYNC_APPLY_BAD_PASSWORD] = state =>
Object.assign({}, state, {
syncApplyPasswordError: true,
});
reducers[ACTIONS.SYNC_RESET] = () => defaultState;
export function syncReducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -1,222 +0,0 @@
import { ACTIONS } from 'lbry-redux';
const reducers = {};
const defaultState = {
authenticationIsPending: false,
userIsPending: false,
emailNewIsPending: false,
emailNewErrorMessage: '',
emailToVerify: '',
inviteNewErrorMessage: '',
inviteNewIsPending: false,
inviteStatusIsPending: false,
invitesRemaining: undefined,
invitees: undefined,
user: undefined,
};
reducers[ACTIONS.AUTHENTICATION_STARTED] = state =>
Object.assign({}, state, {
authenticationIsPending: true,
userIsPending: true,
user: defaultState.user,
});
reducers[ACTIONS.AUTHENTICATION_SUCCESS] = (state, action) =>
Object.assign({}, state, {
authenticationIsPending: false,
userIsPending: false,
user: action.data.user,
});
reducers[ACTIONS.AUTHENTICATION_FAILURE] = state =>
Object.assign({}, state, {
authenticationIsPending: false,
userIsPending: false,
user: null,
});
reducers[ACTIONS.USER_FETCH_STARTED] = state =>
Object.assign({}, state, {
userIsPending: true,
user: defaultState.user,
});
reducers[ACTIONS.USER_FETCH_SUCCESS] = (state, action) =>
Object.assign({}, state, {
userIsPending: false,
user: action.data.user,
});
reducers[ACTIONS.USER_FETCH_FAILURE] = state =>
Object.assign({}, state, {
userIsPending: true,
user: null,
});
reducers[ACTIONS.USER_PHONE_NEW_STARTED] = (state, action) => {
const user = Object.assign({}, state.user);
user.country_code = action.data.country_code;
return Object.assign({}, state, {
phoneNewIsPending: true,
phoneNewErrorMessage: '',
user,
});
};
reducers[ACTIONS.USER_PHONE_NEW_SUCCESS] = (state, action) =>
Object.assign({}, state, {
phoneToVerify: action.data.phone,
phoneNewIsPending: false,
});
reducers[ACTIONS.USER_PHONE_RESET] = state =>
Object.assign({}, state, {
phoneToVerify: null,
});
reducers[ACTIONS.USER_PHONE_NEW_FAILURE] = (state, action) =>
Object.assign({}, state, {
phoneNewIsPending: false,
phoneNewErrorMessage: action.data.error,
});
reducers[ACTIONS.USER_PHONE_VERIFY_STARTED] = state =>
Object.assign({}, state, {
phoneVerifyIsPending: true,
phoneVerifyErrorMessage: '',
});
reducers[ACTIONS.USER_PHONE_VERIFY_SUCCESS] = (state, action) =>
Object.assign({}, state, {
phoneToVerify: '',
phoneVerifyIsPending: false,
user: action.data.user,
});
reducers[ACTIONS.USER_PHONE_VERIFY_FAILURE] = (state, action) =>
Object.assign({}, state, {
phoneVerifyIsPending: false,
phoneVerifyErrorMessage: action.data.error,
});
reducers[ACTIONS.USER_EMAIL_NEW_STARTED] = state =>
Object.assign({}, state, {
emailNewIsPending: true,
emailNewErrorMessage: '',
});
reducers[ACTIONS.USER_EMAIL_NEW_SUCCESS] = (state, action) => {
const user = Object.assign({}, state.user);
user.primary_email = action.data.email;
return Object.assign({}, state, {
emailToVerify: action.data.email,
emailNewIsPending: false,
user,
});
};
reducers[ACTIONS.USER_EMAIL_NEW_EXISTS] = (state, action) =>
Object.assign({}, state, {
emailToVerify: action.data.email,
emailNewIsPending: false,
});
reducers[ACTIONS.USER_EMAIL_NEW_FAILURE] = (state, action) =>
Object.assign({}, state, {
emailNewIsPending: false,
emailNewErrorMessage: action.data.error,
});
reducers[ACTIONS.USER_EMAIL_VERIFY_STARTED] = state =>
Object.assign({}, state, {
emailVerifyIsPending: true,
emailVerifyErrorMessage: '',
});
reducers[ACTIONS.USER_EMAIL_VERIFY_SUCCESS] = (state, action) => {
const user = Object.assign({}, state.user);
user.primary_email = action.data.email;
return Object.assign({}, state, {
emailToVerify: '',
emailVerifyIsPending: false,
user,
});
};
reducers[ACTIONS.USER_EMAIL_VERIFY_FAILURE] = (state, action) =>
Object.assign({}, state, {
emailVerifyIsPending: false,
emailVerifyErrorMessage: action.data.error,
});
reducers[ACTIONS.USER_IDENTITY_VERIFY_STARTED] = state =>
Object.assign({}, state, {
identityVerifyIsPending: true,
identityVerifyErrorMessage: '',
});
reducers[ACTIONS.USER_IDENTITY_VERIFY_SUCCESS] = (state, action) =>
Object.assign({}, state, {
identityVerifyIsPending: false,
identityVerifyErrorMessage: '',
user: action.data.user,
});
reducers[ACTIONS.USER_IDENTITY_VERIFY_FAILURE] = (state, action) =>
Object.assign({}, state, {
identityVerifyIsPending: false,
identityVerifyErrorMessage: action.data.error,
});
reducers[ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS] = (state, action) => {
const { token } = action.data;
return Object.assign({}, state, {
accessToken: token,
});
};
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_STARTED] = state =>
Object.assign({}, state, {
inviteStatusIsPending: true,
});
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS] = (state, action) =>
Object.assign({}, state, {
inviteStatusIsPending: false,
invitesRemaining: action.data.invitesRemaining,
invitees: action.data.invitees,
});
reducers[ACTIONS.USER_INVITE_NEW_STARTED] = state =>
Object.assign({}, state, {
inviteNewIsPending: true,
inviteNewErrorMessage: '',
});
reducers[ACTIONS.USER_INVITE_NEW_SUCCESS] = state =>
Object.assign({}, state, {
inviteNewIsPending: false,
inviteNewErrorMessage: '',
});
reducers[ACTIONS.USER_INVITE_NEW_FAILURE] = (state, action) =>
Object.assign({}, state, {
inviteNewIsPending: false,
inviteNewErrorMessage: action.data.error.message,
});
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE] = state =>
Object.assign({}, state, {
inviteStatusIsPending: false,
invitesRemaining: null,
invitees: null,
});
export function userReducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

62
src/redux/reducers/web.js Normal file
View file

@ -0,0 +1,62 @@
// @flow
import * as ACTIONS from 'constants/action_types';
/*
test mock:
currentUploads: {
'test#upload': {
progress: 50,
params: {
name: 'steve',
thumbnail_url: 'https://dev2.spee.ch/4/KMNtoSZ009fawGz59VG8PrID.jpeg',
},
},
},
*/
export type Params = {
channel?: string,
name: string,
thumbnail_url: ?string,
title: ?string,
};
export type UploadItem = {
progess: string,
params: Params,
xhr?: any,
};
export type TvState = {
currentUploads: { [key: string]: UploadItem },
};
const reducers = {};
const defaultState: TvState = {
currentUploads: {},
};
reducers[ACTIONS.UPDATE_UPLOAD_PROGRESS] = (state: TvState, 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 };
};
export function webReducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -1,5 +1,7 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
const selectState = state => state.authToken || {}; const selectState = state => state.auth || {};
export const selectAuthToken = createSelector(selectState, state => state.authToken); export const selectAuthToken = createSelector(selectState, state => state.authToken);
export const selectIsAuthenticating = createSelector(selectState, state => state.authenticating);

View file

@ -0,0 +1,20 @@
import { createSelector } from 'reselect';
export const selectState = state => state.blacklist || {};
export const selectBlackListedOutpoints = createSelector(
selectState,
state => state.blackListedOutpoints
);
export const selectBlacklistedOutpointMap = createSelector(
selectBlackListedOutpoints,
outpoints =>
outpoints
? outpoints.reduce((acc, val) => {
const outpoint = `${val.txid}:${val.nout}`;
acc[outpoint] = 1;
return acc;
}, {})
: {}
);

View file

@ -0,0 +1,13 @@
import { createSelector } from 'reselect';
export const selectState = state => state.costInfo || {};
export const selectAllCostInfoByUri = createSelector(selectState, state => state.byUri || {});
export const makeSelectCostInfoForUri = uri =>
createSelector(selectAllCostInfoByUri, costInfos => costInfos && costInfos[uri]);
export const selectFetchingCostInfo = createSelector(selectState, state => state.fetching || {});
export const makeSelectFetchingCostInfoForUri = uri =>
createSelector(selectFetchingCostInfo, fetchingByUri => fetchingByUri && fetchingByUri[uri]);

View file

@ -0,0 +1,20 @@
import { createSelector } from 'reselect';
export const selectState = state => state.filtered || {};
export const selectFilteredOutpoints = createSelector(
selectState,
state => state.filteredOutpoints
);
export const selectFilteredOutpointMap = createSelector(
selectFilteredOutpoints,
outpoints =>
outpoints
? outpoints.reduce((acc, val) => {
const outpoint = `${val.txid}:${val.nout}`;
acc[outpoint] = 1;
return acc;
}, {})
: {}
);

View file

@ -0,0 +1,17 @@
import { createSelector } from 'reselect';
const selectState = state => state.homepage || {};
export const selectFeaturedUris = createSelector(selectState, state => state.featuredUris);
export const selectFetchingFeaturedUris = createSelector(
selectState,
state => state.fetchingFeaturedContent
);
export const selectTrendingUris = createSelector(selectState, state => state.trendingUris);
export const selectFetchingTrendingUris = createSelector(
selectState,
state => state.fetchingTrendingContent
);

View file

@ -1,64 +0,0 @@
import { createSelector } from 'reselect';
const selectState = state => state.rewards || {};
export const selectUnclaimedRewardsByType = createSelector(
selectState,
state => state.unclaimedRewardsByType
);
export const selectClaimedRewardsById = createSelector(
selectState,
state => state.claimedRewardsById
);
export const selectClaimedRewards = createSelector(
selectClaimedRewardsById,
byId => Object.values(byId) || []
);
export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedRewards, rewards =>
rewards.reduce((mapParam, reward) => {
const map = mapParam;
map[reward.transaction_id] = reward;
return map;
}, {})
);
export const selectUnclaimedRewards = createSelector(selectState, state => state.unclaimedRewards);
export const selectFetchingRewards = createSelector(selectState, state => !!state.fetching);
export const selectUnclaimedRewardValue = createSelector(selectUnclaimedRewards, rewards =>
rewards.reduce((sum, reward) => sum + reward.reward_amount, 0)
);
export const selectClaimsPendingByType = createSelector(
selectState,
state => state.claimPendingByType
);
const selectIsClaimRewardPending = (state, props) =>
selectClaimsPendingByType(state, props)[props.reward_type];
export const makeSelectIsRewardClaimPending = () =>
createSelector(selectIsClaimRewardPending, isClaiming => isClaiming);
export const selectClaimErrorsByType = createSelector(
selectState,
state => state.claimErrorsByType
);
const selectClaimRewardError = (state, props) =>
selectClaimErrorsByType(state, props)[props.reward_type];
export const makeSelectClaimRewardError = () =>
createSelector(selectClaimRewardError, errorMessage => errorMessage);
const selectRewardByType = (state, rewardType) =>
selectUnclaimedRewards(state).find(reward => reward.reward_type === rewardType);
export const makeSelectRewardByType = () => createSelector(selectRewardByType, reward => reward);
export const makeSelectRewardAmountByType = () =>
createSelector(selectRewardByType, reward => (reward ? reward.reward_amount : 0));

View file

@ -0,0 +1,20 @@
import { createSelector } from 'reselect';
import { makeSelectClaimForUri } from 'lbry-redux';
const selectState = state => state.stats || {};
export const selectViewCount = createSelector(selectState, state => state.viewCountById);
export const selectSubCount = createSelector(selectState, state => state.subCountById);
export const makeSelectViewCountForUri = uri =>
createSelector(
makeSelectClaimForUri(uri),
selectViewCount,
(claim, viewCountById) => (claim ? viewCountById[claim.claim_id] || 0 : 0)
);
export const makeSelectSubCountForUri = uri =>
createSelector(
makeSelectClaimForUri(uri),
selectSubCount,
(claim, subCountById) => (claim ? subCountById[claim.claim_id] || 0 : 0)
);

View file

@ -0,0 +1,40 @@
import { createSelector } from 'reselect';
const selectState = state => state.sync || {};
export const selectHasSyncedWallet = createSelector(selectState, state => state.hasSyncedWallet);
export const selectSyncHash = createSelector(selectState, state => state.syncHash);
export const selectSyncData = createSelector(selectState, state => state.syncData);
export const selectSetSyncErrorMessage = createSelector(
selectState,
state => state.setSyncErrorMessage
);
export const selectGetSyncErrorMessage = createSelector(
selectState,
state => state.getSyncErrorMessage
);
export const selectGetSyncIsPending = createSelector(selectState, state => state.getSyncIsPending);
export const selectSetSyncIsPending = createSelector(selectState, state => state.setSyncIsPending);
export const selectHashChanged = createSelector(selectState, state => state.hashChanged);
export const selectSyncApplyIsPending = createSelector(
selectState,
state => state.syncApplyIsPending
);
export const selectSyncApplyErrorMessage = createSelector(
selectState,
state => state.syncApplyErrorMessage
);
export const selectSyncApplyPasswordError = createSelector(
selectState,
state => state.syncApplyPasswordError
);

View file

@ -1,118 +0,0 @@
import { createSelector } from 'reselect';
export const selectState = state => state.user || {};
export const selectAuthenticationIsPending = createSelector(
selectState,
state => state.authenticationIsPending
);
export const selectUserIsPending = createSelector(selectState, state => state.userIsPending);
export const selectUser = createSelector(selectState, state => state.user);
export const selectUserEmail = createSelector(
selectUser,
user => (user ? user.primary_email : null)
);
export const selectUserPhone = createSelector(
selectUser,
user => (user ? user.phone_number : null)
);
export const selectUserCountryCode = createSelector(
selectUser,
user => (user ? user.country_code : null)
);
export const selectEmailToVerify = createSelector(
selectState,
selectUserEmail,
(state, userEmail) => state.emailToVerify || userEmail
);
export const selectPhoneToVerify = createSelector(
selectState,
selectUserPhone,
(state, userPhone) => state.phoneToVerify || userPhone
);
export const selectUserIsRewardApproved = createSelector(
selectUser,
user => user && user.is_reward_approved
);
export const selectEmailNewIsPending = createSelector(
selectState,
state => state.emailNewIsPending
);
export const selectEmailNewErrorMessage = createSelector(
selectState,
state => state.emailNewErrorMessage
);
export const selectPhoneNewErrorMessage = createSelector(
selectState,
state => state.phoneNewErrorMessage
);
export const selectEmailVerifyIsPending = createSelector(
selectState,
state => state.emailVerifyIsPending
);
export const selectEmailVerifyErrorMessage = createSelector(
selectState,
state => state.emailVerifyErrorMessage
);
export const selectPhoneVerifyErrorMessage = createSelector(
selectState,
state => state.phoneVerifyErrorMessage
);
export const selectIdentityVerifyIsPending = createSelector(
selectState,
state => state.identityVerifyIsPending
);
export const selectIdentityVerifyErrorMessage = createSelector(
selectState,
state => state.identityVerifyErrorMessage
);
export const selectUserIsVerificationCandidate = createSelector(
selectUser,
user => user && (!user.has_verified_email || !user.is_identity_verified)
);
export const selectAccessToken = createSelector(selectState, state => state.accessToken);
export const selectUserInviteStatusIsPending = createSelector(
selectState,
state => state.inviteStatusIsPending
);
export const selectUserInvitesRemaining = createSelector(
selectState,
state => state.invitesRemaining
);
export const selectUserInvitees = createSelector(selectState, state => state.invitees);
export const selectUserInviteStatusFailed = createSelector(
selectUserInvitesRemaining,
() => selectUserInvitesRemaining === null
);
export const selectUserInviteNewIsPending = createSelector(
selectState,
state => state.inviteNewIsPending
);
export const selectUserInviteNewErrorMessage = createSelector(
selectState,
state => state.inviteNewErrorMessage
);

View file

@ -0,0 +1,10 @@
import { createSelector } from 'reselect';
const selectState = state => state.web || {};
export const selectCurrentUploads = createSelector(selectState, state => state.currentUploads);
export const selectUploadCount = createSelector(
selectCurrentUploads,
currentUploads => currentUploads && Object.keys(currentUploads).length
);

View file

@ -1,112 +0,0 @@
import { Lbry, doNotify } from 'lbry-redux';
import Lbryio from 'lbryio';
const rewards = {};
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
rewards.TYPE_NEW_USER = 'new_user';
rewards.TYPE_CONFIRM_EMAIL = 'verified_email';
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
rewards.TYPE_FIRST_STREAM = 'first_stream';
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
rewards.TYPE_FIRST_PUBLISH = 'first_publish';
rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download';
rewards.TYPE_REFERRAL = 'referral';
rewards.YOUTUBE_CREATOR = 'youtube_creator';
rewards.claimReward = type => {
function requestReward(resolve, reject, params) {
if (!Lbryio.enabled) {
reject(new Error(__('Rewards are not enabled.')));
return;
}
Lbryio.call('reward', 'new', params, 'post').then(reward => {
const message =
reward.reward_notification || `You have claimed a ${reward.reward_amount} LBC reward.`;
// Display global notice
const action = doNotify({
message,
linkText: __('Show All'),
linkTarget: '/rewards',
isError: false,
displayType: ['snackbar'],
});
window.store.dispatch(action);
// Add more events here to display other places
resolve(reward);
}, reject);
}
return new Promise((resolve, reject) => {
Lbry.wallet_unused_address().then(address => {
const params = {
reward_type: type,
wallet_address: address,
};
switch (type) {
case rewards.TYPE_FIRST_CHANNEL:
Lbry.claim_list_mine()
.then(claims => {
const claim = claims
.reverse()
.find(
foundClaim =>
foundClaim.name.length &&
foundClaim.name[0] === '@' &&
foundClaim.txid.length &&
foundClaim.category === 'claim'
);
if (claim) {
params.transaction_id = claim.txid;
requestReward(resolve, reject, params);
} else {
reject(new Error(__('Please create a channel identity first.')));
}
})
.catch(reject);
break;
case rewards.TYPE_FIRST_PUBLISH:
Lbry.claim_list_mine()
.then(claims => {
const claim = claims
.reverse()
.find(
foundClaim =>
foundClaim.name.length &&
foundClaim.name[0] !== '@' &&
foundClaim.txid.length &&
foundClaim.category === 'claim'
);
if (claim) {
params.transaction_id = claim.txid;
requestReward(resolve, reject, params);
} else {
reject(
claims.length
? new Error(
__(
'Please publish something and wait for confirmation by the network to claim this reward.'
)
)
: new Error(__('Please publish something to claim this reward.'))
);
}
})
.catch(reject);
break;
case rewards.TYPE_FIRST_STREAM:
case rewards.TYPE_NEW_USER:
default:
requestReward(resolve, reject, params);
}
});
});
};
export default rewards;

17
src/util/redux-utils.js Normal file
View file

@ -0,0 +1,17 @@
// 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
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;
};

10
src/util/swap-json.js Normal file
View file

@ -0,0 +1,10 @@
export 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;
}

View file

@ -0,0 +1,78 @@
const apiBaseUrl = 'https://www.transifex.com/api/2/project';
const resource = 'app-strings';
export 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);
});
}

View file

@ -1,6 +1,5 @@
/* eslint-disable import/no-commonjs */ /* eslint-disable import/no-commonjs */
const path = require('path'); const path = require('path');
const FlowBabelWebpackPlugin = require('flow-babel-webpack-plugin');
module.exports = { module.exports = {
mode: 'none', mode: 'none',
@ -8,7 +7,7 @@ module.exports = {
output: { output: {
filename: 'bundle.js', filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'), path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd' libraryTarget: 'umd',
}, },
module: { module: {
rules: [ rules: [
@ -21,6 +20,9 @@ module.exports = {
}, },
resolve: { resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'], modules: [path.resolve(__dirname, 'src'), 'node_modules'],
alias: {
'flow-typed': path.resolve(__dirname, './flow-typed'),
},
}, },
plugins: [new FlowBabelWebpackPlugin()], externals: 'lbry-redux',
}; };

4033
yarn.lock

File diff suppressed because it is too large Load diff