sync reducer stuff
bring tags into app repo prevent prefset until prefsReady prefs ready on sign up prefsReady-desktop
This commit is contained in:
parent
f54a0de797
commit
9d4f7dc642
38 changed files with 925 additions and 146 deletions
|
@ -1348,6 +1348,9 @@
|
||||||
"Create a channel": "Create a channel",
|
"Create a channel": "Create a channel",
|
||||||
"Credit Details": "Credit Details",
|
"Credit Details": "Credit Details",
|
||||||
"LBRY Credits": "LBRY Credits",
|
"LBRY Credits": "LBRY Credits",
|
||||||
|
"Mark all as read": "Mark all as read",
|
||||||
|
"Log in to %SITE_NAME% to earn rewards From Inviting Your Friends": "Log in to %SITE_NAME% to earn rewards From Inviting Your Friends",
|
||||||
|
"Confirming...": "Confirming...",
|
||||||
"Pinned by @%channel%": "Pinned by @%channel%",
|
"Pinned by @%channel%": "Pinned by @%channel%",
|
||||||
"Pinned by creator": "Pinned by creator",
|
"Pinned by creator": "Pinned by creator",
|
||||||
"Claim Your %reward_amount% Credit Invite Reward": "Claim Your %reward_amount% Credit Invite Reward",
|
"Claim Your %reward_amount% Credit Invite Reward": "Claim Your %reward_amount% Credit Invite Reward",
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { doFetchChannelListMine, SETTINGS } from 'lbry-redux';
|
||||||
import { makeSelectClientSetting, selectLoadedLanguages, selectThemePath } from 'redux/selectors/settings';
|
import { makeSelectClientSetting, selectLoadedLanguages, selectThemePath } from 'redux/selectors/settings';
|
||||||
import { selectIsUpgradeAvailable, selectAutoUpdateDownloaded, selectModal } from 'redux/selectors/app';
|
import { selectIsUpgradeAvailable, selectAutoUpdateDownloaded, selectModal } from 'redux/selectors/app';
|
||||||
import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings';
|
import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings';
|
||||||
import { doSyncSubscribe } from 'redux/actions/syncwrapper';
|
import { doSyncSubscribe } from 'redux/actions/sync';
|
||||||
import {
|
import {
|
||||||
doDownloadUpgradeRequested,
|
doDownloadUpgradeRequested,
|
||||||
doSignIn,
|
doSignIn,
|
||||||
|
|
|
@ -5,8 +5,8 @@ import {
|
||||||
selectClaimSearchByQueryLastPageReached,
|
selectClaimSearchByQueryLastPageReached,
|
||||||
selectFetchingClaimSearch,
|
selectFetchingClaimSearch,
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
selectFollowedTags,
|
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectBlockedChannels } from 'redux/selectors/blocked';
|
import { selectBlockedChannels } from 'redux/selectors/blocked';
|
||||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFetchingClaimSearch, SETTINGS, selectFollowedTags } from 'lbry-redux';
|
import { selectFetchingClaimSearch, SETTINGS } from 'lbry-redux';
|
||||||
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectTagsForUri, selectFollowedTags } from 'lbry-redux';
|
import { makeSelectTagsForUri } from 'lbry-redux';
|
||||||
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import ClaimTags from './view';
|
import ClaimTags from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -7,7 +8,4 @@ const select = (state, props) => ({
|
||||||
followedTags: selectFollowedTags(state),
|
followedTags: selectFollowedTags(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, null)(ClaimTags);
|
||||||
select,
|
|
||||||
null
|
|
||||||
)(ClaimTags);
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { selectFollowedTags, selectPurchaseUriSuccess, doClearPurchasedUriSuccess, SETTINGS } from 'lbry-redux';
|
import { selectPurchaseUriSuccess, doClearPurchasedUriSuccess, SETTINGS } from 'lbry-redux';
|
||||||
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { doSignOut } from 'redux/actions/app';
|
import { doSignOut } from 'redux/actions/app';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectGetSyncIsPending, selectSyncApplyPasswordError } from 'redux/selectors/sync';
|
import { selectGetSyncIsPending, selectSyncApplyPasswordError } from 'redux/selectors/sync';
|
||||||
import { doGetSyncDesktop } from 'redux/actions/syncwrapper';
|
import { doGetSyncDesktop } from 'redux/actions/sync';
|
||||||
import { selectUserEmail } from 'redux/selectors/user';
|
import { selectUserEmail } from 'redux/selectors/user';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import { doSignOut, doHandleSyncComplete } from 'redux/actions/app';
|
import { doSignOut, doHandleSyncComplete } from 'redux/actions/app';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUnfollowedTags, selectFollowedTags, doReplaceTags, doAddTag, doDeleteTag } from 'lbry-redux';
|
import { selectUnfollowedTags, selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
import { doToggleTagFollowDesktop, doAddTag, doDeleteTag } from 'redux/actions/tags';
|
||||||
import DiscoveryFirstRun from './view';
|
import DiscoveryFirstRun from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -8,12 +8,8 @@ const select = (state, props) => ({
|
||||||
followedTags: selectFollowedTags(state),
|
followedTags: selectFollowedTags(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, {
|
||||||
select,
|
doToggleTagFollowDesktop,
|
||||||
{
|
doAddTag,
|
||||||
doToggleTagFollowDesktop,
|
doDeleteTag,
|
||||||
doAddTag,
|
})(DiscoveryFirstRun);
|
||||||
doDeleteTag,
|
|
||||||
doReplaceTags,
|
|
||||||
}
|
|
||||||
)(DiscoveryFirstRun);
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUnfollowedTags, selectFollowedTags, doReplaceTags, doAddTag, doDeleteTag } from 'lbry-redux';
|
import { selectUnfollowedTags, selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
import { doToggleTagFollowDesktop, doAddTag, doDeleteTag } from 'redux/actions/tags';
|
||||||
import DiscoveryFirstRun from './view';
|
import DiscoveryFirstRun from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -8,12 +8,8 @@ const select = (state, props) => ({
|
||||||
followedTags: selectFollowedTags(state),
|
followedTags: selectFollowedTags(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, {
|
||||||
select,
|
doToggleTagFollowDesktop,
|
||||||
{
|
doAddTag,
|
||||||
doToggleTagFollowDesktop,
|
doDeleteTag,
|
||||||
doAddTag,
|
})(DiscoveryFirstRun);
|
||||||
doDeleteTag,
|
|
||||||
doReplaceTags,
|
|
||||||
}
|
|
||||||
)(DiscoveryFirstRun);
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { doChannelSubscribe } from 'redux/actions/subscriptions';
|
import { doChannelSubscribe } from 'redux/actions/subscriptions';
|
||||||
import UserChannelFollowIntro from './view';
|
import UserChannelFollowIntro from './view';
|
||||||
|
@ -13,7 +13,4 @@ const perform = dispatch => ({
|
||||||
channelSubscribe: uri => dispatch(doChannelSubscribe(uri)),
|
channelSubscribe: uri => dispatch(doChannelSubscribe(uri)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, perform)(UserChannelFollowIntro);
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(UserChannelFollowIntro);
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import {
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectInterestedInYoutubeSync } from 'redux/selectors/app';
|
import { selectInterestedInYoutubeSync } from 'redux/selectors/app';
|
||||||
import { doToggleInterestedInYoutubeSync } from 'redux/actions/app';
|
import { doToggleInterestedInYoutubeSync } from 'redux/actions/app';
|
||||||
|
import { doSetPrefsReady } from 'redux/actions/sync';
|
||||||
|
|
||||||
import UserSignIn from './view';
|
import UserSignIn from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -63,6 +65,7 @@ const perform = dispatch => ({
|
||||||
),
|
),
|
||||||
setClientSetting: (setting, value, pushToPrefs) => dispatch(doSetClientSetting(setting, value, pushToPrefs)),
|
setClientSetting: (setting, value, pushToPrefs) => dispatch(doSetClientSetting(setting, value, pushToPrefs)),
|
||||||
doToggleInterestedInYoutubeSync: () => dispatch(doToggleInterestedInYoutubeSync()),
|
doToggleInterestedInYoutubeSync: () => dispatch(doToggleInterestedInYoutubeSync()),
|
||||||
|
setPrefsReady: () => dispatch(doSetPrefsReady()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserSignIn);
|
export default connect(select, perform)(UserSignIn);
|
||||||
|
|
|
@ -45,6 +45,7 @@ type Props = {
|
||||||
rewardsAcknowledged: boolean,
|
rewardsAcknowledged: boolean,
|
||||||
interestedInYoutubeSync: boolean,
|
interestedInYoutubeSync: boolean,
|
||||||
doToggleInterestedInYoutubeSync: () => void,
|
doToggleInterestedInYoutubeSync: () => void,
|
||||||
|
setPrefsReady: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
function UserSignUp(props: Props) {
|
function UserSignUp(props: Props) {
|
||||||
|
@ -70,6 +71,7 @@ function UserSignUp(props: Props) {
|
||||||
setClientSetting,
|
setClientSetting,
|
||||||
interestedInYoutubeSync,
|
interestedInYoutubeSync,
|
||||||
doToggleInterestedInYoutubeSync,
|
doToggleInterestedInYoutubeSync,
|
||||||
|
setPrefsReady,
|
||||||
} = props;
|
} = props;
|
||||||
const {
|
const {
|
||||||
location: { search, pathname },
|
location: { search, pathname },
|
||||||
|
@ -133,9 +135,10 @@ function UserSignUp(props: Props) {
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (hasVerifiedEmail) {
|
if (hasVerifiedEmail) {
|
||||||
|
setPrefsReady();
|
||||||
setSettingAndSync(SETTINGS.FIRST_RUN_STARTED, true);
|
setSettingAndSync(SETTINGS.FIRST_RUN_STARTED, true);
|
||||||
}
|
}
|
||||||
}, [hasVerifiedEmail]);
|
}, [hasVerifiedEmail, setPrefsReady]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// Don't claim the reward if sync is enabled until after a sync has been completed successfully
|
// Don't claim the reward if sync is enabled until after a sync has been completed successfully
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import UserTagFollowIntro from './view';
|
import UserTagFollowIntro from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -279,6 +279,11 @@ export const COMMENT_SET_CHANNEL = 'COMMENT_SET_CHANNEL';
|
||||||
// Blocked channels
|
// Blocked channels
|
||||||
export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL';
|
export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL';
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW';
|
||||||
|
export const TAG_ADD = 'TAG_ADD';
|
||||||
|
export const TAG_DELETE = 'TAG_DELETE';
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
export const WS_CONNECT = 'WS_CONNECT';
|
export const WS_CONNECT = 'WS_CONNECT';
|
||||||
export const WS_DISCONNECT = 'WS_DISCONNECT';
|
export const WS_DISCONNECT = 'WS_DISCONNECT';
|
||||||
|
@ -290,6 +295,7 @@ export const GET_SYNC_FAILED = 'GET_SYNC_FAILED';
|
||||||
export const SET_SYNC_STARTED = 'SET_SYNC_STARTED';
|
export const SET_SYNC_STARTED = 'SET_SYNC_STARTED';
|
||||||
export const SET_SYNC_FAILED = 'SET_SYNC_FAILED';
|
export const SET_SYNC_FAILED = 'SET_SYNC_FAILED';
|
||||||
export const SET_SYNC_COMPLETED = 'SET_SYNC_COMPLETED';
|
export const SET_SYNC_COMPLETED = 'SET_SYNC_COMPLETED';
|
||||||
|
export const SET_PREFS_READY = 'SET_PREFS_READY';
|
||||||
export const SET_DEFAULT_ACCOUNT = 'SET_DEFAULT_ACCOUNT';
|
export const SET_DEFAULT_ACCOUNT = 'SET_DEFAULT_ACCOUNT';
|
||||||
export const SYNC_APPLY_STARTED = 'SYNC_APPLY_STARTED';
|
export const SYNC_APPLY_STARTED = 'SYNC_APPLY_STARTED';
|
||||||
export const SYNC_APPLY_COMPLETED = 'SYNC_APPLY_COMPLETED';
|
export const SYNC_APPLY_COMPLETED = 'SYNC_APPLY_COMPLETED';
|
||||||
|
|
546
ui/constants/tags.js
Normal file
546
ui/constants/tags.js
Normal file
|
@ -0,0 +1,546 @@
|
||||||
|
export const DEFAULT_FOLLOWED_TAGS = [
|
||||||
|
'art',
|
||||||
|
'automotive',
|
||||||
|
'blockchain',
|
||||||
|
'comedy',
|
||||||
|
'economics',
|
||||||
|
'education',
|
||||||
|
'gaming',
|
||||||
|
'music',
|
||||||
|
'news',
|
||||||
|
'science',
|
||||||
|
'sports',
|
||||||
|
'technology',
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MATURE_TAGS = [
|
||||||
|
'porn',
|
||||||
|
'porno',
|
||||||
|
'nsfw',
|
||||||
|
'mature',
|
||||||
|
'xxx',
|
||||||
|
'sex',
|
||||||
|
'creampie',
|
||||||
|
'blowjob',
|
||||||
|
'handjob',
|
||||||
|
'vagina',
|
||||||
|
'boobs',
|
||||||
|
'big boobs',
|
||||||
|
'big dick',
|
||||||
|
'pussy',
|
||||||
|
'cumshot',
|
||||||
|
'anal',
|
||||||
|
'hard fucking',
|
||||||
|
'ass',
|
||||||
|
'fuck',
|
||||||
|
'hentai',
|
||||||
|
];
|
||||||
|
|
||||||
|
const DEFAULT_ENGLISH_KNOWN_TAGS = [
|
||||||
|
'free speech',
|
||||||
|
'censorship',
|
||||||
|
'gaming',
|
||||||
|
'pop culture',
|
||||||
|
'entertainment',
|
||||||
|
'technology',
|
||||||
|
'music',
|
||||||
|
'funny',
|
||||||
|
'education',
|
||||||
|
'learning',
|
||||||
|
'news',
|
||||||
|
'gameplay',
|
||||||
|
'nature',
|
||||||
|
'beliefs',
|
||||||
|
'comedy',
|
||||||
|
'games',
|
||||||
|
'film & animation',
|
||||||
|
'game',
|
||||||
|
'weapons',
|
||||||
|
'blockchain',
|
||||||
|
'video game',
|
||||||
|
'sports',
|
||||||
|
'walkthrough',
|
||||||
|
'lbrytvpaidbeta',
|
||||||
|
'art',
|
||||||
|
'pc',
|
||||||
|
'minecraft',
|
||||||
|
'playthrough',
|
||||||
|
'economics',
|
||||||
|
'automotive',
|
||||||
|
'play',
|
||||||
|
'tutorial',
|
||||||
|
'twitch',
|
||||||
|
'how to',
|
||||||
|
'ps4',
|
||||||
|
'bitcoin',
|
||||||
|
'fortnite',
|
||||||
|
'commentary',
|
||||||
|
'lets play',
|
||||||
|
'fun',
|
||||||
|
'politics',
|
||||||
|
'travel',
|
||||||
|
'food',
|
||||||
|
'science',
|
||||||
|
'xbox',
|
||||||
|
'liberal',
|
||||||
|
'democrat',
|
||||||
|
'progressive',
|
||||||
|
'survival',
|
||||||
|
'non-profits',
|
||||||
|
'activism',
|
||||||
|
'cryptocurrency',
|
||||||
|
'playstation',
|
||||||
|
'nintendo',
|
||||||
|
'government',
|
||||||
|
'steam',
|
||||||
|
'podcast',
|
||||||
|
'gamer',
|
||||||
|
'horror',
|
||||||
|
'conservative',
|
||||||
|
'reaction',
|
||||||
|
'trailer',
|
||||||
|
'love',
|
||||||
|
'cnn',
|
||||||
|
'republican',
|
||||||
|
'political',
|
||||||
|
'hangoutsonair',
|
||||||
|
'hoa',
|
||||||
|
'msnbc',
|
||||||
|
'cbs',
|
||||||
|
'anime',
|
||||||
|
'donald trump',
|
||||||
|
'fiction',
|
||||||
|
'fox news',
|
||||||
|
'crypto',
|
||||||
|
'ethereum',
|
||||||
|
'call of duty',
|
||||||
|
'android',
|
||||||
|
'multiplayer',
|
||||||
|
'epic',
|
||||||
|
'rpg',
|
||||||
|
'adventure',
|
||||||
|
'secular talk',
|
||||||
|
'btc',
|
||||||
|
'atheist',
|
||||||
|
'atheism',
|
||||||
|
'video games',
|
||||||
|
'ps3',
|
||||||
|
'cod',
|
||||||
|
'online',
|
||||||
|
'agnostic',
|
||||||
|
'movie',
|
||||||
|
'fps',
|
||||||
|
'lets',
|
||||||
|
'mod',
|
||||||
|
'world',
|
||||||
|
'reviews',
|
||||||
|
'sharefactory',
|
||||||
|
'space',
|
||||||
|
'pokemon',
|
||||||
|
'stream',
|
||||||
|
'hilarious',
|
||||||
|
'lol',
|
||||||
|
'sony',
|
||||||
|
'god',
|
||||||
|
'dance',
|
||||||
|
'pvp',
|
||||||
|
'tech',
|
||||||
|
'strategy',
|
||||||
|
'zombies',
|
||||||
|
'fail',
|
||||||
|
'film',
|
||||||
|
'xbox360',
|
||||||
|
'animation',
|
||||||
|
'unboxing',
|
||||||
|
'money',
|
||||||
|
'wwe',
|
||||||
|
'mods',
|
||||||
|
'indie',
|
||||||
|
'pubg',
|
||||||
|
'ios',
|
||||||
|
'history',
|
||||||
|
'rap',
|
||||||
|
'mobile',
|
||||||
|
'trump',
|
||||||
|
'hack',
|
||||||
|
'flat earth',
|
||||||
|
'trap',
|
||||||
|
'humor',
|
||||||
|
'vlogging',
|
||||||
|
'fox',
|
||||||
|
'news radio',
|
||||||
|
'facebook',
|
||||||
|
'edm',
|
||||||
|
'fitness',
|
||||||
|
'vaping',
|
||||||
|
'hip hop',
|
||||||
|
'secular',
|
||||||
|
'jesus',
|
||||||
|
'song',
|
||||||
|
'vape',
|
||||||
|
'guitar',
|
||||||
|
'remix',
|
||||||
|
'mining',
|
||||||
|
'daily',
|
||||||
|
'diy',
|
||||||
|
'pets',
|
||||||
|
'videogame',
|
||||||
|
'death',
|
||||||
|
'funny moments',
|
||||||
|
'religion',
|
||||||
|
'media',
|
||||||
|
'viral',
|
||||||
|
'war',
|
||||||
|
'nbc',
|
||||||
|
'freedom',
|
||||||
|
'gold',
|
||||||
|
'family',
|
||||||
|
'meme',
|
||||||
|
'zombie',
|
||||||
|
'photography',
|
||||||
|
'chill',
|
||||||
|
'sniper',
|
||||||
|
'computer',
|
||||||
|
'iphone',
|
||||||
|
'dragon',
|
||||||
|
'bible',
|
||||||
|
'pro',
|
||||||
|
'overwatch',
|
||||||
|
'litecoin',
|
||||||
|
'gta',
|
||||||
|
'house',
|
||||||
|
'fire',
|
||||||
|
'bass',
|
||||||
|
'truth',
|
||||||
|
'crash',
|
||||||
|
'mario',
|
||||||
|
'league of legends',
|
||||||
|
'wii',
|
||||||
|
'mmorpg',
|
||||||
|
'health',
|
||||||
|
'marvel',
|
||||||
|
'racing',
|
||||||
|
'apple',
|
||||||
|
'instrumental',
|
||||||
|
'earth',
|
||||||
|
'destiny',
|
||||||
|
'satire',
|
||||||
|
'race',
|
||||||
|
'training',
|
||||||
|
'electronic',
|
||||||
|
'boss',
|
||||||
|
'roblox',
|
||||||
|
'family friendly',
|
||||||
|
'california',
|
||||||
|
'react',
|
||||||
|
'christian',
|
||||||
|
'mmo',
|
||||||
|
'twitter',
|
||||||
|
'help',
|
||||||
|
'star',
|
||||||
|
'cars',
|
||||||
|
'random',
|
||||||
|
'top 10',
|
||||||
|
'ninja',
|
||||||
|
'guns',
|
||||||
|
'linux',
|
||||||
|
'lessons',
|
||||||
|
'vegan',
|
||||||
|
'future',
|
||||||
|
'dota 2',
|
||||||
|
'studio',
|
||||||
|
'star wars',
|
||||||
|
'shooting',
|
||||||
|
'nasa',
|
||||||
|
'rock',
|
||||||
|
'league',
|
||||||
|
'subscribe',
|
||||||
|
'water',
|
||||||
|
'gta v',
|
||||||
|
'car',
|
||||||
|
'samsung',
|
||||||
|
'music video',
|
||||||
|
'skyrim',
|
||||||
|
'dog',
|
||||||
|
'comics',
|
||||||
|
'shooter game',
|
||||||
|
'bo3',
|
||||||
|
'halloween',
|
||||||
|
'liberty',
|
||||||
|
'eth',
|
||||||
|
'conspiracy',
|
||||||
|
'knife',
|
||||||
|
'fashion',
|
||||||
|
'stories',
|
||||||
|
'vapor',
|
||||||
|
'nvidia',
|
||||||
|
'cute',
|
||||||
|
'beat',
|
||||||
|
'nintendo switch',
|
||||||
|
'fantasy',
|
||||||
|
'christmas',
|
||||||
|
'world of warcraft',
|
||||||
|
'industry',
|
||||||
|
'cartoon',
|
||||||
|
'garden',
|
||||||
|
'animals',
|
||||||
|
'windows',
|
||||||
|
'happy',
|
||||||
|
'magic',
|
||||||
|
'memes',
|
||||||
|
'design',
|
||||||
|
'tactical',
|
||||||
|
'fallout 4',
|
||||||
|
'puzzle',
|
||||||
|
'parody',
|
||||||
|
'rv',
|
||||||
|
'beats',
|
||||||
|
'building',
|
||||||
|
'disney',
|
||||||
|
'drone',
|
||||||
|
'ps2',
|
||||||
|
'beach',
|
||||||
|
'metal',
|
||||||
|
'christianity',
|
||||||
|
'business',
|
||||||
|
'mix',
|
||||||
|
'bo2',
|
||||||
|
'cover',
|
||||||
|
'senate',
|
||||||
|
'4k',
|
||||||
|
'united states',
|
||||||
|
'final',
|
||||||
|
'hero',
|
||||||
|
'playing',
|
||||||
|
'dlc',
|
||||||
|
'ubisoft',
|
||||||
|
'halo',
|
||||||
|
'pc gaming',
|
||||||
|
'raw',
|
||||||
|
'investing',
|
||||||
|
'online learning',
|
||||||
|
'software',
|
||||||
|
'ark',
|
||||||
|
'mojang',
|
||||||
|
'console',
|
||||||
|
'battle royale',
|
||||||
|
'canon',
|
||||||
|
'microsoft',
|
||||||
|
'camping',
|
||||||
|
'ufo',
|
||||||
|
'progressive talk',
|
||||||
|
'switch',
|
||||||
|
'fpv',
|
||||||
|
'arcade',
|
||||||
|
'school',
|
||||||
|
'driving',
|
||||||
|
'bodybuilding',
|
||||||
|
'drama',
|
||||||
|
'retro',
|
||||||
|
'science fiction',
|
||||||
|
'eggs',
|
||||||
|
'australia',
|
||||||
|
'modded',
|
||||||
|
'rainbow',
|
||||||
|
'gamers',
|
||||||
|
'resident evil',
|
||||||
|
'drawing',
|
||||||
|
'brasil',
|
||||||
|
'england',
|
||||||
|
'hillary clinton',
|
||||||
|
'singing',
|
||||||
|
'final fantasy',
|
||||||
|
'hiphop',
|
||||||
|
'video blog',
|
||||||
|
'mature',
|
||||||
|
'quad',
|
||||||
|
'noob',
|
||||||
|
'simulation',
|
||||||
|
'illuminati',
|
||||||
|
'poetry',
|
||||||
|
'dayz',
|
||||||
|
'manga',
|
||||||
|
'howto',
|
||||||
|
'insane',
|
||||||
|
'press',
|
||||||
|
'special',
|
||||||
|
'church',
|
||||||
|
'ico',
|
||||||
|
'weird',
|
||||||
|
'libertarian',
|
||||||
|
'crafting',
|
||||||
|
'level',
|
||||||
|
'comic',
|
||||||
|
'sandbox',
|
||||||
|
'daily vlog',
|
||||||
|
'outdoor',
|
||||||
|
'black ops',
|
||||||
|
'sound',
|
||||||
|
'christ',
|
||||||
|
'duty',
|
||||||
|
'juvenile fiction',
|
||||||
|
'pc game',
|
||||||
|
'how-to',
|
||||||
|
'ww2',
|
||||||
|
'creepy',
|
||||||
|
'artist',
|
||||||
|
'galaxy',
|
||||||
|
'destiny 2',
|
||||||
|
'new music',
|
||||||
|
'quest',
|
||||||
|
'lee',
|
||||||
|
'pacman',
|
||||||
|
'super smash bros',
|
||||||
|
'day',
|
||||||
|
'survival horror',
|
||||||
|
'patreon',
|
||||||
|
'bitcoin price',
|
||||||
|
'trending',
|
||||||
|
'open world',
|
||||||
|
'wii u',
|
||||||
|
'dope',
|
||||||
|
'reaper',
|
||||||
|
'sniping',
|
||||||
|
'dubstep',
|
||||||
|
'truck',
|
||||||
|
'planet',
|
||||||
|
'dc',
|
||||||
|
'amazon',
|
||||||
|
'spirituality',
|
||||||
|
'universe',
|
||||||
|
'video game culture',
|
||||||
|
'community',
|
||||||
|
'cat',
|
||||||
|
'aliens',
|
||||||
|
'tourism',
|
||||||
|
'altcoins',
|
||||||
|
'style',
|
||||||
|
'travel trailer',
|
||||||
|
'rda',
|
||||||
|
'gun',
|
||||||
|
'secret',
|
||||||
|
'far cry 5',
|
||||||
|
'auto',
|
||||||
|
'culture',
|
||||||
|
'dj',
|
||||||
|
'mw2',
|
||||||
|
'lord',
|
||||||
|
'full time rving',
|
||||||
|
'role-playing game',
|
||||||
|
'prank',
|
||||||
|
'grand theft auto',
|
||||||
|
'master',
|
||||||
|
'wrestling',
|
||||||
|
'sci-fi',
|
||||||
|
'workout',
|
||||||
|
'ghost',
|
||||||
|
'fake news',
|
||||||
|
'silly',
|
||||||
|
'season',
|
||||||
|
'bo4',
|
||||||
|
'trading',
|
||||||
|
'extreme',
|
||||||
|
'economy',
|
||||||
|
'combat',
|
||||||
|
'plays',
|
||||||
|
'muslim',
|
||||||
|
'pubg mobile',
|
||||||
|
'clips',
|
||||||
|
'bo1',
|
||||||
|
'paypal',
|
||||||
|
'sims',
|
||||||
|
'exploration',
|
||||||
|
'light',
|
||||||
|
'ripple',
|
||||||
|
'paranormal',
|
||||||
|
'football',
|
||||||
|
'capcom',
|
||||||
|
'rta',
|
||||||
|
'discord',
|
||||||
|
'batman',
|
||||||
|
'player',
|
||||||
|
'server',
|
||||||
|
'anarchy',
|
||||||
|
'military',
|
||||||
|
'playlist',
|
||||||
|
'cosplay',
|
||||||
|
'rv park',
|
||||||
|
'rant',
|
||||||
|
'edit',
|
||||||
|
'germany',
|
||||||
|
'reading',
|
||||||
|
'chris',
|
||||||
|
'flash',
|
||||||
|
'loot',
|
||||||
|
'bitcoin gratis',
|
||||||
|
'game reviews',
|
||||||
|
'movies',
|
||||||
|
'stupid',
|
||||||
|
'latest news',
|
||||||
|
'squad gameplay',
|
||||||
|
'guru',
|
||||||
|
'timelapse',
|
||||||
|
'black ops 3',
|
||||||
|
'holiday',
|
||||||
|
'soul',
|
||||||
|
'motivation',
|
||||||
|
'mw3',
|
||||||
|
'vacation',
|
||||||
|
'sega',
|
||||||
|
'19th century',
|
||||||
|
'pop',
|
||||||
|
'sims 4',
|
||||||
|
'post',
|
||||||
|
'smok',
|
||||||
|
'island',
|
||||||
|
'scotland',
|
||||||
|
'paladins',
|
||||||
|
'warrior',
|
||||||
|
'creepypasta',
|
||||||
|
'role-playing',
|
||||||
|
'solar',
|
||||||
|
'vr',
|
||||||
|
'animal',
|
||||||
|
'peace',
|
||||||
|
'consciousness',
|
||||||
|
'dota',
|
||||||
|
'audio',
|
||||||
|
'mass effect',
|
||||||
|
'humour',
|
||||||
|
'first look',
|
||||||
|
'videogames',
|
||||||
|
'future bass',
|
||||||
|
'freestyle',
|
||||||
|
'hardcore',
|
||||||
|
'portugal',
|
||||||
|
'dantdm',
|
||||||
|
'teaser',
|
||||||
|
'lbry',
|
||||||
|
'coronavirus',
|
||||||
|
'2020protests',
|
||||||
|
'covidcuts',
|
||||||
|
'covid-19',
|
||||||
|
'LBRYFoundationBoardCandidacy',
|
||||||
|
];
|
||||||
|
|
||||||
|
const DEFAULT_SPANISH_KNOWN_TAGS = [
|
||||||
|
'español',
|
||||||
|
'tecnología',
|
||||||
|
'criptomonedas',
|
||||||
|
'economía',
|
||||||
|
'bitcoin',
|
||||||
|
'educación',
|
||||||
|
'videojuegos',
|
||||||
|
'música',
|
||||||
|
'noticias',
|
||||||
|
'ciencia',
|
||||||
|
'deportes',
|
||||||
|
'latinoamérica',
|
||||||
|
'latam',
|
||||||
|
'conspiración',
|
||||||
|
'humor',
|
||||||
|
'política',
|
||||||
|
'tutoriales',
|
||||||
|
];
|
||||||
|
|
||||||
|
export const DEFAULT_KNOWN_TAGS = [...DEFAULT_ENGLISH_KNOWN_TAGS, ...DEFAULT_SPANISH_KNOWN_TAGS];
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectBlockedChannels } from 'redux/selectors/blocked';
|
import { selectBlockedChannels } from 'redux/selectors/blocked';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import ChannelsFollowingManagePage from './view';
|
import ChannelsFollowingManagePage from './view';
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import * as CS from 'constants/claim_search';
|
import * as CS from 'constants/claim_search';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectClaimForUri, selectFollowedTags, doResolveUri, SETTINGS } from 'lbry-redux';
|
import { makeSelectClaimForUri, doResolveUri, SETTINGS } from 'lbry-redux';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import Tags from './view';
|
import Tags from './view';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import DiscoverPage from './view';
|
import DiscoverPage from './view';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectFollowedTags } from 'lbry-redux';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
import { selectSubscriptions, selectSuggestedChannels } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions, selectSuggestedChannels } from 'redux/selectors/subscriptions';
|
||||||
import { doFetchRecommendedSubscriptions } from 'redux/actions/subscriptions';
|
import { doFetchRecommendedSubscriptions } from 'redux/actions/subscriptions';
|
||||||
|
|
||||||
|
@ -11,9 +11,6 @@ const select = state => ({
|
||||||
suggestedSubscriptions: selectSuggestedChannels(state),
|
suggestedSubscriptions: selectSuggestedChannels(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, {
|
||||||
select,
|
doFetchRecommendedSubscriptions,
|
||||||
{
|
})(TagsEdit);
|
||||||
doFetchRecommendedSubscriptions,
|
|
||||||
}
|
|
||||||
)(TagsEdit);
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
import { connectRouter } from 'connected-react-router';
|
import { connectRouter } from 'connected-react-router';
|
||||||
import { claimsReducer, fileInfoReducer, walletReducer, tagsReducer, publishReducer } from 'lbry-redux';
|
import { claimsReducer, fileInfoReducer, walletReducer, publishReducer } from 'lbry-redux';
|
||||||
import { costInfoReducer, blacklistReducer, filteredReducer, homepageReducer, statsReducer, webReducer } from 'lbryinc';
|
import { costInfoReducer, blacklistReducer, filteredReducer, homepageReducer, statsReducer, webReducer } from 'lbryinc';
|
||||||
import appReducer from 'redux/reducers/app';
|
import appReducer from 'redux/reducers/app';
|
||||||
|
import tagsReducer from 'redux/reducers/tags';
|
||||||
import contentReducer from 'redux/reducers/content';
|
import contentReducer from 'redux/reducers/content';
|
||||||
import settingsReducer from 'redux/reducers/settings';
|
import settingsReducer from 'redux/reducers/settings';
|
||||||
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
||||||
|
|
|
@ -18,12 +18,13 @@ import {
|
||||||
doClearPublish,
|
doClearPublish,
|
||||||
doPreferenceGet,
|
doPreferenceGet,
|
||||||
doClearSupport,
|
doClearSupport,
|
||||||
selectFollowedTagsList,
|
|
||||||
SHARED_PREFERENCES,
|
SHARED_PREFERENCES,
|
||||||
DAEMON_SETTINGS,
|
DAEMON_SETTINGS,
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
|
import { selectFollowedTagsList } from 'redux/selectors/tags';
|
||||||
import { doToast, doError, doNotificationList } from 'redux/actions/notifications';
|
import { doToast, doError, doNotificationList } from 'redux/actions/notifications';
|
||||||
|
|
||||||
import Native from 'native';
|
import Native from 'native';
|
||||||
import {
|
import {
|
||||||
doFetchDaemonSettings,
|
doFetchDaemonSettings,
|
||||||
|
@ -47,7 +48,7 @@ import {
|
||||||
import { selectDaemonSettings, makeSelectClientSetting } from 'redux/selectors/settings';
|
import { selectDaemonSettings, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectUser } from 'redux/selectors/user';
|
import { selectUser } from 'redux/selectors/user';
|
||||||
// import { selectDaemonSettings } from 'redux/selectors/settings';
|
// import { selectDaemonSettings } from 'redux/selectors/settings';
|
||||||
import { doSyncSubscribe } from 'redux/actions/syncwrapper';
|
import { doSyncSubscribe, doSetPrefsReady } from 'redux/actions/sync';
|
||||||
import { doAuthenticate } from 'redux/actions/user';
|
import { doAuthenticate } from 'redux/actions/user';
|
||||||
import { lbrySettings as config, version as appVersion } from 'package.json';
|
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||||
import analytics, { SHARE_INTERNAL } from 'analytics';
|
import analytics, { SHARE_INTERNAL } from 'analytics';
|
||||||
|
@ -90,13 +91,6 @@ export function doUpdateDownloadProgress(percent) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSetSyncLock(lock) {
|
|
||||||
return {
|
|
||||||
type: ACTIONS.SET_SYNC_LOCK,
|
|
||||||
data: lock,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doSkipUpgrade() {
|
export function doSkipUpgrade() {
|
||||||
return {
|
return {
|
||||||
type: ACTIONS.SKIP_UPGRADE,
|
type: ACTIONS.SKIP_UPGRADE,
|
||||||
|
@ -340,6 +334,16 @@ export function doAlertError(errorList) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doAlertWaitingForSync() {
|
||||||
|
return dispatch =>
|
||||||
|
dispatch(
|
||||||
|
doToast({
|
||||||
|
message: __('Hold on, we are setting up your account'),
|
||||||
|
isError: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function doDaemonReady() {
|
export function doDaemonReady() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -628,6 +632,8 @@ export function doGetAndPopulatePreferences() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// @endif
|
// @endif
|
||||||
|
} else {
|
||||||
|
dispatch(doSetPrefsReady());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { selectPrefsReady } from 'redux/selectors/sync';
|
||||||
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
|
|
||||||
export const doToggleBlockChannel = (uri: string) => ({
|
export const doToggleBlockChannel = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
|
||||||
type: ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
const state = getState();
|
||||||
data: {
|
const ready = selectPrefsReady(state);
|
||||||
uri,
|
|
||||||
},
|
if (!ready) {
|
||||||
});
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
||||||
|
data: {
|
||||||
|
uri,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
import { doError } from 'redux/actions/notifications';
|
import { doError } from 'redux/actions/notifications';
|
||||||
import { push } from 'connected-react-router';
|
import { push } from 'connected-react-router';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
import { doOpenModal } from './app';
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
|
|
||||||
export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispatch: Dispatch, getState: () => {}) => {
|
export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispatch: Dispatch, getState: () => {}) => {
|
||||||
const publishPreview = previewResponse => {
|
const publishPreview = previewResponse => {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as REACTION_TYPES from 'constants/reactions';
|
import * as REACTION_TYPES from 'constants/reactions';
|
||||||
import { makeSelectMyReactionForUri } from '../selectors/reactions';
|
import { makeSelectMyReactionForUri } from 'redux/selectors/reactions';
|
||||||
import { makeSelectClaimForUri } from 'lbry-redux';
|
import { makeSelectClaimForUri } from 'lbry-redux';
|
||||||
|
|
||||||
export const doFetchReactions = (claimId: string) => (dispatch: Dispatch) => {
|
export const doFetchReactions = (claimId: string) => (dispatch: Dispatch) => {
|
||||||
|
|
|
@ -5,8 +5,9 @@ import analytics from 'analytics';
|
||||||
import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
||||||
import { launcher } from 'util/autoLaunch';
|
import { launcher } from 'util/autoLaunch';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { doGetSyncDesktop, doSyncUnsubscribe } from 'redux/actions/syncwrapper';
|
import { doGetSyncDesktop, doSyncUnsubscribe, doSetSyncLock } from 'redux/actions/sync';
|
||||||
import { doGetAndPopulatePreferences, doSetSyncLock } from 'redux/actions/app';
|
import { doAlertWaitingForSync, doGetAndPopulatePreferences } from 'redux/actions/app';
|
||||||
|
import { selectPrefsReady } from 'redux/selectors/sync';
|
||||||
|
|
||||||
const { DEFAULT_LANGUAGE } = require('config');
|
const { DEFAULT_LANGUAGE } = require('config');
|
||||||
const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
|
const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
|
||||||
|
@ -57,10 +58,18 @@ export function doGetDaemonStatus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doClearDaemonSetting(key) {
|
export function doClearDaemonSetting(key) {
|
||||||
return dispatch => {
|
return (dispatch, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
const ready = selectPrefsReady(state);
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
const clearKey = {
|
const clearKey = {
|
||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
|
// not if syncLocked
|
||||||
Lbry.settings_clear(clearKey).then(defaultSettings => {
|
Lbry.settings_clear(clearKey).then(defaultSettings => {
|
||||||
if (SDK_SYNC_KEYS.includes(key)) {
|
if (SDK_SYNC_KEYS.includes(key)) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -85,7 +94,14 @@ export function doClearDaemonSetting(key) {
|
||||||
}
|
}
|
||||||
// if doPopulate is applying settings, we don't want to cause a loop; doNotDispatch = true.
|
// if doPopulate is applying settings, we don't want to cause a loop; doNotDispatch = true.
|
||||||
export function doSetDaemonSetting(key, value, doNotDispatch = false) {
|
export function doSetDaemonSetting(key, value, doNotDispatch = false) {
|
||||||
return dispatch => {
|
return (dispatch, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
const ready = selectPrefsReady(state);
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
const newSettings = {
|
const newSettings = {
|
||||||
key,
|
key,
|
||||||
value: !value && value !== false ? null : value,
|
value: !value && value !== false ? null : value,
|
||||||
|
@ -123,7 +139,14 @@ export function doSaveCustomWalletServers(servers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSetClientSetting(key, value, pushPrefs) {
|
export function doSetClientSetting(key, value, pushPrefs) {
|
||||||
return dispatch => {
|
return (dispatch, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
const ready = selectPrefsReady(state);
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.CLIENT_SETTING_CHANGED,
|
type: ACTIONS.CLIENT_SETTING_CHANGED,
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Lbryio } from 'lbryinc';
|
||||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||||
import { selectUnreadByChannel } from 'redux/selectors/subscriptions';
|
import { selectUnreadByChannel } from 'redux/selectors/subscriptions';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
|
|
||||||
export const doSetViewMode = (viewMode: ViewMode) => (dispatch: Dispatch) =>
|
export const doSetViewMode = (viewMode: ViewMode) => (dispatch: Dispatch) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -123,7 +124,13 @@ export const doRemoveUnreadSubscription = (channelUri: string, readUri: string)
|
||||||
export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
||||||
const {
|
const {
|
||||||
settings: { daemonSettings },
|
settings: { daemonSettings },
|
||||||
|
sync: { prefsReady: ready },
|
||||||
} = getState();
|
} = getState();
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
const { share_usage_data: shareSetting } = daemonSettings;
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
const isSharingData = shareSetting || IS_WEB;
|
||||||
|
|
||||||
|
@ -153,7 +160,13 @@ export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dis
|
||||||
export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: Dispatch, getState: GetState) => {
|
||||||
const {
|
const {
|
||||||
settings: { daemonSettings },
|
settings: { daemonSettings },
|
||||||
|
sync: { prefsReady: ready },
|
||||||
} = getState();
|
} = getState();
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
const { share_usage_data: shareSetting } = daemonSettings;
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
const isSharingData = shareSetting || IS_WEB;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { Lbry, doWalletEncrypt, doWalletDecrypt } from 'lbry-redux';
|
import { SETTINGS, Lbry, doWalletEncrypt, doWalletDecrypt } from 'lbry-redux';
|
||||||
|
import { selectGetSyncIsPending, selectSetSyncIsPending, selectSyncIsLocked } from 'redux/selectors/sync';
|
||||||
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
import { getSavedPassword } from 'util/saved-passwords';
|
||||||
|
import { doAnalyticsTagSync, doHandleSyncComplete } from 'redux/actions/app';
|
||||||
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
|
|
||||||
|
let syncTimer = null;
|
||||||
|
const SYNC_INTERVAL = 1000 * 60 * 5; // 5 minutes
|
||||||
|
|
||||||
export function doSetDefaultAccount(success, failure) {
|
export function doSetDefaultAccount(success, failure) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
|
@ -77,6 +85,52 @@ export function doSetSync(oldHash, newHash, data) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const doGetSyncDesktop = (cb?, password) => (dispatch, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
||||||
|
const getSyncPending = selectGetSyncIsPending(state);
|
||||||
|
const setSyncPending = selectSetSyncIsPending(state);
|
||||||
|
const syncLocked = selectSyncIsLocked(state);
|
||||||
|
|
||||||
|
return getSavedPassword().then(savedPassword => {
|
||||||
|
const passwordArgument = password || password === '' ? password : savedPassword === null ? '' : savedPassword;
|
||||||
|
|
||||||
|
if (syncEnabled && !getSyncPending && !setSyncPending && !syncLocked) {
|
||||||
|
return dispatch(doGetSync(passwordArgument, cb));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function doSyncSubscribe() {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
if (syncTimer) clearInterval(syncTimer);
|
||||||
|
const state = getState();
|
||||||
|
const hasVerifiedEmail = selectUserVerifiedEmail(state);
|
||||||
|
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
||||||
|
const syncLocked = selectSyncIsLocked(state);
|
||||||
|
if (hasVerifiedEmail && syncEnabled && !syncLocked) {
|
||||||
|
dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData))));
|
||||||
|
dispatch(doAnalyticsTagSync());
|
||||||
|
syncTimer = setInterval(() => {
|
||||||
|
const state = getState();
|
||||||
|
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
||||||
|
if (syncEnabled) {
|
||||||
|
dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData))));
|
||||||
|
dispatch(doAnalyticsTagSync());
|
||||||
|
}
|
||||||
|
}, SYNC_INTERVAL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doSyncUnsubscribe() {
|
||||||
|
return dispatch => {
|
||||||
|
if (syncTimer) {
|
||||||
|
clearInterval(syncTimer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function doGetSync(passedPassword, callback) {
|
export function doGetSync(passedPassword, callback) {
|
||||||
const password = passedPassword === null || passedPassword === undefined ? '' : passedPassword;
|
const password = passedPassword === null || passedPassword === undefined ? '' : passedPassword;
|
||||||
|
|
||||||
|
@ -280,3 +334,17 @@ export function doSyncEncryptAndDecrypt(oldPassword, newPassword, encrypt) {
|
||||||
.catch(console.error); // eslint-disable-line
|
.catch(console.error); // eslint-disable-line
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doSetSyncLock(lock) {
|
||||||
|
return {
|
||||||
|
type: ACTIONS.SET_SYNC_LOCK,
|
||||||
|
data: lock,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doSetPrefsReady() {
|
||||||
|
return {
|
||||||
|
type: ACTIONS.SET_PREFS_READY,
|
||||||
|
data: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
// @flow
|
|
||||||
import { doGetSync } from 'redux/actions/sync';
|
|
||||||
import { selectGetSyncIsPending, selectSetSyncIsPending } from 'redux/selectors/sync';
|
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
|
||||||
import { getSavedPassword } from 'util/saved-passwords';
|
|
||||||
import { doAnalyticsTagSync, doHandleSyncComplete } from 'redux/actions/app';
|
|
||||||
import { selectSyncIsLocked } from 'redux/selectors/app';
|
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import { SETTINGS } from 'lbry-redux';
|
|
||||||
|
|
||||||
let syncTimer = null;
|
|
||||||
const SYNC_INTERVAL = 1000 * 60 * 5; // 5 minutes
|
|
||||||
|
|
||||||
export const doGetSyncDesktop = (cb?: () => void, password?: string) => (dispatch: Dispatch, getState: GetState) => {
|
|
||||||
const state = getState();
|
|
||||||
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
|
||||||
const getSyncPending = selectGetSyncIsPending(state);
|
|
||||||
const setSyncPending = selectSetSyncIsPending(state);
|
|
||||||
const syncLocked = selectSyncIsLocked(state);
|
|
||||||
|
|
||||||
return getSavedPassword().then(savedPassword => {
|
|
||||||
const passwordArgument = password || password === '' ? password : savedPassword === null ? '' : savedPassword;
|
|
||||||
|
|
||||||
if (syncEnabled && !getSyncPending && !setSyncPending && !syncLocked) {
|
|
||||||
return dispatch(doGetSync(passwordArgument, cb));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function doSyncSubscribe() {
|
|
||||||
return (dispatch: Dispatch, getState: GetState) => {
|
|
||||||
if (syncTimer) clearInterval(syncTimer);
|
|
||||||
const state = getState();
|
|
||||||
const hasVerifiedEmail = selectUserVerifiedEmail(state);
|
|
||||||
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
|
||||||
const syncLocked = selectSyncIsLocked(state);
|
|
||||||
if (hasVerifiedEmail && syncEnabled && !syncLocked) {
|
|
||||||
dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData))));
|
|
||||||
dispatch(doAnalyticsTagSync());
|
|
||||||
syncTimer = setInterval(() => {
|
|
||||||
const state = getState();
|
|
||||||
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
|
||||||
if (syncEnabled) {
|
|
||||||
dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData))));
|
|
||||||
dispatch(doAnalyticsTagSync());
|
|
||||||
}
|
|
||||||
}, SYNC_INTERVAL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doSyncUnsubscribe() {
|
|
||||||
return (dispatch: Dispatch) => {
|
|
||||||
if (syncTimer) {
|
|
||||||
clearInterval(syncTimer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,15 +1,42 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { doToggleTagFollow, selectFollowedTagsList } from 'lbry-redux';
|
import { selectFollowedTagsList } from 'redux/selectors/tags';
|
||||||
|
import { selectPrefsReady } from 'redux/selectors/sync';
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
|
|
||||||
export const doToggleTagFollowDesktop = (name: string) => (dispatch: Dispatch, getState: GetState) => {
|
export const doToggleTagFollowDesktop = (name: string) => (dispatch: Dispatch, getState: GetState) => {
|
||||||
dispatch(doToggleTagFollow(name));
|
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const tags = selectFollowedTagsList(state);
|
const tags = selectFollowedTagsList(state);
|
||||||
|
const ready = selectPrefsReady(state);
|
||||||
|
if (!ready) {
|
||||||
|
return dispatch(doAlertWaitingForSync());
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.TOGGLE_TAG_FOLLOW,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const stringOfTags = tags.join(',');
|
const stringOfTags = tags.join(',');
|
||||||
if (stringOfTags) {
|
if (stringOfTags) {
|
||||||
analytics.apiSyncTags({ content_tags: stringOfTags });
|
analytics.apiSyncTags({ content_tags: stringOfTags });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const doAddTag = (name: string) => ({
|
||||||
|
type: ACTIONS.TAG_ADD,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const doDeleteTag = (name: string) => ({
|
||||||
|
type: ACTIONS.TAG_DELETE,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -42,7 +42,6 @@ export type AppState = {
|
||||||
welcomeVersion: number,
|
welcomeVersion: number,
|
||||||
allowAnalytics: boolean,
|
allowAnalytics: boolean,
|
||||||
hasNavigated: boolean,
|
hasNavigated: boolean,
|
||||||
syncLocked: boolean,
|
|
||||||
interestedInYoutubeSync: boolean,
|
interestedInYoutubeSync: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +77,6 @@ const defaultState: AppState = {
|
||||||
welcomeVersion: 0.0,
|
welcomeVersion: 0.0,
|
||||||
allowAnalytics: false,
|
allowAnalytics: false,
|
||||||
hasNavigated: false,
|
hasNavigated: false,
|
||||||
syncLocked: false,
|
|
||||||
interestedInYoutubeSync: false,
|
interestedInYoutubeSync: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,11 +111,6 @@ reducers[ACTIONS.DAEMON_READY] = state =>
|
||||||
daemonReady: true,
|
daemonReady: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
reducers[ACTIONS.SET_SYNC_LOCK] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
syncLocked: action.data,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.PASSWORD_SAVED] = (state, action) =>
|
reducers[ACTIONS.PASSWORD_SAVED] = (state, action) =>
|
||||||
Object.assign({}, state, {
|
Object.assign({}, state, {
|
||||||
isPasswordSaved: action.data,
|
isPasswordSaved: action.data,
|
||||||
|
|
|
@ -144,6 +144,12 @@ export default handleActions(
|
||||||
action: { data: { subscriptions: ?Array<string> } }
|
action: { data: { subscriptions: ?Array<string> } }
|
||||||
) => {
|
) => {
|
||||||
const { subscriptions } = action.data;
|
const { subscriptions } = action.data;
|
||||||
|
const incomingSubscriptions = Array.isArray(subscriptions) && subscriptions.length;
|
||||||
|
if (!incomingSubscriptions) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
}
|
||||||
let newSubscriptions;
|
let newSubscriptions;
|
||||||
|
|
||||||
if (!subscriptions) {
|
if (!subscriptions) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
|
@ -12,15 +13,35 @@ const defaultState = {
|
||||||
syncApplyPasswordError: false,
|
syncApplyPasswordError: false,
|
||||||
getSyncIsPending: false,
|
getSyncIsPending: false,
|
||||||
setSyncIsPending: false,
|
setSyncIsPending: false,
|
||||||
|
prefsReady: false,
|
||||||
|
syncLocked: false,
|
||||||
hashChanged: false,
|
hashChanged: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = state => {
|
||||||
|
const { syncReady } = state;
|
||||||
|
if (!syncReady) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
prefsReady: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Object.assign({}, state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[ACTIONS.SET_PREFS_READY] = (state, action) => Object.assign({}, state, { prefsReady: action.data });
|
||||||
|
|
||||||
reducers[ACTIONS.GET_SYNC_STARTED] = state =>
|
reducers[ACTIONS.GET_SYNC_STARTED] = state =>
|
||||||
Object.assign({}, state, {
|
Object.assign({}, state, {
|
||||||
getSyncIsPending: true,
|
getSyncIsPending: true,
|
||||||
getSyncErrorMessage: null,
|
getSyncErrorMessage: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reducers[ACTIONS.SET_SYNC_LOCK] = (state, action) =>
|
||||||
|
Object.assign({}, state, {
|
||||||
|
syncLocked: action.data,
|
||||||
|
});
|
||||||
|
|
||||||
reducers[ACTIONS.GET_SYNC_COMPLETED] = (state, action) =>
|
reducers[ACTIONS.GET_SYNC_COMPLETED] = (state, action) =>
|
||||||
Object.assign({}, state, {
|
Object.assign({}, state, {
|
||||||
syncHash: action.data.syncHash,
|
syncHash: action.data.syncHash,
|
||||||
|
|
82
ui/redux/reducers/tags.js
Normal file
82
ui/redux/reducers/tags.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// @flow
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { ACTIONS as LBRY_REDUX_ACTIONS, DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS } from 'lbry-redux';
|
||||||
|
import { handleActions } from 'util/redux-utils';
|
||||||
|
|
||||||
|
function getDefaultKnownTags() {
|
||||||
|
return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce(
|
||||||
|
(tagsMap, tag) => ({
|
||||||
|
...tagsMap,
|
||||||
|
[tag]: { name: tag },
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultState: TagState = {
|
||||||
|
followedTags: [],
|
||||||
|
knownTags: getDefaultKnownTags(),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default handleActions(
|
||||||
|
{
|
||||||
|
[ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => {
|
||||||
|
const { followedTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newFollowedTags = followedTags.slice();
|
||||||
|
|
||||||
|
if (newFollowedTags.includes(name)) {
|
||||||
|
newFollowedTags = newFollowedTags.filter(tag => tag !== name);
|
||||||
|
} else {
|
||||||
|
newFollowedTags.push(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
followedTags: newFollowedTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => {
|
||||||
|
const { knownTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newKnownTags = { ...knownTags };
|
||||||
|
newKnownTags[name] = { name };
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
knownTags: newKnownTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => {
|
||||||
|
const { knownTags, followedTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newKnownTags = { ...knownTags };
|
||||||
|
delete newKnownTags[name];
|
||||||
|
const newFollowedTags = followedTags.filter(tag => tag !== name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
knownTags: newKnownTags,
|
||||||
|
followedTags: newFollowedTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE]: (state: TagState, action: { data: { tags: ?Array<string> } }) => {
|
||||||
|
const { tags } = action.data;
|
||||||
|
if (Array.isArray(tags)) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
followedTags: tags,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultState
|
||||||
|
);
|
|
@ -81,6 +81,4 @@ export const selectScrollStartingPosition = createSelector(selectState, state =>
|
||||||
|
|
||||||
export const selectIsPasswordSaved = createSelector(selectState, state => state.isPasswordSaved);
|
export const selectIsPasswordSaved = createSelector(selectState, state => state.isPasswordSaved);
|
||||||
|
|
||||||
export const selectSyncIsLocked = createSelector(selectState, state => state.syncLocked);
|
|
||||||
|
|
||||||
export const selectInterestedInYoutubeSync = createSelector(selectState, state => state.interestedInYoutubeSync);
|
export const selectInterestedInYoutubeSync = createSelector(selectState, state => state.interestedInYoutubeSync);
|
||||||
|
|
|
@ -23,3 +23,7 @@ export const selectSyncApplyIsPending = createSelector(selectState, state => sta
|
||||||
export const selectSyncApplyErrorMessage = createSelector(selectState, state => state.syncApplyErrorMessage);
|
export const selectSyncApplyErrorMessage = createSelector(selectState, state => state.syncApplyErrorMessage);
|
||||||
|
|
||||||
export const selectSyncApplyPasswordError = createSelector(selectState, state => state.syncApplyPasswordError);
|
export const selectSyncApplyPasswordError = createSelector(selectState, state => state.syncApplyPasswordError);
|
||||||
|
|
||||||
|
export const selectSyncIsLocked = createSelector(selectState, state => state.syncLocked);
|
||||||
|
|
||||||
|
export const selectPrefsReady = createSelector(selectState, state => state.prefsReady);
|
||||||
|
|
36
ui/redux/selectors/tags.js
Normal file
36
ui/redux/selectors/tags.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// @flow
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
const selectState = (state: { tags: TagState }) => state.tags || {};
|
||||||
|
|
||||||
|
export const selectKnownTagsByName = createSelector(selectState, (state: TagState): KnownTags => state.knownTags);
|
||||||
|
|
||||||
|
export const selectFollowedTagsList = createSelector(selectState, (state: TagState): Array<string> =>
|
||||||
|
state.followedTags.filter(tag => typeof tag === 'string')
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectFollowedTags = createSelector(selectFollowedTagsList, (followedTags: Array<string>): Array<Tag> =>
|
||||||
|
followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectUnfollowedTags = createSelector(
|
||||||
|
selectKnownTagsByName,
|
||||||
|
selectFollowedTagsList,
|
||||||
|
(tagsByName: KnownTags, followedTags: Array<string>): Array<Tag> => {
|
||||||
|
const followedTagsSet = new Set(followedTags);
|
||||||
|
let tagsToReturn = [];
|
||||||
|
Object.keys(tagsByName).forEach(key => {
|
||||||
|
if (!followedTagsSet.has(key)) {
|
||||||
|
const { name } = tagsByName[key];
|
||||||
|
tagsToReturn.push({ name: name.toLowerCase() });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return tagsToReturn;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const makeSelectIsFollowingTag = (tag: string) =>
|
||||||
|
createSelector(selectFollowedTags, followedTags => {
|
||||||
|
return followedTags.some(followedTag => followedTag.name === tag.toLowerCase());
|
||||||
|
});
|
|
@ -10,7 +10,7 @@ import { createMemoryHistory, createBrowserHistory } from 'history';
|
||||||
import { routerMiddleware } from 'connected-react-router';
|
import { routerMiddleware } from 'connected-react-router';
|
||||||
import createRootReducer from './reducers';
|
import createRootReducer from './reducers';
|
||||||
import { Lbry, buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
|
import { Lbry, buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
|
||||||
import { doSyncSubscribe } from 'redux/actions/syncwrapper';
|
import { doSyncSubscribe } from 'redux/actions/sync';
|
||||||
import { getAuthToken } from 'util/saved-passwords';
|
import { getAuthToken } from 'util/saved-passwords';
|
||||||
import { generateInitialUrl } from 'util/url';
|
import { generateInitialUrl } from 'util/url';
|
||||||
import { X_LBRY_AUTH_TOKEN } from 'constants/token';
|
import { X_LBRY_AUTH_TOKEN } from 'constants/token';
|
||||||
|
@ -120,7 +120,7 @@ const triggerSharedStateActions = [
|
||||||
ACTIONS.CHANNEL_SUBSCRIBE,
|
ACTIONS.CHANNEL_SUBSCRIBE,
|
||||||
ACTIONS.CHANNEL_UNSUBSCRIBE,
|
ACTIONS.CHANNEL_UNSUBSCRIBE,
|
||||||
ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
||||||
LBRY_REDUX_ACTIONS.TOGGLE_TAG_FOLLOW,
|
ACTIONS.TOGGLE_TAG_FOLLOW,
|
||||||
LBRY_REDUX_ACTIONS.CREATE_CHANNEL_COMPLETED,
|
LBRY_REDUX_ACTIONS.CREATE_CHANNEL_COMPLETED,
|
||||||
ACTIONS.SYNC_CLIENT_SETTINGS,
|
ACTIONS.SYNC_CLIENT_SETTINGS,
|
||||||
// Disabled until we can overwrite preferences
|
// Disabled until we can overwrite preferences
|
||||||
|
|
Loading…
Add table
Reference in a new issue