mostly remove is_web #7408
54 changed files with 302 additions and 618 deletions
|
@ -3,22 +3,10 @@ import { Lbryio } from 'lbryinc';
|
||||||
import * as Sentry from '@sentry/browser';
|
import * as Sentry from '@sentry/browser';
|
||||||
import MatomoTracker from '@datapunt/matomo-tracker-js';
|
import MatomoTracker from '@datapunt/matomo-tracker-js';
|
||||||
import { history } from './store';
|
import { history } from './store';
|
||||||
import { SDK_API_PATH } from './index';
|
|
||||||
// @if TARGET='app'
|
|
||||||
import Native from 'native';
|
import Native from 'native';
|
||||||
import ElectronCookies from '@meetfranz/electron-cookies';
|
import ElectronCookies from '@meetfranz/electron-cookies';
|
||||||
import { generateInitialUrl } from 'util/url';
|
import { generateInitialUrl } from 'util/url';
|
||||||
// @endif
|
|
||||||
import { MATOMO_ID, MATOMO_URL } from 'config';
|
import { MATOMO_ID, MATOMO_URL } from 'config';
|
||||||
// import getConnectionSpeed from 'util/detect-user-bandwidth';
|
|
||||||
|
|
||||||
// let userDownloadBandwidthInBitsPerSecond;
|
|
||||||
// async function getUserBandwidth() {
|
|
||||||
// userDownloadBandwidthInBitsPerSecond = await getConnectionSpeed();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// get user bandwidth every minute, starting after an initial one minute wait
|
|
||||||
// setInterval(getUserBandwidth, 1000 * 60);
|
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === 'production';
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.includes('dev');
|
const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.includes('dev');
|
||||||
|
@ -27,7 +15,7 @@ export const SHARE_INTERNAL = 'shareInternal';
|
||||||
const SHARE_THIRD_PARTY = 'shareThirdParty';
|
const SHARE_THIRD_PARTY = 'shareThirdParty';
|
||||||
|
|
||||||
const WATCHMAN_BACKEND_ENDPOINT = 'https://watchman.na-backend.odysee.com/reports/playback';
|
const WATCHMAN_BACKEND_ENDPOINT = 'https://watchman.na-backend.odysee.com/reports/playback';
|
||||||
const SEND_DATA_TO_WATCHMAN_INTERVAL = 10; // in seconds
|
// const SEND_DATA_TO_WATCHMAN_INTERVAL = 10; // in seconds
|
||||||
|
|
||||||
if (isProduction) {
|
if (isProduction) {
|
||||||
ElectronCookies.enable({
|
ElectronCookies.enable({
|
||||||
|
@ -80,7 +68,7 @@ type LogPublishParams = {
|
||||||
channel_claim_id?: string,
|
channel_claim_id?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
let internalAnalyticsEnabled: boolean = IS_WEB || false;
|
let internalAnalyticsEnabled: boolean = false;
|
||||||
if (window.localStorage.getItem(SHARE_INTERNAL) === 'true') internalAnalyticsEnabled = true;
|
if (window.localStorage.getItem(SHARE_INTERNAL) === 'true') internalAnalyticsEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,11 +152,6 @@ function startWatchmanIntervalIfNotRunning() {
|
||||||
if (!watchmanInterval) {
|
if (!watchmanInterval) {
|
||||||
// instantiate the first time to calculate duration from
|
// instantiate the first time to calculate duration from
|
||||||
lastSentTime = new Date();
|
lastSentTime = new Date();
|
||||||
|
|
||||||
// only set an interval if analytics are enabled and is prod
|
|
||||||
if (isProduction && IS_WEB) {
|
|
||||||
watchmanInterval = setInterval(sendAndResetWatchmanData, 1000 * SEND_DATA_TO_WATCHMAN_INTERVAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +223,7 @@ const analytics: Analytics = {
|
||||||
videoPlayer = passedPlayer;
|
videoPlayer = passedPlayer;
|
||||||
bitrateAsBitsPerSecond = videoBitrate;
|
bitrateAsBitsPerSecond = videoBitrate;
|
||||||
|
|
||||||
sendPromMetric('time_to_start', duration);
|
// sendPromMetric('time_to_start', duration);
|
||||||
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
||||||
},
|
},
|
||||||
error: (message) => {
|
error: (message) => {
|
||||||
|
@ -313,7 +296,7 @@ const analytics: Analytics = {
|
||||||
claim_id: claimId,
|
claim_id: claimId,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (timeToStart && !IS_WEB) {
|
if (timeToStart) {
|
||||||
params.time_to_start = timeToStart;
|
params.time_to_start = timeToStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,14 +388,15 @@ function sendMatomoEvent(category, action, name, value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendPromMetric(name: string, value?: number) {
|
// Prometheus
|
||||||
if (IS_WEB) {
|
// function sendPromMetric(name: string, value?: number) {
|
||||||
let url = new URL(SDK_API_PATH + '/metric/ui');
|
// if (IS_WEB) {
|
||||||
const params = { name: name, value: value ? value.toString() : '' };
|
// let url = new URL(SDK_API_PATH + '/metric/ui');
|
||||||
url.search = new URLSearchParams(params).toString();
|
// const params = { name: name, value: value ? value.toString() : '' };
|
||||||
return fetch(url, { method: 'post' });
|
// url.search = new URLSearchParams(params).toString();
|
||||||
}
|
// return fetch(url, { method: 'post' });
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
const MatomoInstance = new MatomoTracker({
|
const MatomoInstance = new MatomoTracker({
|
||||||
urlBase: MATOMO_URL,
|
urlBase: MATOMO_URL,
|
||||||
|
|
|
@ -314,7 +314,6 @@ function App(props: Props) {
|
||||||
if (!hasSignedIn && hasVerifiedEmail) {
|
if (!hasSignedIn && hasVerifiedEmail) {
|
||||||
signIn();
|
signIn();
|
||||||
setHasSignedIn(true);
|
setHasSignedIn(true);
|
||||||
if (IS_WEB) setReadyForSync(true);
|
|
||||||
}
|
}
|
||||||
}, [hasVerifiedEmail, signIn, hasSignedIn]);
|
}, [hasVerifiedEmail, signIn, hasSignedIn]);
|
||||||
|
|
||||||
|
@ -339,7 +338,7 @@ function App(props: Props) {
|
||||||
[`${MAIN_WRAPPER_CLASS}--scrollbar`]: useCustomScrollbar,
|
[`${MAIN_WRAPPER_CLASS}--scrollbar`]: useCustomScrollbar,
|
||||||
})}
|
})}
|
||||||
ref={appRef}
|
ref={appRef}
|
||||||
onContextMenu={IS_WEB ? undefined : (e) => openContextMenu(e)}
|
onContextMenu={(e) => openContextMenu(e)}
|
||||||
>
|
>
|
||||||
<Router />
|
<Router />
|
||||||
<ModalRouter />
|
<ModalRouter />
|
||||||
|
|
|
@ -29,7 +29,6 @@ export default function CollectionAddButton(props: Props) {
|
||||||
icon={fileAction ? (!isSaved ? ICONS.ADD : ICONS.STACK) : ICONS.LIBRARY}
|
icon={fileAction ? (!isSaved ? ICONS.ADD : ICONS.STACK) : ICONS.LIBRARY}
|
||||||
iconSize={fileAction ? 22 : undefined}
|
iconSize={fileAction ? 22 : undefined}
|
||||||
label={uri ? (!isSaved ? __('Save') : __('Saved')) : __('New List')}
|
label={uri ? (!isSaved ? __('Save') : __('Saved')) : __('New List')}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={__('Add this claim to a list')}
|
title={__('Add this claim to a list')}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
@ -27,7 +27,6 @@ import {
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
|
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
|
||||||
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import { selectListShuffle } from 'redux/selectors/content';
|
import { selectListShuffle } from 'redux/selectors/content';
|
||||||
import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
|
import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
|
||||||
import ClaimPreview from './view';
|
import ClaimPreview from './view';
|
||||||
|
@ -69,7 +68,6 @@ const select = (state, props) => {
|
||||||
claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state),
|
claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state),
|
||||||
isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
|
isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
|
||||||
editedCollection: makeSelectEditedCollectionForId(collectionId)(state),
|
editedCollection: makeSelectEditedCollectionForId(collectionId)(state),
|
||||||
isAuthenticated: Boolean(selectUserVerifiedEmail(state)),
|
|
||||||
resolvedList: makeSelectUrlsForCollectionId(collectionId)(state),
|
resolvedList: makeSelectUrlsForCollectionId(collectionId)(state),
|
||||||
playNextUri,
|
playNextUri,
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,13 +8,7 @@ import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import {
|
import { generateShareUrl, generateLbryContentUrl, formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
|
||||||
generateShareUrl,
|
|
||||||
generateRssUrl,
|
|
||||||
generateLbryContentUrl,
|
|
||||||
formatLbryUrlForWeb,
|
|
||||||
generateListSearchUrlParams,
|
|
||||||
} from 'util/url';
|
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { buildURI, parseURI } from 'util/lbryURI';
|
import { buildURI, parseURI } from 'util/lbryURI';
|
||||||
|
|
||||||
|
@ -62,7 +56,6 @@ type Props = {
|
||||||
doChannelUnsubscribe: (SubscriptionArgs) => void,
|
doChannelUnsubscribe: (SubscriptionArgs) => void,
|
||||||
isChannelPage: boolean,
|
isChannelPage: boolean,
|
||||||
editedCollection: Collection,
|
editedCollection: Collection,
|
||||||
isAuthenticated: boolean,
|
|
||||||
playNextUri: string,
|
playNextUri: string,
|
||||||
resolvedList: boolean,
|
resolvedList: boolean,
|
||||||
fetchCollectionItems: (string) => void,
|
fetchCollectionItems: (string) => void,
|
||||||
|
@ -103,7 +96,6 @@ function ClaimMenuList(props: Props) {
|
||||||
doChannelUnsubscribe,
|
doChannelUnsubscribe,
|
||||||
isChannelPage = false,
|
isChannelPage = false,
|
||||||
editedCollection,
|
editedCollection,
|
||||||
isAuthenticated,
|
|
||||||
playNextUri,
|
playNextUri,
|
||||||
resolvedList,
|
resolvedList,
|
||||||
fetchCollectionItems,
|
fetchCollectionItems,
|
||||||
|
@ -150,7 +142,6 @@ function ClaimMenuList(props: Props) {
|
||||||
|
|
||||||
const lbryUrl: string = generateLbryContentUrl(claim.canonical_url, claim.permanent_url);
|
const lbryUrl: string = generateLbryContentUrl(claim.canonical_url, claim.permanent_url);
|
||||||
const shareUrl: string = generateShareUrl(SHARE_DOMAIN, lbryUrl);
|
const shareUrl: string = generateShareUrl(SHARE_DOMAIN, lbryUrl);
|
||||||
const rssUrl: string = isChannel ? generateRssUrl(SHARE_DOMAIN, claim) : '';
|
|
||||||
const isCollectionClaim = claim && claim.value_type === 'collection';
|
const isCollectionClaim = claim && claim.value_type === 'collection';
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
const isPlayable =
|
const isPlayable =
|
||||||
|
@ -252,10 +243,6 @@ function ClaimMenuList(props: Props) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCopyRssLink() {
|
|
||||||
copyToClipboard(rssUrl, 'RSS URL copied.', 'Failed to copy RSS URL.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleCopyLink() {
|
function handleCopyLink() {
|
||||||
copyToClipboard(shareUrl, 'Link copied.', 'Failed to copy link.');
|
copyToClipboard(shareUrl, 'Link copied.', 'Failed to copy link.');
|
||||||
}
|
}
|
||||||
|
@ -281,7 +268,6 @@ function ClaimMenuList(props: Props) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const shouldShow = !IS_WEB || (IS_WEB && isAuthenticated);
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
|
@ -343,7 +329,6 @@ function ClaimMenuList(props: Props) {
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
shouldShow &&
|
|
||||||
isPlayable && (
|
isPlayable && (
|
||||||
<>
|
<>
|
||||||
{/* WATCH LATER */}
|
{/* WATCH LATER */}
|
||||||
|
@ -381,105 +366,89 @@ function ClaimMenuList(props: Props) {
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
{!isChannelPage && (
|
||||||
{shouldShow && (
|
|
||||||
<>
|
<>
|
||||||
{!isChannelPage && (
|
<MenuItem className="comment__menu-option" onSelect={handleSupport}>
|
||||||
<>
|
<div className="menu__link">
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleSupport}>
|
<Icon aria-hidden icon={ICONS.LBC} />
|
||||||
<div className="menu__link">
|
{__('Support --[button to support a claim]--')}
|
||||||
<Icon aria-hidden icon={ICONS.LBC} />
|
</div>
|
||||||
{__('Support --[button to support a claim]--')}
|
</MenuItem>
|
||||||
</div>
|
</>
|
||||||
</MenuItem>
|
)}
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!incognitoClaim && !claimIsMine && !isChannelPage && (
|
{!incognitoClaim && !claimIsMine && !isChannelPage && (
|
||||||
<>
|
<>
|
||||||
<hr className="menu__separator" />
|
<hr className="menu__separator" />
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleFollow}>
|
<MenuItem className="comment__menu-option" onSelect={handleFollow}>
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
<Icon aria-hidden icon={ICONS.SUBSCRIBE} />
|
<Icon aria-hidden icon={ICONS.SUBSCRIBE} />
|
||||||
{subscriptionLabel}
|
{subscriptionLabel}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isMyCollection && (
|
{!isMyCollection && (
|
||||||
<>
|
<>
|
||||||
{(!claimIsMine || channelIsBlocked) && contentChannelUri ? (
|
{(!claimIsMine || channelIsBlocked) && contentChannelUri ? (
|
||||||
!incognitoClaim && (
|
!incognitoClaim && (
|
||||||
<>
|
<>
|
||||||
<hr className="menu__separator" />
|
<hr className="menu__separator" />
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleToggleBlock}>
|
<MenuItem className="comment__menu-option" onSelect={handleToggleBlock}>
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.BLOCK} />
|
|
||||||
{channelIsBlocked ? __('Unblock Channel') : __('Block Channel')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
|
|
||||||
{isAdmin && (
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleToggleAdminBlock}>
|
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.GLOBE} />
|
|
||||||
{channelIsAdminBlocked ? __('Global Unblock Channel') : __('Global Block Channel')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleToggleMute}>
|
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.MUTE} />
|
|
||||||
{channelIsMuted ? __('Unmute Channel') : __('Mute Channel')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{!isChannelPage && !repostedClaim && (
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleEdit}>
|
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.EDIT} />
|
|
||||||
{__('Edit')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{showDelete && (
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleDelete}>
|
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
<Icon aria-hidden icon={ICONS.DELETE} />
|
<Icon aria-hidden icon={ICONS.BLOCK} />
|
||||||
{__('Delete')}
|
{channelIsBlocked ? __('Unblock Channel') : __('Block Channel')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
|
{isAdmin && (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleToggleAdminBlock}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.GLOBE} />
|
||||||
|
{channelIsAdminBlocked ? __('Global Unblock Channel') : __('Global Block Channel')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleToggleMute}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.MUTE} />
|
||||||
|
{channelIsMuted ? __('Unmute Channel') : __('Mute Channel')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{!isChannelPage && !repostedClaim && (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleEdit}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.EDIT} />
|
||||||
|
{__('Edit')}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<hr className="menu__separator" />
|
|
||||||
|
{showDelete && (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleDelete}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.DELETE} />
|
||||||
|
{__('Delete')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<hr className="menu__separator" />
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleCopyLink}>
|
<MenuItem className="comment__menu-option" onSelect={handleCopyLink}>
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
<Icon aria-hidden icon={ICONS.COPY_LINK} />
|
<Icon aria-hidden icon={ICONS.COPY_LINK} />
|
||||||
{__('Copy Link')}
|
{__('Copy Link')}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
{isChannelPage && IS_WEB && rssUrl && (
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleCopyRssLink}>
|
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.RSS} />
|
|
||||||
{__('Copy RSS URL')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!claimIsMine && !isMyCollection && (
|
{!claimIsMine && !isMyCollection && (
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleReportContent}>
|
<MenuItem className="comment__menu-option" onSelect={handleReportContent}>
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
|
|
|
@ -6,15 +6,15 @@ import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
hasChannels: boolean,
|
hasChannels: boolean,
|
||||||
doOpenModal: (string, {}) => void,
|
doOpenModal: (string, {}) => void,
|
||||||
doToast: ({ message: string }) => void,
|
doToast: ({ message: string }) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ClaimRepostButton(props: Props) {
|
export default function ClaimRepostButton(props: Props) {
|
||||||
const { uri, claim, hasChannels, doOpenModal, doToast } = props;
|
const { uri, claim, hasChannels, doOpenModal, doToast } = props;
|
||||||
const [contentUri, setContentUri] = React.useState('');
|
const [contentUri, setContentUri] = React.useState('');
|
||||||
const [repostUri, setRepostUri] = React.useState('');
|
const [repostUri, setRepostUri] = React.useState('');
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ export default function ClaimRepostButton(props: Props) {
|
||||||
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
|
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
|
||||||
}
|
}
|
||||||
description={__('Repost')}
|
description={__('Repost')}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!hasChannels) {
|
if (!hasChannels) {
|
||||||
doToast({
|
doToast({
|
||||||
|
|
|
@ -28,7 +28,6 @@ export default function ClaimSupportButton(props: Props) {
|
||||||
icon={ICONS.LBC}
|
icon={ICONS.LBC}
|
||||||
iconSize={fileAction ? 22 : undefined}
|
iconSize={fileAction ? 22 : undefined}
|
||||||
label={isRepost ? __('Support Repost') : __('Support --[button to support a claim]--')}
|
label={isRepost ? __('Support Repost') : __('Support --[button to support a claim]--')}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={__('Support this claim')}
|
title={__('Support this claim')}
|
||||||
onClick={() => doOpenModal(MODALS.SEND_TIP, { uri, isSupport: true })}
|
onClick={() => doOpenModal(MODALS.SEND_TIP, { uri, isSupport: true })}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { DOMAIN } from 'config';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
@ -90,7 +89,7 @@ function CollectionForm(props: Props) {
|
||||||
onDone,
|
onDone,
|
||||||
} = props;
|
} = props;
|
||||||
const activeChannelName = activeChannelClaim && activeChannelClaim.name;
|
const activeChannelName = activeChannelClaim && activeChannelClaim.name;
|
||||||
let prefix = IS_WEB ? `${DOMAIN}/` : 'lbry://';
|
let prefix = 'lbry://';
|
||||||
if (activeChannelName && !incognito) {
|
if (activeChannelName && !incognito) {
|
||||||
prefix += `${activeChannelName}/`;
|
prefix += `${activeChannelName}/`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { doCommentUpdate, doCommentList } from 'redux/actions/comments';
|
||||||
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import {
|
import {
|
||||||
selectLinkedCommentAncestors,
|
selectLinkedCommentAncestors,
|
||||||
selectOthersReactsForComment,
|
selectOthersReactsForComment,
|
||||||
|
@ -28,7 +27,7 @@ const select = (state, props) => {
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state),
|
thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state),
|
||||||
channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state),
|
channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state),
|
||||||
commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
|
commentingEnabled: true,
|
||||||
othersReacts: selectOthersReactsForComment(state, reactionKey),
|
othersReacts: selectOthersReactsForComment(state, reactionKey),
|
||||||
activeChannelClaim,
|
activeChannelClaim,
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
|
|
|
@ -314,13 +314,7 @@ function Comment(props: Props) {
|
||||||
textAreaMaxLength={FF_MAX_CHARS_IN_COMMENT}
|
textAreaMaxLength={FF_MAX_CHARS_IN_COMMENT}
|
||||||
/>
|
/>
|
||||||
<div className="section__actions section__actions--no-margin">
|
<div className="section__actions section__actions--no-margin">
|
||||||
<Button
|
<Button button="primary" type="submit" label={__('Done')} disabled={message === editedMessage} />
|
||||||
button="primary"
|
|
||||||
type="submit"
|
|
||||||
label={__('Done')}
|
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
disabled={message === editedMessage}
|
|
||||||
/>
|
|
||||||
<Button button="link" label={__('Cancel')} onClick={() => setEditing(false)} />
|
<Button button="link" label={__('Cancel')} onClick={() => setEditing(false)} />
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -354,7 +348,6 @@ function Comment(props: Props) {
|
||||||
<div className="comment__actions">
|
<div className="comment__actions">
|
||||||
{threadDepth !== 0 && (
|
{threadDepth !== 0 && (
|
||||||
<Button
|
<Button
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
label={commentingEnabled ? __('Reply') : __('Log in to reply')}
|
label={commentingEnabled ? __('Reply') : __('Log in to reply')}
|
||||||
className="comment__action"
|
className="comment__action"
|
||||||
onClick={handleCommentReply}
|
onClick={handleCommentReply}
|
||||||
|
|
|
@ -443,7 +443,7 @@ export function CommentCreate(props: Props) {
|
||||||
>
|
>
|
||||||
<FormField type="textarea" name={'comment_signup_prompt'} placeholder={__('Say something about this...')} />
|
<FormField type="textarea" name={'comment_signup_prompt'} placeholder={__('Say something about this...')} />
|
||||||
<div className="section__actions--no-margin">
|
<div className="section__actions--no-margin">
|
||||||
<Button disabled button="primary" label={__('Post --[button to submit something]--')} requiresAuth={IS_WEB} />
|
<Button disabled button="primary" label={__('Post --[button to submit something]--')} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -553,7 +553,6 @@ export function CommentCreate(props: Props) {
|
||||||
icon={activeTab === TAB_LBC ? ICONS.LBC : ICONS.FINANCE}
|
icon={activeTab === TAB_LBC ? ICONS.LBC : ICONS.FINANCE}
|
||||||
label={__('Review')}
|
label={__('Review')}
|
||||||
onClick={() => setIsReviewingSupportComment(true)}
|
onClick={() => setIsReviewingSupportComment(true)}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -580,7 +579,6 @@ export function CommentCreate(props: Props) {
|
||||||
? __('Commenting...')
|
? __('Commenting...')
|
||||||
: __('Comment --[button to submit something]--')
|
: __('Comment --[button to submit something]--')
|
||||||
}
|
}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!supportDisabled && !claimIsMine && (
|
{!supportDisabled && !claimIsMine && (
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { doChannelMute } from 'redux/actions/blocked';
|
||||||
import { doCommentPin, doCommentModAddDelegate } from 'redux/actions/comments';
|
import { doCommentPin, doCommentModAddDelegate } from 'redux/actions/comments';
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
|
||||||
import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
|
import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
|
||||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||||
import { selectModerationDelegatorsById } from 'redux/selectors/comments';
|
import { selectModerationDelegatorsById } from 'redux/selectors/comments';
|
||||||
|
@ -28,7 +27,6 @@ const perform = (dispatch) => ({
|
||||||
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
|
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
|
||||||
commentModAddDelegate: (modChanId, modChanName, creatorChannelClaim) =>
|
commentModAddDelegate: (modChanId, modChanName, creatorChannelClaim) =>
|
||||||
dispatch(doCommentModAddDelegate(modChanId, modChanName, creatorChannelClaim, true)),
|
dispatch(doCommentModAddDelegate(modChanId, modChanName, creatorChannelClaim, true)),
|
||||||
doToast: (props) => dispatch(doToast(props)),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(CommentMenuList);
|
export default connect(select, perform)(CommentMenuList);
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
import { getChannelFromClaim } from 'util/claim';
|
import { getChannelFromClaim } from 'util/claim';
|
||||||
import { MenuList, MenuItem } from '@reach/menu-button';
|
import { MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import { parseURI } from 'util/lbryURI';
|
import { parseURI } from 'util/lbryURI';
|
||||||
import { URL } from 'config';
|
|
||||||
import { useHistory } from 'react-router';
|
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import ChannelThumbnail from 'component/channelThumbnail';
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
|
@ -54,7 +52,6 @@ function CommentMenuList(props: Props) {
|
||||||
disableEdit,
|
disableEdit,
|
||||||
disableRemove,
|
disableRemove,
|
||||||
supportAmount,
|
supportAmount,
|
||||||
doToast,
|
|
||||||
handleEditComment,
|
handleEditComment,
|
||||||
openModal,
|
openModal,
|
||||||
clearPlayingUri,
|
clearPlayingUri,
|
||||||
|
@ -64,10 +61,6 @@ function CommentMenuList(props: Props) {
|
||||||
setQuickReply,
|
setQuickReply,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const {
|
|
||||||
location: { pathname, search },
|
|
||||||
} = useHistory();
|
|
||||||
|
|
||||||
const contentChannelClaim = getChannelFromClaim(claim);
|
const contentChannelClaim = getChannelFromClaim(claim);
|
||||||
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
|
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
|
||||||
const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl;
|
const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl;
|
||||||
|
@ -151,15 +144,6 @@ function CommentMenuList(props: Props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCopyCommentLink() {
|
|
||||||
const urlParams = new URLSearchParams(search);
|
|
||||||
urlParams.delete('lc');
|
|
||||||
urlParams.append('lc', commentId);
|
|
||||||
navigator.clipboard
|
|
||||||
.writeText(`${URL}${pathname}?${urlParams.toString()}`)
|
|
||||||
.then(() => doToast({ message: __('Link copied.') }));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuList className="menu__list">
|
<MenuList className="menu__list">
|
||||||
{activeChannelIsCreator && <div className="comment__menu-title">{__('Creator tools')}</div>}
|
{activeChannelIsCreator && <div className="comment__menu-title">{__('Creator tools')}</div>}
|
||||||
|
@ -229,15 +213,6 @@ function CommentMenuList(props: Props) {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{IS_WEB && (
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleCopyCommentLink}>
|
|
||||||
<div className="menu__link">
|
|
||||||
<Icon aria-hidden icon={ICONS.COPY_LINK} />
|
|
||||||
{__('Copy Link')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{activeChannelClaim && (
|
{activeChannelClaim && (
|
||||||
<div className="comment__menu-active">
|
<div className="comment__menu-active">
|
||||||
<ChannelThumbnail xsmall noLazyLoad uri={activeChannelClaim.permanent_url} />
|
<ChannelThumbnail xsmall noLazyLoad uri={activeChannelClaim.permanent_url} />
|
||||||
|
|
|
@ -99,7 +99,6 @@ export default function CommentReactions(props: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={__('Upvote')}
|
title={__('Upvote')}
|
||||||
icon={likeIcon}
|
icon={likeIcon}
|
||||||
className={classnames('comment__action', {
|
className={classnames('comment__action', {
|
||||||
|
@ -109,7 +108,6 @@ export default function CommentReactions(props: Props) {
|
||||||
label={<span className="comment__reaction-count">{getCountForReact(REACTION_TYPES.LIKE)}</span>}
|
label={<span className="comment__reaction-count">{getCountForReact(REACTION_TYPES.LIKE)}</span>}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={__('Downvote')}
|
title={__('Downvote')}
|
||||||
icon={dislikeIcon}
|
icon={dislikeIcon}
|
||||||
className={classnames('comment__action', {
|
className={classnames('comment__action', {
|
||||||
|
@ -122,7 +120,6 @@ export default function CommentReactions(props: Props) {
|
||||||
{!shouldHide && ENABLE_CREATOR_REACTIONS && (canCreatorReact || creatorLiked) && (
|
{!shouldHide && ENABLE_CREATOR_REACTIONS && (canCreatorReact || creatorLiked) && (
|
||||||
<Button
|
<Button
|
||||||
disabled={!canCreatorReact || !claimIsMine}
|
disabled={!canCreatorReact || !claimIsMine}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={claimIsMine ? __('You loved this') : __('Creator loved this')}
|
title={claimIsMine ? __('You loved this') : __('Creator loved this')}
|
||||||
icon={creatorLiked ? ICONS.CREATOR_LIKE : ICONS.SUBSCRIBE}
|
icon={creatorLiked ? ICONS.CREATOR_LIKE : ICONS.SUBSCRIBE}
|
||||||
className={classnames('comment__action comment__action--creator-like')}
|
className={classnames('comment__action comment__action--creator-like')}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { connect } from 'react-redux';
|
||||||
import { doResolveUris } from 'redux/actions/claims';
|
import { doResolveUris } from 'redux/actions/claims';
|
||||||
import { makeSelectClaimIsMine, selectMyChannelClaims, makeSelectClaimForUri } from 'redux/selectors/claims';
|
import { makeSelectClaimIsMine, selectMyChannelClaims, makeSelectClaimForUri } from 'redux/selectors/claims';
|
||||||
import { selectIsFetchingCommentsByParentId, selectRepliesForParentId } from 'redux/selectors/comments';
|
import { selectIsFetchingCommentsByParentId, selectRepliesForParentId } from 'redux/selectors/comments';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import CommentsReplies from './view';
|
import CommentsReplies from './view';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
|
@ -16,7 +15,7 @@ const select = (state, props) => {
|
||||||
fetchedReplies,
|
fetchedReplies,
|
||||||
resolvedReplies,
|
resolvedReplies,
|
||||||
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
||||||
userCanComment: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
|
userCanComment: true,
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
isFetchingByParentId: selectIsFetchingCommentsByParentId(state),
|
isFetchingByParentId: selectIsFetchingCommentsByParentId(state),
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,9 +19,7 @@ export default function HiddenNsfw(props: Props) {
|
||||||
<I18nMessage
|
<I18nMessage
|
||||||
tokens={{
|
tokens={{
|
||||||
type,
|
type,
|
||||||
settings: (
|
settings: <Button button="link" label={__('settings')} navigate={`/$/${PAGES.SETTINGS}`} />,
|
||||||
<Button button="link" label={__('settings')} navigate={`/$/${PAGES.SETTINGS}`} requiresAuth={IS_WEB} />
|
|
||||||
),
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Content may be hidden on this %type% because of your %settings%.
|
Content may be hidden on this %type% because of your %settings%.
|
||||||
|
|
|
@ -61,9 +61,9 @@ class ErrorBoundary extends React.Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { hasError } = this.state;
|
const { hasError } = this.state;
|
||||||
const { sentryEventId, desktopErrorReported } = this.state;
|
const { desktopErrorReported } = this.state;
|
||||||
|
|
||||||
const errorWasReported = IS_WEB ? sentryEventId !== null : desktopErrorReported;
|
const errorWasReported = desktopErrorReported;
|
||||||
|
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -82,7 +82,6 @@ function FileReactions(props: Props) {
|
||||||
onClick={() => doReactionLike(uri)}
|
onClick={() => doReactionLike(uri)}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
authSrc={'filereaction_dislike'}
|
authSrc={'filereaction_dislike'}
|
||||||
title={__('I dislike this')}
|
title={__('I dislike this')}
|
||||||
className={classnames('button--file-action', {
|
className={classnames('button--file-action', {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import * as COLLECTIONS_CONSTS from 'constants/collections';
|
import * as COLLECTIONS_CONSTS from 'constants/collections';
|
||||||
import { makeSelectCostInfoForUri } from 'lbryinc';
|
import { makeSelectCostInfoForUri } from 'lbryinc';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import {
|
import {
|
||||||
|
@ -33,7 +32,6 @@ const select = (state, props) => {
|
||||||
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
|
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
|
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
|
||||||
authenticated: selectUserVerifiedEmail(state),
|
|
||||||
collectionId,
|
collectionId,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,6 @@ type Props = {
|
||||||
renderMode: string,
|
renderMode: string,
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
claimWasPurchased: boolean,
|
claimWasPurchased: boolean,
|
||||||
authenticated: boolean,
|
|
||||||
videoTheaterMode: boolean,
|
videoTheaterMode: boolean,
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
};
|
};
|
||||||
|
@ -50,7 +49,6 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
renderMode,
|
renderMode,
|
||||||
costInfo,
|
costInfo,
|
||||||
claimWasPurchased,
|
claimWasPurchased,
|
||||||
authenticated,
|
|
||||||
videoTheaterMode,
|
videoTheaterMode,
|
||||||
collectionId,
|
collectionId,
|
||||||
} = props;
|
} = props;
|
||||||
|
@ -91,10 +89,6 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
}
|
}
|
||||||
}, [claimThumbnail, thumbnail]);
|
}, [claimThumbnail, thumbnail]);
|
||||||
|
|
||||||
function doAuthRedirect() {
|
|
||||||
history.push(`/$/${PAGES.AUTH}?redirect=${encodeURIComponent(location.pathname)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap this in useCallback because we need to use it to the keyboard effect
|
// Wrap this in useCallback because we need to use it to the keyboard effect
|
||||||
// If we don't a new instance will be created for every render and react will think the dependencies have changed, which will add/remove the listener for every render
|
// If we don't a new instance will be created for every render and react will think the dependencies have changed, which will add/remove the listener for every render
|
||||||
const viewFile = useCallback(
|
const viewFile = useCallback(
|
||||||
|
@ -148,14 +142,12 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const showAppNag = IS_WEB && RENDER_MODES.UNSUPPORTED_IN_THIS_APP.includes(renderMode);
|
const disabled = !fileInfo && insufficientCredits && !claimWasPurchased;
|
||||||
const disabled = showAppNag || (!fileInfo && insufficientCredits && !claimWasPurchased);
|
|
||||||
const shouldRedirect = IS_WEB && !authenticated && !isFree;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
onClick={disabled ? undefined : shouldRedirect ? doAuthRedirect : viewFile}
|
onClick={disabled ? undefined : viewFile}
|
||||||
style={thumbnail && !obscurePreview ? { backgroundImage: `url("${thumbnail}")` } : {}}
|
style={thumbnail && !obscurePreview ? { backgroundImage: `url("${thumbnail}")` } : {}}
|
||||||
className={classnames('content__cover', {
|
className={classnames('content__cover', {
|
||||||
'content__cover--disabled': disabled,
|
'content__cover--disabled': disabled,
|
||||||
|
@ -164,16 +156,7 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
'card__media--nsfw': obscurePreview,
|
'card__media--nsfw': obscurePreview,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{showAppNag && (
|
{!claimWasPurchased && insufficientCredits && (
|
||||||
<Nag
|
|
||||||
type="helpful"
|
|
||||||
inline
|
|
||||||
message={__('This content requires LBRY Desktop to display.')}
|
|
||||||
actionText={__('Get the App')}
|
|
||||||
href="https://lbry.com/get"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!claimWasPurchased && insufficientCredits && !showAppNag && (
|
|
||||||
<Nag
|
<Nag
|
||||||
type="helpful"
|
type="helpful"
|
||||||
inline
|
inline
|
||||||
|
@ -184,7 +167,6 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
)}
|
)}
|
||||||
{!disabled && (
|
{!disabled && (
|
||||||
<Button
|
<Button
|
||||||
requiresAuth={shouldRedirect}
|
|
||||||
onClick={viewFile}
|
onClick={viewFile}
|
||||||
iconSize={30}
|
iconSize={30}
|
||||||
title={isPlayable ? __('Play') : __('View')}
|
title={isPlayable ? __('Play') : __('View')}
|
||||||
|
|
|
@ -46,7 +46,6 @@ function FileWatchLaterLink(props: Props) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
title={title}
|
title={title}
|
||||||
label={label}
|
label={label}
|
||||||
className="button--file-action"
|
className="button--file-action"
|
||||||
|
|
|
@ -163,19 +163,6 @@ const Header = (props: Props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginButtons = (
|
|
||||||
<div className="header__auth-buttons">
|
|
||||||
<Button
|
|
||||||
navigate={`/$/${PAGES.AUTH_SIGNIN}`}
|
|
||||||
button="link"
|
|
||||||
label={__('Log In')}
|
|
||||||
className="mobile-hidden"
|
|
||||||
disabled={user === null}
|
|
||||||
/>
|
|
||||||
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} disabled={user === null} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
type BalanceButtonProps = { className: string };
|
type BalanceButtonProps = { className: string };
|
||||||
const BalanceButton = (balanceButtonProps: BalanceButtonProps) => (
|
const BalanceButton = (balanceButtonProps: BalanceButtonProps) => (
|
||||||
<Button
|
<Button
|
||||||
|
@ -220,11 +207,7 @@ const Header = (props: Props) => {
|
||||||
icon={ICONS.ARROW_LEFT}
|
icon={ICONS.ARROW_LEFT}
|
||||||
/>
|
/>
|
||||||
{backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
|
{backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
|
||||||
{authenticated || !IS_WEB ? (
|
<BalanceButton className="header__navigation-item menu__title" />
|
||||||
<BalanceButton className="header__navigation-item menu__title" />
|
|
||||||
) : (
|
|
||||||
loginButtons
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
@ -288,68 +271,61 @@ const Header = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!authHeader && !backout ? (
|
{!authHeader && !backout ? (
|
||||||
<div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
|
<div className={classnames('header__menu', 'header__menu--with-balance')}>
|
||||||
{(!IS_WEB || authenticated) && (
|
<BalanceButton className="header__navigation-item menu__title mobile-hidden" />
|
||||||
<BalanceButton className="header__navigation-item menu__title mobile-hidden" />
|
<Menu>
|
||||||
)}
|
<MenuButton
|
||||||
|
aria-label={__('Your account')}
|
||||||
{IS_WEB && !authenticated && loginButtons}
|
title={__('Your account')}
|
||||||
|
className={classnames('header__navigation-item', {
|
||||||
{(authenticated || !IS_WEB) && (
|
'menu__title header__navigation-item--icon': !activeChannelUrl,
|
||||||
<Menu>
|
'header__navigation-item--profile-pic': activeChannelUrl,
|
||||||
<MenuButton
|
})}
|
||||||
aria-label={__('Your account')}
|
// @if TARGET='app'
|
||||||
title={__('Your account')}
|
onDoubleClick={(e) => {
|
||||||
className={classnames('header__navigation-item', {
|
e.stopPropagation();
|
||||||
'menu__title header__navigation-item--icon': !activeChannelUrl,
|
}}
|
||||||
'header__navigation-item--profile-pic': activeChannelUrl,
|
// @endif
|
||||||
})}
|
>
|
||||||
// @if TARGET='app'
|
{activeChannelUrl ? (
|
||||||
onDoubleClick={(e) => {
|
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
|
||||||
e.stopPropagation();
|
) : (
|
||||||
}}
|
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
|
||||||
// @endif
|
)}
|
||||||
>
|
</MenuButton>
|
||||||
{activeChannelUrl ? (
|
<MenuList className="menu__list--header">
|
||||||
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOADS}`)}>
|
||||||
) : (
|
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||||
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
|
{__('Uploads')}
|
||||||
)}
|
</MenuItem>
|
||||||
</MenuButton>
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNELS}`)}>
|
||||||
<MenuList className="menu__list--header">
|
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOADS}`)}>
|
{__('Channels')}
|
||||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
</MenuItem>
|
||||||
{__('Uploads')}
|
{hasChannels && authenticated && (
|
||||||
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CREATOR_DASHBOARD}`)}>
|
||||||
|
<Icon aria-hidden icon={ICONS.ANALYTICS} />
|
||||||
|
{__('Creator Analytics')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNELS}`)}>
|
)}
|
||||||
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
{authenticated ? (
|
||||||
{__('Channels')}
|
<MenuItem onSelect={openSignOutModal}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.SIGN_OUT} />
|
||||||
|
{__('Sign Out')}
|
||||||
|
</div>
|
||||||
|
<span className="menu__link-help">{email}</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{hasChannels && authenticated && (
|
) : (
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CREATOR_DASHBOARD}`)}>
|
<>
|
||||||
<Icon aria-hidden icon={ICONS.ANALYTICS} />
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.AUTH_SIGNIN}`)}>
|
||||||
{__('Creator Analytics')}
|
<Icon aria-hidden icon={ICONS.SIGN_IN} />
|
||||||
|
{__('Cloud Connect')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
</>
|
||||||
{authenticated ? (
|
)}
|
||||||
<MenuItem onSelect={IS_WEB ? signOut : openSignOutModal}>
|
</MenuList>
|
||||||
<div className="menu__link">
|
</Menu>
|
||||||
<Icon aria-hidden icon={ICONS.SIGN_OUT} />
|
|
||||||
{__('Sign Out')}
|
|
||||||
</div>
|
|
||||||
<span className="menu__link-help">{email}</span>
|
|
||||||
</MenuItem>
|
|
||||||
) : !IS_WEB ? (
|
|
||||||
<>
|
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.AUTH_SIGNIN}`)}>
|
|
||||||
<Icon aria-hidden icon={ICONS.SIGN_IN} />
|
|
||||||
{__('Cloud Connect')}
|
|
||||||
</MenuItem>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</MenuList>
|
|
||||||
</Menu>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
!isVerifyPage &&
|
!isVerifyPage &&
|
||||||
|
@ -390,37 +366,35 @@ type HeaderMenuButtonProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
||||||
const { authenticated, notificationsEnabled, history, handleThemeToggle, currentTheme } = props;
|
const { notificationsEnabled, history, handleThemeToggle, currentTheme } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="header__buttons">
|
<div className="header__buttons">
|
||||||
{(authenticated || !IS_WEB) && (
|
<Menu>
|
||||||
<Menu>
|
<MenuButton
|
||||||
<MenuButton
|
aria-label={__('Publish a file, or create a channel')}
|
||||||
aria-label={__('Publish a file, or create a channel')}
|
title={__('Publish a file, or create a channel')}
|
||||||
title={__('Publish a file, or create a channel')}
|
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
||||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
// @if TARGET='app'
|
||||||
// @if TARGET='app'
|
onDoubleClick={(e) => {
|
||||||
onDoubleClick={(e) => {
|
e.stopPropagation();
|
||||||
e.stopPropagation();
|
}}
|
||||||
}}
|
// @endif
|
||||||
// @endif
|
>
|
||||||
>
|
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
||||||
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
</MenuButton>
|
||||||
</MenuButton>
|
|
||||||
|
|
||||||
<MenuList className="menu__list--header">
|
<MenuList className="menu__list--header">
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOAD}`)}>
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOAD}`)}>
|
||||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||||
{__('Upload')}
|
{__('Upload')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNEL_NEW}`)}>
|
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNEL_NEW}`)}>
|
||||||
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
||||||
{__('New Channel')}
|
{__('New Channel')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
)}
|
|
||||||
|
|
||||||
{notificationsEnabled && <NotificationHeaderButton />}
|
{notificationsEnabled && <NotificationHeaderButton />}
|
||||||
|
|
||||||
|
|
|
@ -102,20 +102,7 @@ type PrivateRouteProps = Props & {
|
||||||
|
|
||||||
function PrivateRoute(props: PrivateRouteProps) {
|
function PrivateRoute(props: PrivateRouteProps) {
|
||||||
const { component: Component, isAuthenticated, ...rest } = props;
|
const { component: Component, isAuthenticated, ...rest } = props;
|
||||||
const urlSearchParams = new URLSearchParams(props.location.search);
|
return <Route {...rest} render={(props) => <Component {...props} />} />;
|
||||||
const redirectUrl = urlSearchParams.get('redirect');
|
|
||||||
return (
|
|
||||||
<Route
|
|
||||||
{...rest}
|
|
||||||
render={(props) =>
|
|
||||||
isAuthenticated || !IS_WEB ? (
|
|
||||||
<Component {...props} />
|
|
||||||
) : (
|
|
||||||
<Redirect to={`/$/${PAGES.AUTH}?redirect=${redirectUrl || props.location.pathname}`} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function AppRouter(props: Props) {
|
function AppRouter(props: Props) {
|
||||||
|
@ -262,7 +249,7 @@ function AppRouter(props: Props) {
|
||||||
{...props}
|
{...props}
|
||||||
exact
|
exact
|
||||||
path={`/$/${PAGES.CHANNELS_FOLLOWING}`}
|
path={`/$/${PAGES.CHANNELS_FOLLOWING}`}
|
||||||
component={isAuthenticated || !IS_WEB ? ChannelsFollowingPage : DiscoverPage}
|
component={isAuthenticated ? ChannelsFollowingPage : DiscoverPage}
|
||||||
/>
|
/>
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_NOTIFICATIONS}`} component={SettingsNotificationsPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_NOTIFICATIONS}`} component={SettingsNotificationsPage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_UPDATE_PWD}`} component={UpdatePasswordPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_UPDATE_PWD}`} component={UpdatePasswordPage} />
|
||||||
|
|
|
@ -25,14 +25,12 @@ export default function SettingAccount(props: Props) {
|
||||||
|
|
||||||
// Determine if password is stored.
|
// Determine if password is stored.
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isAuthenticated || !IS_WEB) {
|
doWalletStatus();
|
||||||
doWalletStatus();
|
getPasswordFromCookie().then((p) => {
|
||||||
getPasswordFromCookie().then((p) => {
|
if (typeof p === 'string') {
|
||||||
if (typeof p === 'string') {
|
setStoredPassword(true);
|
||||||
setStoredPassword(true);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,13 +2,11 @@ import { connect } from 'react-redux';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import { selectLanguage, makeSelectClientSetting } from 'redux/selectors/settings';
|
import { selectLanguage, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
|
||||||
import SettingAppearance from './view';
|
import SettingAppearance from './view';
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
|
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
|
||||||
searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state),
|
searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state),
|
||||||
isAuthenticated: selectUserVerifiedEmail(state),
|
|
||||||
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
||||||
language: selectLanguage(state),
|
language: selectLanguage(state),
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,14 +14,13 @@ import homepages from 'homepages';
|
||||||
type Props = {
|
type Props = {
|
||||||
clock24h: boolean,
|
clock24h: boolean,
|
||||||
searchInLanguage: boolean,
|
searchInLanguage: boolean,
|
||||||
isAuthenticated: boolean,
|
|
||||||
hideBalance: boolean,
|
hideBalance: boolean,
|
||||||
setClientSetting: (string, boolean | string | number) => void,
|
setClientSetting: (string, boolean | string | number) => void,
|
||||||
setSearchInLanguage: (boolean) => void,
|
setSearchInLanguage: (boolean) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function SettingAppearance(props: Props) {
|
export default function SettingAppearance(props: Props) {
|
||||||
const { clock24h, searchInLanguage, isAuthenticated, hideBalance, setClientSetting, setSearchInLanguage } = props;
|
const { clock24h, searchInLanguage, hideBalance, setClientSetting, setSearchInLanguage } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -64,17 +63,14 @@ export default function SettingAppearance(props: Props) {
|
||||||
checked={clock24h}
|
checked={clock24h}
|
||||||
/>
|
/>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
|
<SettingsRow title={__('Hide wallet balance in header')}>
|
||||||
{(isAuthenticated || !IS_WEB) && (
|
<FormField
|
||||||
<SettingsRow title={__('Hide wallet balance in header')}>
|
type="checkbox"
|
||||||
<FormField
|
name="hide_balance"
|
||||||
type="checkbox"
|
onChange={() => setClientSetting(SETTINGS.HIDE_BALANCE, !hideBalance)}
|
||||||
name="hide_balance"
|
checked={hideBalance}
|
||||||
onChange={() => setClientSetting(SETTINGS.HIDE_BALANCE, !hideBalance)}
|
/>
|
||||||
checked={hideBalance}
|
</SettingsRow>
|
||||||
/>
|
|
||||||
</SettingsRow>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectMyChannelUrls } from 'redux/selectors/claims';
|
import { selectMyChannelUrls } from 'redux/selectors/claims';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import { selectShowMatureContent, selectLanguage, makeSelectClientSetting } from 'redux/selectors/settings';
|
import { selectShowMatureContent, selectLanguage, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
@ -26,7 +25,6 @@ const select = (state) => ({
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||||
openModal: (id, params) => dispatch(doOpenModal(id, params)),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(SettingContent);
|
export default connect(select, perform)(SettingContent);
|
||||||
|
|
|
@ -4,7 +4,6 @@ import * as PAGES from 'constants/pages';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import * as MODALS from 'constants/modal_types';
|
|
||||||
import { SETTINGS_GRP } from 'constants/settings';
|
import { SETTINGS_GRP } from 'constants/settings';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
|
@ -32,7 +31,6 @@ type Props = {
|
||||||
// --- perform ---
|
// --- perform ---
|
||||||
setClientSetting: (string, boolean | string | number) => void,
|
setClientSetting: (string, boolean | string | number) => void,
|
||||||
clearPlayingUri: () => void,
|
clearPlayingUri: () => void,
|
||||||
openModal: (string) => void,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function SettingContent(props: Props) {
|
export default function SettingContent(props: Props) {
|
||||||
|
@ -49,7 +47,6 @@ export default function SettingContent(props: Props) {
|
||||||
enablePublishPreview,
|
enablePublishPreview,
|
||||||
setClientSetting,
|
setClientSetting,
|
||||||
clearPlayingUri,
|
clearPlayingUri,
|
||||||
openModal,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -109,47 +106,37 @@ export default function SettingContent(props: Props) {
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="show_nsfw"
|
name="show_nsfw"
|
||||||
checked={showNsfw}
|
checked={showNsfw}
|
||||||
onChange={() =>
|
onChange={() => setClientSetting(SETTINGS.SHOW_MATURE, !showNsfw)}
|
||||||
!IS_WEB || showNsfw
|
/>
|
||||||
? setClientSetting(SETTINGS.SHOW_MATURE, !showNsfw)
|
</SettingsRow>
|
||||||
: openModal(MODALS.CONFIRM_AGE)
|
<SettingsRow title={__('Notifications')}>
|
||||||
}
|
<Button
|
||||||
|
button="inverse"
|
||||||
|
label={__('Manage')}
|
||||||
|
icon={ICONS.ARROW_RIGHT}
|
||||||
|
navigate={`/$/${PAGES.SETTINGS_NOTIFICATIONS}`}
|
||||||
/>
|
/>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
|
|
||||||
{(isAuthenticated || !IS_WEB) && (
|
<SettingsRow title={__('Blocked and muted channels')}>
|
||||||
<>
|
<Button
|
||||||
<SettingsRow title={__('Notifications')}>
|
button="inverse"
|
||||||
<Button
|
label={__('Manage')}
|
||||||
button="inverse"
|
icon={ICONS.ARROW_RIGHT}
|
||||||
label={__('Manage')}
|
navigate={`/$/${PAGES.SETTINGS_BLOCKED_MUTED}`}
|
||||||
icon={ICONS.ARROW_RIGHT}
|
/>
|
||||||
navigate={`/$/${PAGES.SETTINGS_NOTIFICATIONS}`}
|
</SettingsRow>
|
||||||
/>
|
|
||||||
</SettingsRow>
|
|
||||||
|
|
||||||
<SettingsRow title={__('Blocked and muted channels')}>
|
{myChannelUrls && myChannelUrls.length > 0 && (
|
||||||
<Button
|
<SettingsRow title={__('Creator settings')}>
|
||||||
button="inverse"
|
<Button
|
||||||
label={__('Manage')}
|
button="inverse"
|
||||||
icon={ICONS.ARROW_RIGHT}
|
label={__('Manage')}
|
||||||
navigate={`/$/${PAGES.SETTINGS_BLOCKED_MUTED}`}
|
icon={ICONS.ARROW_RIGHT}
|
||||||
/>
|
navigate={`/$/${PAGES.SETTINGS_CREATOR}`}
|
||||||
</SettingsRow>
|
/>
|
||||||
|
</SettingsRow>
|
||||||
{myChannelUrls && myChannelUrls.length > 0 && (
|
|
||||||
<SettingsRow title={__('Creator settings')}>
|
|
||||||
<Button
|
|
||||||
button="inverse"
|
|
||||||
label={__('Manage')}
|
|
||||||
icon={ICONS.ARROW_RIGHT}
|
|
||||||
navigate={`/$/${PAGES.SETTINGS_CREATOR}`}
|
|
||||||
/>
|
|
||||||
</SettingsRow>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SettingsRow title={__('Publish confirmation')} subtitle={__(HELP.PUBLISH_PREVIEW)}>
|
<SettingsRow title={__('Publish confirmation')} subtitle={__(HELP.PUBLISH_PREVIEW)}>
|
||||||
<FormField
|
<FormField
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -159,13 +146,9 @@ export default function SettingContent(props: Props) {
|
||||||
onChange={() => setClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW, !enablePublishPreview)}
|
onChange={() => setClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW, !enablePublishPreview)}
|
||||||
/>
|
/>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
|
|
||||||
{/* @if TARGET='app' */}
|
|
||||||
<SettingsRow title={__('Max purchase price')} subtitle={__(HELP.MAX_PURCHASE_PRICE)} multirow>
|
<SettingsRow title={__('Max purchase price')} subtitle={__(HELP.MAX_PURCHASE_PRICE)} multirow>
|
||||||
<MaxPurchasePrice />
|
<MaxPurchasePrice />
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
{/* @endif */}
|
|
||||||
|
|
||||||
<SettingsRow title={__('Purchase and tip confirmations')} multirow>
|
<SettingsRow title={__('Purchase and tip confirmations')} multirow>
|
||||||
<FormField
|
<FormField
|
||||||
type="radio"
|
type="radio"
|
||||||
|
|
|
@ -172,14 +172,12 @@ export default function SettingSystem(props: Props) {
|
||||||
|
|
||||||
// Update storedPassword state
|
// Update storedPassword state
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isAuthenticated || !IS_WEB) {
|
updateWalletStatus();
|
||||||
updateWalletStatus();
|
getPasswordFromCookie().then((p) => {
|
||||||
getPasswordFromCookie().then((p) => {
|
if (typeof p === 'string') {
|
||||||
if (typeof p === 'string') {
|
setStoredPassword(true);
|
||||||
setStoredPassword(true);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -88,7 +88,7 @@ function SideNavigation(props: Props) {
|
||||||
icon: ICONS.DISCOVER,
|
icon: ICONS.DISCOVER,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: IS_WEB ? 'Purchased' : 'Library',
|
title: 'Library',
|
||||||
link: `/$/${PAGES.LIBRARY}`,
|
link: `/$/${PAGES.LIBRARY}`,
|
||||||
icon: ICONS.PURCHASED,
|
icon: ICONS.PURCHASED,
|
||||||
hideForUnauth: true,
|
hideForUnauth: true,
|
||||||
|
@ -210,7 +210,6 @@ function SideNavigation(props: Props) {
|
||||||
SIDE_LINKS.push(...FULL_LINKS);
|
SIDE_LINKS.push(...FULL_LINKS);
|
||||||
|
|
||||||
const [pulseLibrary, setPulseLibrary] = React.useState(false);
|
const [pulseLibrary, setPulseLibrary] = React.useState(false);
|
||||||
const isPersonalized = !IS_WEB || isAuthenticated;
|
|
||||||
const isAbsolute = isOnFilePage || isMediumScreen;
|
const isAbsolute = isOnFilePage || isMediumScreen;
|
||||||
const microNavigation = !sidebarOpen || isMediumScreen;
|
const microNavigation = !sidebarOpen || isMediumScreen;
|
||||||
const subLinks = email
|
const subLinks = email
|
||||||
|
@ -312,7 +311,7 @@ function SideNavigation(props: Props) {
|
||||||
{SIDE_LINKS.map((linkProps) => {
|
{SIDE_LINKS.map((linkProps) => {
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
const { hideForUnauth, ...passedProps } = linkProps;
|
const { hideForUnauth, ...passedProps } = linkProps;
|
||||||
return !email && linkProps.hideForUnauth && IS_WEB ? null : (
|
return (
|
||||||
<li key={linkProps.route || linkProps.link}>
|
<li key={linkProps.route || linkProps.link}>
|
||||||
<Button
|
<Button
|
||||||
{...passedProps}
|
{...passedProps}
|
||||||
|
@ -333,14 +332,14 @@ function SideNavigation(props: Props) {
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
|
{sidebarOpen && subscriptions && subscriptions.length > 0 && (
|
||||||
<ul className="navigation__secondary navigation-links">
|
<ul className="navigation__secondary navigation-links">
|
||||||
{subscriptions.map((subscription) => (
|
{subscriptions.map((subscription) => (
|
||||||
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
{sidebarOpen && isPersonalized && followedTags && followedTags.length > 0 && (
|
{sidebarOpen && followedTags && followedTags.length > 0 && (
|
||||||
<ul className="navigation__secondary navigation-links navigation-links--small">
|
<ul className="navigation__secondary navigation-links navigation-links--small">
|
||||||
{followedTags.map(({ name }, key) => (
|
{followedTags.map(({ name }, key) => (
|
||||||
<li key={name} className="navigation-link__wrapper">
|
<li key={name} className="navigation-link__wrapper">
|
||||||
|
@ -371,7 +370,7 @@ function SideNavigation(props: Props) {
|
||||||
{SIDE_LINKS.map((linkProps) => {
|
{SIDE_LINKS.map((linkProps) => {
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
const { hideForUnauth, link, route, ...passedProps } = linkProps;
|
const { hideForUnauth, link, route, ...passedProps } = linkProps;
|
||||||
return !email && linkProps.hideForUnauth && IS_WEB ? null : (
|
return (
|
||||||
<li key={route || link}>
|
<li key={route || link}>
|
||||||
<Button
|
<Button
|
||||||
{...passedProps}
|
{...passedProps}
|
||||||
|
@ -394,7 +393,7 @@ function SideNavigation(props: Props) {
|
||||||
{subLinks.map((linkProps) => {
|
{subLinks.map((linkProps) => {
|
||||||
const { hideForUnauth, ...passedProps } = linkProps;
|
const { hideForUnauth, ...passedProps } = linkProps;
|
||||||
|
|
||||||
return !email && hideForUnauth && IS_WEB ? null : (
|
return (
|
||||||
<li key={linkProps.title} className="mobile-only">
|
<li key={linkProps.title} className="mobile-only">
|
||||||
<Button
|
<Button
|
||||||
{...passedProps}
|
{...passedProps}
|
||||||
|
@ -409,14 +408,14 @@ function SideNavigation(props: Props) {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
|
{sidebarOpen && subscriptions && subscriptions.length > 0 && (
|
||||||
<ul className="navigation__secondary navigation-links">
|
<ul className="navigation__secondary navigation-links">
|
||||||
{subscriptions.map((subscription) => (
|
{subscriptions.map((subscription) => (
|
||||||
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
{sidebarOpen && isPersonalized && followedTags && followedTags.length > 0 && (
|
{sidebarOpen && followedTags && followedTags.length > 0 && (
|
||||||
<ul className="navigation__secondary navigation-links navigation-links--small">
|
<ul className="navigation__secondary navigation-links navigation-links--small">
|
||||||
{followedTags.map(({ name }, key) => (
|
{followedTags.map(({ name }, key) => (
|
||||||
<li key={name} className="navigation-link__wrapper">
|
<li key={name} className="navigation-link__wrapper">
|
||||||
|
|
|
@ -76,7 +76,6 @@ export default function SubscribeButton(props: Props) {
|
||||||
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
|
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
|
||||||
icon={ICONS.UNSUBSCRIBE}
|
icon={ICONS.UNSUBSCRIBE}
|
||||||
button={'alt'}
|
button={'alt'}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
label={label}
|
label={label}
|
||||||
title={titlePrefix}
|
title={titlePrefix}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
@ -104,7 +103,6 @@ export default function SubscribeButton(props: Props) {
|
||||||
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
|
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
|
||||||
icon={unfollowOverride ? ICONS.UNSUBSCRIBE : isSubscribed ? ICONS.SUBSCRIBED : ICONS.SUBSCRIBE}
|
icon={unfollowOverride ? ICONS.UNSUBSCRIBE : isSubscribed ? ICONS.SUBSCRIBED : ICONS.SUBSCRIBE}
|
||||||
button={'alt'}
|
button={'alt'}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
label={label}
|
label={label}
|
||||||
title={titlePrefix}
|
title={titlePrefix}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ type Props = {
|
||||||
class PdfViewer extends React.PureComponent<Props> {
|
class PdfViewer extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { source } = this.props;
|
const { source } = this.props;
|
||||||
const src = IS_WEB ? source : `file://${source}`;
|
const src = `file://${source}`;
|
||||||
return (
|
return (
|
||||||
<div className="file-viewer file-viewer--document" onContextMenu={stopContextMenu}>
|
<div className="file-viewer file-viewer--document" onContextMenu={stopContextMenu}>
|
||||||
<div className="file-viewer file-viewer--iframe">
|
<div className="file-viewer file-viewer--iframe">
|
||||||
|
|
|
@ -59,7 +59,7 @@ const select = (state, props) => {
|
||||||
thumbnail: makeSelectThumbnailForUri(uri)(state),
|
thumbnail: makeSelectThumbnailForUri(uri)(state),
|
||||||
claim: makeSelectClaimForUri(uri)(state),
|
claim: makeSelectClaimForUri(uri)(state),
|
||||||
homepageData: selectHomepageData(state),
|
homepageData: selectHomepageData(state),
|
||||||
shareTelemetry: IS_WEB || selectDaemonSettings(state).share_usage_data,
|
shareTelemetry: selectDaemonSettings(state).share_usage_data,
|
||||||
isFloating: makeSelectIsPlayerFloating(props.location)(state),
|
isFloating: makeSelectIsPlayerFloating(props.location)(state),
|
||||||
videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state),
|
videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state),
|
||||||
};
|
};
|
||||||
|
|
|
@ -280,9 +280,7 @@ function VideoViewer(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const playerReadyDependencyList = [uri];
|
const playerReadyDependencyList = [uri];
|
||||||
if (!IS_WEB) {
|
playerReadyDependencyList.push(desktopPlayStartTime);
|
||||||
playerReadyDependencyList.push(desktopPlayStartTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
const doPlayNext = () => {
|
const doPlayNext = () => {
|
||||||
setPlayNextUrl(true);
|
setPlayNextUrl(true);
|
||||||
|
|
|
@ -60,19 +60,16 @@ class WalletAddress extends React.PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
{!IS_WEB && (
|
<Button
|
||||||
<Button
|
button="secondary"
|
||||||
button="secondary"
|
label={__('Get New Address')}
|
||||||
label={__('Get New Address')}
|
onClick={getNewAddress}
|
||||||
onClick={getNewAddress}
|
disabled={gettingNewAddress}
|
||||||
disabled={gettingNewAddress}
|
/>
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Button button="link" label={showQR ? __('Hide QR code') : __('Show QR code')} onClick={this.toggleQR} />
|
<Button button="link" label={showQR ? __('Hide QR code') : __('Show QR code')} onClick={this.toggleQR} />
|
||||||
</div>
|
</div>
|
||||||
<p className="help">
|
<p className="help">
|
||||||
{!IS_WEB &&
|
{__('You can generate a new address at any time, and any previous addresses will continue to work.')}
|
||||||
__('You can generate a new address at any time, and any previous addresses will continue to work.')}
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{showQR && <QRCode value={receiveAddress} paddingTop />}
|
{showQR && <QRCode value={receiveAddress} paddingTop />}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export const CAD = 'cad';
|
||||||
export const COMIC = 'comic';
|
export const COMIC = 'comic';
|
||||||
|
|
||||||
// These types can only be render if download completed
|
// These types can only be render if download completed
|
||||||
export const NON_STREAM_MODES = IS_WEB ? [CAD, COMIC] : [CAD, COMIC, ...TEXT_MODES];
|
export const NON_STREAM_MODES = [CAD, COMIC, ...TEXT_MODES];
|
||||||
|
|
||||||
export const AUTO_RENDER_MODES = [IMAGE].concat(TEXT_MODES);
|
export const AUTO_RENDER_MODES = [IMAGE].concat(TEXT_MODES);
|
||||||
export const WEB_SHAREABLE_MODES = AUTO_RENDER_MODES.concat(FLOATING_MODES);
|
export const WEB_SHAREABLE_MODES = AUTO_RENDER_MODES.concat(FLOATING_MODES);
|
||||||
|
@ -26,7 +26,7 @@ export const DOWNLOAD = 'download';
|
||||||
export const APPLICATION = 'application';
|
export const APPLICATION = 'application';
|
||||||
export const UNSUPPORTED = 'unsupported';
|
export const UNSUPPORTED = 'unsupported';
|
||||||
|
|
||||||
export const UNSUPPORTED_IN_THIS_APP = IS_WEB ? [CAD, COMIC, APPLICATION] : [APPLICATION];
|
export const UNSUPPORTED_IN_THIS_APP = [APPLICATION];
|
||||||
|
|
||||||
export const UNRENDERABLE_MODES = Array.from(
|
export const UNRENDERABLE_MODES = Array.from(
|
||||||
new Set(UNSUPPORTED_IN_THIS_APP.concat([DOWNLOAD, APPLICATION, UNSUPPORTED]))
|
new Set(UNSUPPORTED_IN_THIS_APP.concat([DOWNLOAD, APPLICATION, UNSUPPORTED]))
|
||||||
|
|
|
@ -185,7 +185,7 @@ document.addEventListener('drop', (event) => {
|
||||||
|
|
||||||
function AppWrapper() {
|
function AppWrapper() {
|
||||||
// Splash screen and sdk setup not needed on web
|
// Splash screen and sdk setup not needed on web
|
||||||
const [readyToLaunch, setReadyToLaunch] = useState(IS_WEB);
|
const [readyToLaunch, setReadyToLaunch] = useState(false);
|
||||||
const [persistDone, setPersistDone] = useState(false);
|
const [persistDone, setPersistDone] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ModalPublishSuccess extends React.PureComponent<Props> {
|
||||||
<div className="card--inline">
|
<div className="card--inline">
|
||||||
<ClaimPreview type="small" uri={uri} />
|
<ClaimPreview type="small" uri={uri} />
|
||||||
</div>
|
</div>
|
||||||
{filePath && !IS_WEB && (
|
{filePath && (
|
||||||
<p className="help">
|
<p className="help">
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{__(
|
{__(
|
||||||
|
|
|
@ -87,7 +87,7 @@ function DiscoverPage(props: Props) {
|
||||||
icon={ICONS.SUBSCRIBE}
|
icon={ICONS.SUBSCRIBE}
|
||||||
iconColor="red"
|
iconColor="red"
|
||||||
onClick={handleFollowClick}
|
onClick={handleFollowClick}
|
||||||
requiresAuth={IS_WEB}
|
requiresAuth={false}
|
||||||
label={label}
|
label={label}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ import Icon from 'component/common/icon';
|
||||||
import { FormField } from 'component/common/form-components/form-field';
|
import { FormField } from 'component/common/form-components/form-field';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import Yrbl from 'component/yrbl';
|
|
||||||
import { PURCHASES_PAGE_SIZE } from 'page/library/view';
|
import { PURCHASES_PAGE_SIZE } from 'page/library/view';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
|
|
||||||
|
@ -91,44 +90,28 @@ function FileListDownloaded(props: Props) {
|
||||||
/>
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
{IS_WEB && viewMode === VIEW_DOWNLOADS ? (
|
<div>
|
||||||
<div className="main--empty">
|
<ClaimList
|
||||||
<Yrbl
|
renderProperties={() => null}
|
||||||
title={__('Try out the app!')}
|
empty={
|
||||||
subtitle={
|
viewMode === VIEW_PURCHASES && !query ? (
|
||||||
<p className="section__subtitle">{__("Download the app to track files you've viewed and downloaded.")}</p>
|
<div>{__('No purchases found.')}</div>
|
||||||
}
|
) : (
|
||||||
actions={
|
__('No results for %query%', { query })
|
||||||
<div className="section__actions">
|
)
|
||||||
<Button button="primary" label={__('Get The App')} href="https://lbry.com/get" />
|
}
|
||||||
</div>
|
uris={viewMode === VIEW_PURCHASES ? myPurchases : myDownloads}
|
||||||
}
|
loading={loading}
|
||||||
|
/>
|
||||||
|
{!query && (
|
||||||
|
<Paginate
|
||||||
|
totalPages={Math.ceil(
|
||||||
|
Number(viewMode === VIEW_PURCHASES ? myPurchasesCount : downloadedUrlsCount) /
|
||||||
|
Number(viewMode === VIEW_PURCHASES ? PURCHASES_PAGE_SIZE : PAGE_SIZE)
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
)}
|
||||||
) : (
|
</div>
|
||||||
<div>
|
|
||||||
<ClaimList
|
|
||||||
renderProperties={() => null}
|
|
||||||
empty={
|
|
||||||
viewMode === VIEW_PURCHASES && !query ? (
|
|
||||||
<div>{__('No purchases found.')}</div>
|
|
||||||
) : (
|
|
||||||
__('No results for %query%', { query })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
uris={viewMode === VIEW_PURCHASES ? myPurchases : myDownloads}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
{!query && (
|
|
||||||
<Paginate
|
|
||||||
totalPages={Math.ceil(
|
|
||||||
Number(viewMode === VIEW_PURCHASES ? myPurchasesCount : downloadedUrlsCount) /
|
|
||||||
Number(viewMode === VIEW_PURCHASES ? PURCHASES_PAGE_SIZE : PAGE_SIZE)
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ type Props = {
|
||||||
|
|
||||||
function HomePage(props: Props) {
|
function HomePage(props: Props) {
|
||||||
const { followedTags, subscribedChannels, authenticated, showNsfw, homepageData } = props;
|
const { followedTags, subscribedChannels, authenticated, showNsfw, homepageData } = props;
|
||||||
const showPersonalizedChannels = (authenticated || !IS_WEB) && subscribedChannels && subscribedChannels.length > 0;
|
const showPersonalizedChannels = subscribedChannels && subscribedChannels.length > 0;
|
||||||
const showPersonalizedTags = (authenticated || !IS_WEB) && followedTags && followedTags.length > 0;
|
const showPersonalizedTags = followedTags && followedTags.length > 0;
|
||||||
const showIndividualTags = showPersonalizedTags && followedTags.length < 5;
|
const showIndividualTags = showPersonalizedTags && followedTags.length < 5;
|
||||||
|
|
||||||
const rowData: Array<RowDataItem> = GetLinksData(
|
const rowData: Array<RowDataItem> = GetLinksData(
|
||||||
|
@ -84,7 +84,7 @@ function HomePage(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page fullWidthPage>
|
<Page fullWidthPage>
|
||||||
{(authenticated || !IS_WEB) && !subscribedChannels.length && (
|
{!subscribedChannels.length && (
|
||||||
<div className="notice-message">
|
<div className="notice-message">
|
||||||
<h1 className="section__title">
|
<h1 className="section__title">
|
||||||
{__("%SITE_NAME% is more fun if you're following channels", { SITE_NAME })}
|
{__("%SITE_NAME% is more fun if you're following channels", { SITE_NAME })}
|
||||||
|
|
|
@ -41,9 +41,7 @@ function LibraryPage(props: Props) {
|
||||||
{!loading && !hasDownloads && (
|
{!loading && !hasDownloads && (
|
||||||
<div className="main--empty">
|
<div className="main--empty">
|
||||||
<Yrbl
|
<Yrbl
|
||||||
title={
|
title={__("You haven't downloaded anything from LBRY yet")}
|
||||||
IS_WEB ? __("You haven't purchased anything yet") : __("You haven't downloaded anything from LBRY yet")
|
|
||||||
}
|
|
||||||
actions={
|
actions={
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
<Button button="primary" navigate="/" label={__('Explore New Content')} />
|
<Button button="primary" navigate="/" label={__('Explore New Content')} />
|
||||||
|
|
|
@ -44,7 +44,7 @@ class RewardsPage extends PureComponent<Props> {
|
||||||
|
|
||||||
renderPageHeader() {
|
renderPageHeader() {
|
||||||
const { user, daemonSettings, fetchUser } = this.props;
|
const { user, daemonSettings, fetchUser } = this.props;
|
||||||
const rewardsEnabled = IS_WEB || (daemonSettings && daemonSettings.share_usage_data);
|
const rewardsEnabled = daemonSettings && daemonSettings.share_usage_data;
|
||||||
|
|
||||||
if (user && !user.is_reward_approved && rewardsEnabled) {
|
if (user && !user.is_reward_approved && rewardsEnabled) {
|
||||||
if (!user.primary_email || !user.has_verified_email || !user.is_identity_verified) {
|
if (!user.primary_email || !user.has_verified_email || !user.is_identity_verified) {
|
||||||
|
@ -120,7 +120,7 @@ class RewardsPage extends PureComponent<Props> {
|
||||||
renderUnclaimedRewards() {
|
renderUnclaimedRewards() {
|
||||||
const { fetching, rewards, user, daemonSettings, claimed } = this.props;
|
const { fetching, rewards, user, daemonSettings, claimed } = this.props;
|
||||||
|
|
||||||
if (!IS_WEB && daemonSettings && !daemonSettings.share_usage_data) {
|
if (daemonSettings && !daemonSettings.share_usage_data) {
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
<section className="card card--section">
|
||||||
<h2 className="card__title card__title--deprecated">{__('Rewards Disabled')}</h2>
|
<h2 className="card__title card__title--deprecated">{__('Rewards Disabled')}</h2>
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as PAGES from 'constants/pages';
|
|
||||||
import * as ICONS from 'constants/icons';
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classnames from 'classnames';
|
|
||||||
import Button from 'component/button';
|
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import SettingAccount from 'component/settingAccount';
|
import SettingAccount from 'component/settingAccount';
|
||||||
import SettingAppearance from 'component/settingAppearance';
|
import SettingAppearance from 'component/settingAppearance';
|
||||||
import SettingContent from 'component/settingContent';
|
import SettingContent from 'component/settingContent';
|
||||||
import SettingSystem from 'component/settingSystem';
|
import SettingSystem from 'component/settingSystem';
|
||||||
import SettingUnauthenticated from 'component/settingUnauthenticated';
|
|
||||||
import Yrbl from 'component/yrbl';
|
|
||||||
|
|
||||||
type DaemonSettings = {
|
type DaemonSettings = {
|
||||||
download_dir: string,
|
download_dir: string,
|
||||||
|
@ -36,7 +30,7 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { daemonSettings, isAuthenticated } = this.props;
|
const { daemonSettings } = this.props;
|
||||||
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -47,30 +41,12 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
backout={{ title: __('Settings'), backLabel: __('Back') }}
|
backout={{ title: __('Settings'), backLabel: __('Back') }}
|
||||||
className="card-stack"
|
className="card-stack"
|
||||||
>
|
>
|
||||||
{!isAuthenticated && IS_WEB && (
|
{noDaemonSettings ? (
|
||||||
<>
|
|
||||||
<SettingUnauthenticated />
|
|
||||||
<div className="main--empty">
|
|
||||||
<Yrbl
|
|
||||||
type="happy"
|
|
||||||
title={__('Sign up for full control')}
|
|
||||||
subtitle={__('Unlock new buttons that change things.')}
|
|
||||||
actions={
|
|
||||||
<div className="section__actions">
|
|
||||||
<Button button="primary" icon={ICONS.SIGN_UP} label={__('Sign Up')} navigate={`/$/${PAGES.AUTH}`} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!IS_WEB && noDaemonSettings ? (
|
|
||||||
<section className="card card--section">
|
<section className="card card--section">
|
||||||
<div className="card__title card__title--deprecated">{__('Failed to load settings.')}</div>
|
<div className="card__title card__title--deprecated">{__('Failed to load settings.')}</div>
|
||||||
</section>
|
</section>
|
||||||
) : (
|
) : (
|
||||||
<div className={classnames('card-stack', { 'card--disabled': IS_WEB && !isAuthenticated })}>
|
<div className={'card-stack'}>
|
||||||
<SettingAppearance />
|
<SettingAppearance />
|
||||||
<SettingAccount />
|
<SettingAccount />
|
||||||
<SettingContent />
|
<SettingContent />
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
@ -10,7 +9,6 @@ import Card from 'component/common/card';
|
||||||
import SettingsRow from 'component/settingsRow';
|
import SettingsRow from 'component/settingsRow';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { Redirect } from 'react-router-dom';
|
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
|
||||||
|
@ -92,10 +90,6 @@ export default function NotificationSettingsPage(props: Props) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_WEB && !isAuthenticated && !verificationToken) {
|
|
||||||
return <Redirect to={`/$/${PAGES.AUTH_SIGNIN}?redirect=${location.pathname}`} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page
|
<Page
|
||||||
noFooter
|
noFooter
|
||||||
|
|
|
@ -32,7 +32,6 @@ function TagsFollowingPage(props: Props) {
|
||||||
button="secondary"
|
button="secondary"
|
||||||
icon={ICONS.EDIT}
|
icon={ICONS.EDIT}
|
||||||
label={__('Manage')}
|
label={__('Manage')}
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
navigate={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`}
|
navigate={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,9 +112,9 @@ export default function YoutubeSync(props: Props) {
|
||||||
<YoutubeTransferStatus alwaysShow addNewChannel={handleNewChannel} />
|
<YoutubeTransferStatus alwaysShow addNewChannel={handleNewChannel} />
|
||||||
) : (
|
) : (
|
||||||
<Card
|
<Card
|
||||||
title={__('Sync your YouTube channel to %site_name%', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })}
|
title={__('Sync your YouTube channel to %site_name%', { site_name: 'LBRY' })}
|
||||||
subtitle={__('Get your YouTube videos in front of the %site_name% audience.', {
|
subtitle={__('Get your YouTube videos in front of the %site_name% audience.', {
|
||||||
site_name: IS_WEB ? SITE_NAME : 'LBRY',
|
site_name: 'LBRY',
|
||||||
})}
|
})}
|
||||||
actions={
|
actions={
|
||||||
<Form onSubmit={handleCreateChannel}>
|
<Form onSubmit={handleCreateChannel}>
|
||||||
|
@ -124,7 +124,7 @@ export default function YoutubeSync(props: Props) {
|
||||||
{nameError ? (
|
{nameError ? (
|
||||||
<span className="error__text">{nameError}</span>
|
<span className="error__text">{nameError}</span>
|
||||||
) : (
|
) : (
|
||||||
__('Your %site_name% channel name', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })
|
__('Your %site_name% channel name', { site_name: 'LBRY' })
|
||||||
)}
|
)}
|
||||||
</label>
|
</label>
|
||||||
<div className="form-field__prefix">@</div>
|
<div className="form-field__prefix">@</div>
|
||||||
|
|
|
@ -38,7 +38,7 @@ import {
|
||||||
selectAllowAnalytics,
|
selectAllowAnalytics,
|
||||||
} from 'redux/selectors/app';
|
} from 'redux/selectors/app';
|
||||||
import { selectDaemonSettings, makeSelectClientSetting } from 'redux/selectors/settings';
|
import { selectDaemonSettings, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUser } from 'redux/selectors/user';
|
||||||
import { doSyncLoop, doSetPrefsReady, doPreferenceGet, doPopulateSharedUserState } from 'redux/actions/sync';
|
import { doSyncLoop, doSetPrefsReady, doPreferenceGet, doPopulateSharedUserState } 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';
|
||||||
|
@ -294,16 +294,10 @@ export function doAlertError(errorList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doAlertWaitingForSync() {
|
export function doAlertWaitingForSync() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch) => {
|
||||||
const state = getState();
|
|
||||||
const authenticated = selectUserVerifiedEmail(state);
|
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
doToast({
|
doToast({
|
||||||
message:
|
message: __('Please wait a bit, we are still getting your account ready.'),
|
||||||
!authenticated && IS_WEB
|
|
||||||
? __('Sign in or create an account to change this setting.')
|
|
||||||
: __('Please wait a bit, we are still getting your account ready.'),
|
|
||||||
isError: false,
|
isError: false,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -315,7 +309,7 @@ export function doDaemonReady() {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
// TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store
|
// TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store
|
||||||
const shareUsageData = IS_WEB || window.localStorage.getItem(SHARE_INTERNAL) === 'true';
|
const shareUsageData = window.localStorage.getItem(SHARE_INTERNAL) === 'true';
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
doAuthenticate(
|
doAuthenticate(
|
||||||
|
|
|
@ -164,14 +164,14 @@ export function doPlayUri(
|
||||||
const alreadyDownloaded = fileInfo && (fileInfo.completed || (fileInfo.blobs_remaining === 0 && uriIsStreamable));
|
const alreadyDownloaded = fileInfo && (fileInfo.completed || (fileInfo.blobs_remaining === 0 && uriIsStreamable));
|
||||||
const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
|
const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
|
||||||
|
|
||||||
if (!IS_WEB && (alreadyDownloading || alreadyDownloaded)) {
|
if (alreadyDownloading || alreadyDownloaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const daemonSettings = selectDaemonSettings(state);
|
const daemonSettings = selectDaemonSettings(state);
|
||||||
const costInfo = makeSelectCostInfoForUri(uri)(state);
|
const costInfo = makeSelectCostInfoForUri(uri)(state);
|
||||||
const cost = (costInfo && Number(costInfo.cost)) || 0;
|
const cost = (costInfo && Number(costInfo.cost)) || 0;
|
||||||
const saveFile = !IS_WEB && (!uriIsStreamable ? true : daemonSettings.save_files || saveFileOverride || cost > 0);
|
const saveFile = !uriIsStreamable ? true : daemonSettings.save_files || saveFileOverride || cost > 0;
|
||||||
const instantPurchaseEnabled = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state);
|
const instantPurchaseEnabled = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state);
|
||||||
const instantPurchaseMax = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_MAX)(state);
|
const instantPurchaseMax = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_MAX)(state);
|
||||||
|
|
||||||
|
|
|
@ -255,9 +255,7 @@ export function doEnterSettingsPage() {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
||||||
const hasVerifiedEmail = state.user && state.user.user && state.user.user.has_verified_email;
|
const hasVerifiedEmail = state.user && state.user.user && state.user.user.has_verified_email;
|
||||||
if (IS_WEB && !hasVerifiedEmail) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dispatch(doSyncUnsubscribe());
|
dispatch(doSyncUnsubscribe());
|
||||||
if (syncEnabled && hasVerifiedEmail) {
|
if (syncEnabled && hasVerifiedEmail) {
|
||||||
await dispatch(doSyncLoop(true));
|
await dispatch(doSyncLoop(true));
|
||||||
|
@ -269,12 +267,7 @@ export function doEnterSettingsPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doExitSettingsPage() {
|
export function doExitSettingsPage() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch) => {
|
||||||
const state = getState();
|
|
||||||
const hasVerifiedEmail = state.user && state.user.user && state.user.user.has_verified_email;
|
|
||||||
if (IS_WEB && !hasVerifiedEmail) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dispatch(doSetSyncLock(false));
|
dispatch(doSetSyncLock(false));
|
||||||
dispatch(doPushSettingsToPrefs());
|
dispatch(doPushSettingsToPrefs());
|
||||||
// syncLoop is restarted in store.js sharedStateCB if necessary
|
// syncLoop is restarted in store.js sharedStateCB if necessary
|
||||||
|
@ -324,7 +317,7 @@ export function doSetLanguage(language) {
|
||||||
const { settings } = getState();
|
const { settings } = getState();
|
||||||
const { daemonSettings } = settings;
|
const { daemonSettings } = settings;
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
const { share_usage_data: shareSetting } = daemonSettings;
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
const isSharingData = shareSetting;
|
||||||
let languageSetting;
|
let languageSetting;
|
||||||
if (language === getDefaultLanguage()) {
|
if (language === getDefaultLanguage()) {
|
||||||
languageSetting = null;
|
languageSetting = null;
|
||||||
|
|
|
@ -29,7 +29,7 @@ export function doToggleSubscription(
|
||||||
}
|
}
|
||||||
|
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
const { share_usage_data: shareSetting } = daemonSettings;
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
const isSharingData = shareSetting;
|
||||||
|
|
||||||
if (!isSubscribed) {
|
if (!isSubscribed) {
|
||||||
const subscriptionUri = subscription.uri;
|
const subscriptionUri = subscription.uri;
|
||||||
|
@ -44,7 +44,7 @@ export function doToggleSubscription(
|
||||||
});
|
});
|
||||||
|
|
||||||
// if the user isn't sharing data, keep the subscriptions entirely in the app
|
// if the user isn't sharing data, keep the subscriptions entirely in the app
|
||||||
if (isSharingData || IS_WEB) {
|
if (isSharingData) {
|
||||||
const { channelClaimId } = parseURI(subscription.uri);
|
const { channelClaimId } = parseURI(subscription.uri);
|
||||||
|
|
||||||
if (!isSubscribed) {
|
if (!isSubscribed) {
|
||||||
|
|
|
@ -13,8 +13,6 @@ import { DOMAIN } from 'config';
|
||||||
import { getDefaultLanguage } from 'util/default-languages';
|
import { getDefaultLanguage } from 'util/default-languages';
|
||||||
const AUTH_IN_PROGRESS = 'authInProgress';
|
const AUTH_IN_PROGRESS = 'authInProgress';
|
||||||
export let sessionStorageAvailable = false;
|
export let sessionStorageAvailable = false;
|
||||||
const CHECK_INTERVAL = 200;
|
|
||||||
const AUTH_WAIT_TIMEOUT = 10000;
|
|
||||||
|
|
||||||
export function doFetchInviteStatus(shouldCallRewardList = true) {
|
export function doFetchInviteStatus(shouldCallRewardList = true) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
|
@ -96,37 +94,6 @@ export function doInstallNewWithParams(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkAuthBusy() {
|
|
||||||
let time = Date.now();
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
(function waitForAuth() {
|
|
||||||
try {
|
|
||||||
sessionStorage.setItem('test', 'available');
|
|
||||||
sessionStorage.removeItem('test');
|
|
||||||
sessionStorageAvailable = true;
|
|
||||||
} catch (e) {
|
|
||||||
if (e) {
|
|
||||||
// no session storage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!IS_WEB || !sessionStorageAvailable) {
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
const inProgress = window.sessionStorage.getItem(AUTH_IN_PROGRESS);
|
|
||||||
if (!inProgress) {
|
|
||||||
window.sessionStorage.setItem(AUTH_IN_PROGRESS, 'true');
|
|
||||||
return resolve();
|
|
||||||
} else {
|
|
||||||
if (Date.now() - time < AUTH_WAIT_TIMEOUT) {
|
|
||||||
setTimeout(waitForAuth, CHECK_INTERVAL);
|
|
||||||
} else {
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Call doInstallNew separately so we don't have to pass appVersion and os_system params?
|
// TODO: Call doInstallNew separately so we don't have to pass appVersion and os_system params?
|
||||||
export function doAuthenticate(
|
export function doAuthenticate(
|
||||||
appVersion,
|
appVersion,
|
||||||
|
@ -141,10 +108,7 @@ export function doAuthenticate(
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.AUTHENTICATION_STARTED,
|
type: ACTIONS.AUTHENTICATION_STARTED,
|
||||||
});
|
});
|
||||||
checkAuthBusy()
|
return Lbryio.authenticate(DOMAIN, getDefaultLanguage())
|
||||||
.then(() => {
|
|
||||||
return Lbryio.authenticate(DOMAIN, getDefaultLanguage());
|
|
||||||
})
|
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS);
|
if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS);
|
||||||
Lbryio.getAuthToken().then((token) => {
|
Lbryio.getAuthToken().then((token) => {
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import * as SHARED_PREFERENCES from 'constants/shared_preferences';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { getSubsetFromKeysArray } from 'util/sync-settings';
|
|
||||||
import { getDefaultLanguage } from 'util/default-languages';
|
import { getDefaultLanguage } from 'util/default-languages';
|
||||||
import { UNSYNCED_SETTINGS } from 'config';
|
|
||||||
|
|
||||||
const { CLIENT_SYNC_KEYS } = SHARED_PREFERENCES;
|
|
||||||
const settingsToIgnore = (UNSYNCED_SETTINGS && UNSYNCED_SETTINGS.trim().split(' ')) || [];
|
|
||||||
const clientSyncKeys = settingsToIgnore.length
|
|
||||||
? CLIENT_SYNC_KEYS.filter((k) => !settingsToIgnore.includes(k))
|
|
||||||
: CLIENT_SYNC_KEYS;
|
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
let settingLanguage = [];
|
let settingLanguage = [];
|
||||||
|
@ -34,7 +25,7 @@ const defaultState = {
|
||||||
[SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED]: false,
|
[SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED]: false,
|
||||||
[SETTINGS.FOLLOWING_ACKNOWLEDGED]: false,
|
[SETTINGS.FOLLOWING_ACKNOWLEDGED]: false,
|
||||||
[SETTINGS.TAGS_ACKNOWLEDGED]: false,
|
[SETTINGS.TAGS_ACKNOWLEDGED]: false,
|
||||||
[SETTINGS.ENABLE_SYNC]: IS_WEB,
|
[SETTINGS.ENABLE_SYNC]: false,
|
||||||
[SETTINGS.ENABLE_PUBLISH_PREVIEW]: true,
|
[SETTINGS.ENABLE_PUBLISH_PREVIEW]: true,
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const { DOMAIN } = require('../../config.js');
|
const { DOMAIN } = require('../../config.js');
|
||||||
const AUTH_TOKEN = 'auth_token';
|
const AUTH_TOKEN = 'auth_token';
|
||||||
const SAVED_PASSWORD = 'saved_password';
|
const SAVED_PASSWORD = 'saved_password';
|
||||||
const DEPRECATED_SAVED_PASSWORD = 'saved-password';
|
|
||||||
const domain =
|
const domain =
|
||||||
typeof window === 'object' && window.location.hostname.includes('localhost') ? window.location.hostname : DOMAIN;
|
typeof window === 'object' && window.location.hostname.includes('localhost') ? window.location.hostname : DOMAIN;
|
||||||
const isProduction = process.env.NODE_ENV === 'production';
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
@ -14,7 +13,7 @@ function setCookie(name, value, expirationDaysOnWeb) {
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
date.setTime(date.getTime() + expirationDaysOnWeb * 24 * 60 * 60 * 1000);
|
date.setTime(date.getTime() + expirationDaysOnWeb * 24 * 60 * 60 * 1000);
|
||||||
// If on PC, set to not expire (max)
|
// If on PC, set to not expire (max)
|
||||||
expires = `expires=${IS_WEB ? date.toUTCString() : maxExpiration};`;
|
expires = `expires=${maxExpiration};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cookie = `${name}=${value || ''}; ${expires} path=/;`;
|
let cookie = `${name}=${value || ''}; ${expires} path=/;`;
|
||||||
|
@ -59,7 +58,7 @@ function deleteCookie(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSavedPassword(value, saveToDisk) {
|
function setSavedPassword(value, saveToDisk) {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
const password = value === undefined || value === null ? '' : value;
|
const password = value === undefined || value === null ? '' : value;
|
||||||
sessionPassword = password;
|
sessionPassword = password;
|
||||||
|
|
||||||
|
@ -74,17 +73,17 @@ function setSavedPassword(value, saveToDisk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSavedPassword() {
|
function getSavedPassword() {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
if (sessionPassword) {
|
if (sessionPassword) {
|
||||||
resolve(sessionPassword);
|
resolve(sessionPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getPasswordFromCookie().then(p => resolve(p));
|
return getPasswordFromCookie().then((p) => resolve(p));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPasswordFromCookie() {
|
function getPasswordFromCookie() {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
let password;
|
let password;
|
||||||
password = getCookie(SAVED_PASSWORD);
|
password = getCookie(SAVED_PASSWORD);
|
||||||
resolve(password);
|
resolve(password);
|
||||||
|
@ -92,7 +91,7 @@ function getPasswordFromCookie() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSavedPassword() {
|
function deleteSavedPassword() {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
deleteCookie(SAVED_PASSWORD);
|
deleteCookie(SAVED_PASSWORD);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
@ -107,14 +106,14 @@ function setAuthToken(value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteAuthToken() {
|
function deleteAuthToken() {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
deleteCookie(AUTH_TOKEN);
|
deleteCookie(AUTH_TOKEN);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSignOutCleanup() {
|
function doSignOutCleanup() {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
deleteAuthToken();
|
deleteAuthToken();
|
||||||
deleteSavedPassword();
|
deleteSavedPassword();
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -129,18 +128,7 @@ function doAuthTokenRefresh() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doDeprecatedPasswordMigrationMarch2020() {
|
|
||||||
const savedPassword = getCookie(DEPRECATED_SAVED_PASSWORD);
|
|
||||||
if (savedPassword) {
|
|
||||||
deleteCookie(DEPRECATED_SAVED_PASSWORD);
|
|
||||||
setSavedPassword(savedPassword, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setCookie,
|
|
||||||
getCookie,
|
|
||||||
deleteCookie,
|
|
||||||
setSavedPassword,
|
setSavedPassword,
|
||||||
getSavedPassword,
|
getSavedPassword,
|
||||||
getPasswordFromCookie,
|
getPasswordFromCookie,
|
||||||
|
@ -150,5 +138,4 @@ module.exports = {
|
||||||
deleteAuthToken,
|
deleteAuthToken,
|
||||||
doSignOutCleanup,
|
doSignOutCleanup,
|
||||||
doAuthTokenRefresh,
|
doAuthTokenRefresh,
|
||||||
doDeprecatedPasswordMigrationMarch2020,
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue