navigation redesign
This commit is contained in:
parent
e7c1085faa
commit
a8711c027f
33 changed files with 499 additions and 219 deletions
|
@ -936,5 +936,12 @@
|
|||
"Text copied": "Text copied",
|
||||
"Rewards Disabled": "Rewards Disabled",
|
||||
"Woah, you have a lot of friends! You've claimed the maximum amount of referral rewards. Check back soon to see if more are available!.": "Woah, you have a lot of friends! You've claimed the maximum amount of referral rewards. Check back soon to see if more are available!.",
|
||||
"Wallet servers are used to relay data to and from the LBRY blockchain. They also determine what content shows in trending or is blocked. %learn_more%.": "Wallet servers are used to relay data to and from the LBRY blockchain. They also determine what content shows in trending or is blocked. %learn_more%."
|
||||
}
|
||||
"Wallet servers are used to relay data to and from the LBRY blockchain. They also determine what content shows in trending or is blocked. %learn_more%.": "Wallet servers are used to relay data to and from the LBRY blockchain. They also determine what content shows in trending or is blocked. %learn_more%.",
|
||||
"Your Tags": "Your Tags",
|
||||
"All Content": "All Content",
|
||||
"Claim Your 5 LBC Invite Reward": "Claim Your 5 LBC Invite Reward",
|
||||
"Accepted": "Accepted",
|
||||
"Claimable": "Claimable",
|
||||
"Invite A Friend": "Invite A Friend",
|
||||
"Navigation": "Navigation"
|
||||
}
|
|
@ -46,7 +46,7 @@ type LogPublishParams = {
|
|||
let analyticsEnabled: boolean = true;
|
||||
const analytics: Analytics = {
|
||||
error: message => {
|
||||
if (analyticsEnabled) {
|
||||
if (analyticsEnabled && isProduction) {
|
||||
Lbryio.call('event', 'desktop_error', { error_message: message });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -147,6 +147,13 @@ function App(props: Props) {
|
|||
}
|
||||
}, [previousRewardApproved, isRewardApproved]);
|
||||
|
||||
// @if TARGET='app'
|
||||
useEffect(() => {
|
||||
console.log('update prefs');
|
||||
updatePreferences();
|
||||
}, []);
|
||||
// @endif
|
||||
|
||||
// Keep this at the end to ensure initial setup effects are run first
|
||||
useEffect(() => {
|
||||
// Wait for balance to be populated on desktop so we know when we can begin syncing
|
||||
|
|
|
@ -7,14 +7,12 @@ import {
|
|||
doToggleTagFollow,
|
||||
selectBlockedChannels,
|
||||
} from 'lbry-redux';
|
||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import ClaimListDiscover from './view';
|
||||
|
||||
const select = state => ({
|
||||
claimSearchByQuery: selectClaimSearchByQuery(state),
|
||||
loading: selectFetchingClaimSearch(state),
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
showNsfw: makeSelectClientSetting(SETTINGS.SHOW_MATURE)(state),
|
||||
hiddenUris: selectBlockedChannels(state),
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import type { Node } from 'react';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import classnames from 'classnames';
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { createNormalizedClaimSearchKey, MATURE_TAGS } from 'lbry-redux';
|
||||
|
@ -8,7 +8,6 @@ import { FormField } from 'component/common/form';
|
|||
import Button from 'component/button';
|
||||
import moment from 'moment';
|
||||
import ClaimList from 'component/claimList';
|
||||
import Tag from 'component/tag';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import { toCapitalCase } from 'util/string';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
@ -19,15 +18,12 @@ const TIME_WEEK = 'week';
|
|||
const TIME_MONTH = 'month';
|
||||
const TIME_YEAR = 'year';
|
||||
const TIME_ALL = 'all';
|
||||
const SEARCH_SORT_YOU = 'you';
|
||||
const SEARCH_SORT_ALL = 'everyone';
|
||||
const SEARCH_SORT_CHANNELS = 'channels';
|
||||
|
||||
const TYPE_TRENDING = 'trending';
|
||||
const TYPE_TOP = 'top';
|
||||
const TYPE_NEW = 'new';
|
||||
const SEARCH_FILTER_TYPES = [SEARCH_SORT_YOU, SEARCH_SORT_CHANNELS, SEARCH_SORT_ALL];
|
||||
const SEARCH_TYPES = [TYPE_TRENDING, TYPE_TOP, TYPE_NEW];
|
||||
export const TYPE_TRENDING = 'trending';
|
||||
export const TYPE_TOP = 'top';
|
||||
export const TYPE_NEW = 'new';
|
||||
|
||||
const SEARCH_TYPES = [TYPE_TRENDING, TYPE_NEW, TYPE_TOP];
|
||||
const SEARCH_TIMES = [TIME_DAY, TIME_WEEK, TIME_MONTH, TIME_YEAR, TIME_ALL];
|
||||
|
||||
type Props = {
|
||||
|
@ -40,7 +36,6 @@ type Props = {
|
|||
doToggleTagFollow: string => void,
|
||||
meta?: Node,
|
||||
showNsfw: boolean,
|
||||
hideCustomization: boolean,
|
||||
history: { action: string, push: string => void, replace: string => void },
|
||||
location: { search: string, pathname: string },
|
||||
claimSearchByQuery: {
|
||||
|
@ -48,6 +43,8 @@ type Props = {
|
|||
},
|
||||
hiddenUris: Array<string>,
|
||||
hiddenNsfwMessage?: Node,
|
||||
channelIds?: Array<string>,
|
||||
defaultTypeSort?: string,
|
||||
};
|
||||
|
||||
function ClaimListDiscover(props: Props) {
|
||||
|
@ -58,21 +55,20 @@ function ClaimListDiscover(props: Props) {
|
|||
loading,
|
||||
personalView,
|
||||
meta,
|
||||
subscribedChannels,
|
||||
channelIds,
|
||||
showNsfw,
|
||||
history,
|
||||
location,
|
||||
hiddenUris,
|
||||
hideCustomization,
|
||||
hiddenNsfwMessage,
|
||||
defaultTypeSort,
|
||||
} = props;
|
||||
const didNavigateForward = history.action === 'PUSH';
|
||||
const [page, setPage] = useState(1);
|
||||
const { search } = location;
|
||||
const [forceRefresh, setForceRefresh] = useState();
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const personalSort = urlParams.get('sort') || (hideCustomization ? SEARCH_SORT_ALL : SEARCH_SORT_YOU);
|
||||
const typeSort = urlParams.get('type') || TYPE_TRENDING;
|
||||
const typeSort = urlParams.get('type') || defaultTypeSort || TYPE_TRENDING;
|
||||
const timeSort = urlParams.get('time') || TIME_WEEK;
|
||||
const tagsInUrl = urlParams.get('t') || '';
|
||||
const options: {
|
||||
|
@ -91,8 +87,8 @@ function ClaimListDiscover(props: Props) {
|
|||
// no_totals makes it so the sdk doesn't have to calculate total number pages for pagination
|
||||
// it's faster, but we will need to remove it if we start using total_pages
|
||||
no_totals: true,
|
||||
any_tags: (personalView && !hideCustomization && personalSort === SEARCH_SORT_YOU) || !personalView ? tags : [],
|
||||
channel_ids: personalSort === SEARCH_SORT_CHANNELS ? subscribedChannels.map(sub => sub.uri.split('#')[1]) : [],
|
||||
any_tags: tags || [],
|
||||
channel_ids: channelIds || [],
|
||||
not_channel_ids: hiddenUris && hiddenUris.length ? hiddenUris.map(hiddenUri => hiddenUri.split('#')[1]) : [],
|
||||
not_tags: !showNsfw ? MATURE_TAGS : [],
|
||||
order_by:
|
||||
|
@ -110,41 +106,17 @@ function ClaimListDiscover(props: Props) {
|
|||
.unix()
|
||||
)}`;
|
||||
}
|
||||
const hasContent =
|
||||
(personalSort === SEARCH_SORT_CHANNELS && subscribedChannels.length) ||
|
||||
(personalSort === SEARCH_SORT_YOU && !!tags.length) ||
|
||||
personalSort === SEARCH_SORT_ALL;
|
||||
const hasMatureTags = tags.some(t => MATURE_TAGS.includes(t));
|
||||
|
||||
const hasMatureTags = tags && tags.some(t => MATURE_TAGS.includes(t));
|
||||
const claimSearchCacheQuery = createNormalizedClaimSearchKey(options);
|
||||
const uris = (hasContent && claimSearchByQuery[claimSearchCacheQuery]) || [];
|
||||
const uris = claimSearchByQuery[claimSearchCacheQuery] || [];
|
||||
const shouldPerformSearch =
|
||||
hasContent &&
|
||||
(uris.length === 0 ||
|
||||
didNavigateForward ||
|
||||
(!loading && uris.length < PAGE_SIZE * page && uris.length % PAGE_SIZE === 0));
|
||||
uris.length === 0 ||
|
||||
didNavigateForward ||
|
||||
(!loading && uris.length < PAGE_SIZE * page && uris.length % PAGE_SIZE === 0);
|
||||
// Don't use the query from createNormalizedClaimSearchKey for the effect since that doesn't include page & release_time
|
||||
const optionsStringForEffect = JSON.stringify(options);
|
||||
|
||||
const noChannels = (
|
||||
<div>
|
||||
<p>
|
||||
<I18nMessage>You're not following any channels.</I18nMessage>
|
||||
</p>
|
||||
<p>
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
trending: (
|
||||
<Button button="link" label={__('trending for everyone')} navigate={'/?type=trending&sort=everyone'} />
|
||||
),
|
||||
discover: <Button button="link" label={__('discover some channels!')} navigate={'/$/following'} />,
|
||||
}}
|
||||
>
|
||||
Look what's %trending% or %discover%
|
||||
</I18nMessage>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
const noResults = (
|
||||
<div>
|
||||
<p>
|
||||
|
@ -174,22 +146,6 @@ function ClaimListDiscover(props: Props) {
|
|||
</div>
|
||||
);
|
||||
|
||||
const noTags = (
|
||||
<p>
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
customize: <Button button="link" navigate={`/$/${PAGES.FOLLOWING}`} label={__('customize')} />,
|
||||
}}
|
||||
>
|
||||
You're not following any tags. Add tags above or smash that %customize% button!
|
||||
</I18nMessage>
|
||||
</p>
|
||||
);
|
||||
|
||||
const noFollowing =
|
||||
(personalSort === SEARCH_SORT_YOU && noTags) || (personalSort === SEARCH_SORT_CHANNELS && noChannels);
|
||||
const emptyState = !loading && !hasContent ? noFollowing : noResults;
|
||||
|
||||
function getSearch() {
|
||||
let search = `?`;
|
||||
if (!personalView) {
|
||||
|
@ -200,7 +156,7 @@ function ClaimListDiscover(props: Props) {
|
|||
}
|
||||
|
||||
function handleTypeSort(newTypeSort) {
|
||||
let url = `${getSearch()}type=${newTypeSort}&sort=${personalSort}`;
|
||||
let url = `${getSearch()}type=${newTypeSort}`;
|
||||
if (newTypeSort === TYPE_TOP) {
|
||||
url += `&time=${timeSort}`;
|
||||
}
|
||||
|
@ -209,14 +165,9 @@ function ClaimListDiscover(props: Props) {
|
|||
history.push(url);
|
||||
}
|
||||
|
||||
function handlePersonalSort(newPersonalSort) {
|
||||
setPage(1);
|
||||
history.push(`${getSearch()}type=${typeSort}&sort=${newPersonalSort}`);
|
||||
}
|
||||
|
||||
function handleTimeSort(newTimeSort) {
|
||||
setPage(1);
|
||||
history.push(`${getSearch()}type=${typeSort}&sort=${personalSort}&time=${newTimeSort}`);
|
||||
history.push(`${getSearch()}type=${typeSort}&time=${newTimeSort}`);
|
||||
}
|
||||
|
||||
function handleScrollBottom() {
|
||||
|
@ -234,47 +185,19 @@ function ClaimListDiscover(props: Props) {
|
|||
|
||||
const header = (
|
||||
<Fragment>
|
||||
<FormField
|
||||
className="claim-list__dropdown"
|
||||
type="select"
|
||||
name="trending_sort"
|
||||
value={typeSort}
|
||||
onChange={e => handleTypeSort(e.target.value)}
|
||||
>
|
||||
{SEARCH_TYPES.map(type => (
|
||||
<option key={type} value={type}>
|
||||
{__(toCapitalCase(type))}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
{!hideCustomization && (
|
||||
<Fragment>
|
||||
<span className="claim-list__conjuction">{__('for')}</span>
|
||||
{!personalView && tags && tags.length ? (
|
||||
tags.map(tag => <Tag key={tag} name={tag} disabled type="large" />)
|
||||
) : (
|
||||
<FormField
|
||||
type="select"
|
||||
name="trending_overview"
|
||||
className="claim-list__dropdown"
|
||||
value={personalSort}
|
||||
onChange={e => {
|
||||
handlePersonalSort(e.target.value);
|
||||
}}
|
||||
>
|
||||
{SEARCH_FILTER_TYPES.map(type => (
|
||||
<option key={type} value={type}>
|
||||
{type === SEARCH_SORT_ALL
|
||||
? __('Everyone')
|
||||
: type === SEARCH_SORT_YOU
|
||||
? __('Tags You Follow')
|
||||
: __('Channels You Follow')}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
{SEARCH_TYPES.map(type => (
|
||||
<Button
|
||||
key={type}
|
||||
button="alt"
|
||||
onClick={() => handleTypeSort(type)}
|
||||
className={classnames(`button-toggle button-toggle--${type}`, {
|
||||
'button-toggle--active': typeSort === type,
|
||||
})}
|
||||
icon={toCapitalCase(type)}
|
||||
label={__(toCapitalCase(type))}
|
||||
/>
|
||||
))}
|
||||
|
||||
{typeSort === 'top' && (
|
||||
<FormField
|
||||
className="claim-list__dropdown"
|
||||
|
@ -308,7 +231,7 @@ function ClaimListDiscover(props: Props) {
|
|||
onScrollBottom={handleScrollBottom}
|
||||
page={page}
|
||||
pageSize={PAGE_SIZE}
|
||||
empty={emptyState}
|
||||
empty={noResults}
|
||||
/>
|
||||
|
||||
{loading && new Array(PAGE_SIZE).fill(1).map((x, i) => <ClaimPreview key={i} placeholder="loading" />)}
|
||||
|
|
|
@ -329,4 +329,37 @@ export const icons = {
|
|||
<line x1="3" y1="18" x2="21" y2="18" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.DISCOVER]: buildIcon(
|
||||
<g>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.TRENDING]: buildIcon(
|
||||
<g>
|
||||
<polyline points="23 6 13.5 15.5 8.5 10.5 1 18" />
|
||||
<polyline points="17 6 23 6 23 12" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.TOP]: buildIcon(
|
||||
<g>
|
||||
<line x1="12" y1="20" x2="12" y2="10" />
|
||||
<line x1="18" y1="20" x2="18" y2="4" />
|
||||
<line x1="6" y1="20" x2="6" y2="16" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.NEW]: buildIcon(
|
||||
<g>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.INVITE]: buildIcon(
|
||||
<g>
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</g>
|
||||
),
|
||||
};
|
||||
|
|
|
@ -127,33 +127,42 @@ const Header = (props: Props) => {
|
|||
<div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
|
||||
{(!IS_WEB || authenticated) && (
|
||||
<Fragment>
|
||||
<Menu>
|
||||
<MenuButton className="header__navigation-item menu__title">{getWalletTitle()}</MenuButton>
|
||||
<MenuList className="menu__list--header">
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.WALLET}`)}>
|
||||
<Icon aria-hidden icon={ICONS.WALLET} />
|
||||
{__('Wallet')}
|
||||
</MenuItem>
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.REWARDS}`)}>
|
||||
<Icon aria-hidden icon={ICONS.FEATURED} />
|
||||
{__('Rewards')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Button
|
||||
navigate={`/$/${PAGES.WALLET}`}
|
||||
className="header__navigation-item menu__title header__navigation-item--balance"
|
||||
label={getWalletTitle()}
|
||||
/>
|
||||
<Menu>
|
||||
<MenuButton className="header__navigation-item menu__title header__navigation-item--icon">
|
||||
<Icon size={18} icon={ICONS.ACCOUNT} />
|
||||
</MenuButton>
|
||||
<MenuList className="menu__list--header">
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.ACCOUNT}`)}>
|
||||
<Icon aria-hidden icon={ICONS.OVERVIEW} />
|
||||
{__('Overview')}
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.PUBLISH}`)}>
|
||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||
{__('Publish')}
|
||||
{__('New Publish')}
|
||||
</MenuItem>
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.PUBLISHED}`)}>
|
||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||
{__('Your Publishes')}
|
||||
</MenuItem>
|
||||
|
||||
{/* @if TARGET='app' */}
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.PUBLISH}`)}>
|
||||
<Icon aria-hidden icon={ICONS.LIBRARY} />
|
||||
{__('Your Library')}
|
||||
</MenuItem>
|
||||
{/* @endif */}
|
||||
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.REWARDS}`)}>
|
||||
<Icon aria-hidden icon={ICONS.FEATURED} />
|
||||
{__('Rewards')}
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.INVITE}`)}>
|
||||
<Icon aria-hidden icon={ICONS.INVITE} />
|
||||
{__('Invite A Friend')}
|
||||
</MenuItem>
|
||||
|
||||
{authenticated ? (
|
||||
<MenuItem className="menu__link" onSelect={signOut}>
|
||||
<Icon aria-hidden icon={ICONS.SIGN_OUT} />
|
||||
|
|
|
@ -17,14 +17,14 @@ type Props = {
|
|||
|
||||
function Page(props: Props) {
|
||||
const { children, className, authPage = false, authenticated } = props;
|
||||
const obscureSideBar = IS_WEB ? !authenticated : false;
|
||||
const obscureSideNavigation = IS_WEB ? !authenticated : false;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Header authHeader={authPage} />
|
||||
<div className={classnames('main-wrapper__inner')}>
|
||||
<main className={classnames(MAIN_CLASS, className, { 'main--full-width': authPage })}>{children}</main>
|
||||
{!authPage && <SideNavigation obscureSideBar={obscureSideBar} />}
|
||||
{!authPage && <SideNavigation obscureSideNavigation={obscureSideNavigation} />}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -5,10 +5,10 @@ import { Route, Redirect, Switch, withRouter } from 'react-router-dom';
|
|||
import SettingsPage from 'page/settings';
|
||||
import HelpPage from 'page/help';
|
||||
import ReportPage from 'page/report';
|
||||
import AccountPage from 'page/account';
|
||||
import ShowPage from 'page/show';
|
||||
import PublishPage from 'page/publish';
|
||||
import DiscoverPage from 'page/discover';
|
||||
// import HomePage from 'page/home';
|
||||
import RewardsPage from 'page/rewards';
|
||||
import FileListDownloaded from 'page/fileListDownloaded';
|
||||
import FileListPublished from 'page/fileListPublished';
|
||||
|
@ -18,6 +18,9 @@ import SearchPage from 'page/search';
|
|||
import LibraryPage from 'page/library';
|
||||
import WalletPage from 'page/wallet';
|
||||
import TagsPage from 'page/tags';
|
||||
import TagsFollowingPage from 'page/tagsFollowing';
|
||||
import ChannelsFollowingPage from 'page/channelsFollowing';
|
||||
import ChannelsFollowingManagePage from 'page/channelsFollowingManage';
|
||||
import FollowingPage from 'page/following';
|
||||
import ListBlockedPage from 'page/listBlocked';
|
||||
import FourOhFourPage from 'page/fourOhFour';
|
||||
|
@ -70,10 +73,13 @@ function AppRouter(props: Props) {
|
|||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path="/" exact component={DiscoverPage} />
|
||||
{/* <Route path={`/$/${PAGES.HOME}`} exact component={HomePage} /> */}
|
||||
<Route path={`/$/${PAGES.DISCOVER}`} exact component={DiscoverPage} />
|
||||
<Route path={`/$/${PAGES.AUTH}`} exact component={SignInPage} />
|
||||
<Route path={`/$/${PAGES.TAGS}`} exact component={TagsPage} />
|
||||
<Route path={`/$/${PAGES.TAGS_FOLLOWING}`} exact component={TagsFollowingPage} />
|
||||
<Route path={`/$/${PAGES.CHANNELS_FOLLOWING}`} exact component={ChannelsFollowingPage} />
|
||||
<Route path={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`} exact component={ChannelsFollowingManagePage} />
|
||||
<Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} />
|
||||
<Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} />
|
||||
<Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} />
|
||||
|
@ -87,7 +93,6 @@ function AppRouter(props: Props) {
|
|||
<PrivateRoute {...props} path={`/$/${PAGES.REWARDS}`} component={RewardsPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.TRANSACTIONS}`} component={TransactionHistoryPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.LIBRARY}`} component={LibraryPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.ACCOUNT}`} component={AccountPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.FOLLOWING}`} component={FollowingPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.BLOCKED}`} component={ListBlockedPage} />
|
||||
<PrivateRoute {...props} path={`/$/${PAGES.WALLET}`} exact component={WalletPage} />
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import * as PAGES from 'constants/pages';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import Button from 'component/button';
|
||||
import Tag from 'component/tag';
|
||||
import StickyBox from 'react-sticky-box/dist/esnext';
|
||||
|
@ -11,24 +12,27 @@ type Props = {
|
|||
subscriptions: Array<Subscription>,
|
||||
followedTags: Array<Tag>,
|
||||
email: ?string,
|
||||
obscureSideBar: boolean,
|
||||
obscureSideNavigation: boolean,
|
||||
uploadCount: number,
|
||||
sticky: boolean,
|
||||
expanded: boolean,
|
||||
doSignOut: () => void,
|
||||
location: { pathname: string },
|
||||
};
|
||||
|
||||
function SideBar(props: Props) {
|
||||
function SideNavigation(props: Props) {
|
||||
const {
|
||||
subscriptions,
|
||||
followedTags,
|
||||
obscureSideBar,
|
||||
obscureSideNavigation,
|
||||
uploadCount,
|
||||
doSignOut,
|
||||
email,
|
||||
sticky = true,
|
||||
expanded = false,
|
||||
location,
|
||||
} = props;
|
||||
const { pathname } = location;
|
||||
const isAuthenticated = Boolean(email);
|
||||
|
||||
function buildLink(path, label, icon, onClick) {
|
||||
|
@ -49,7 +53,7 @@ function SideBar(props: Props) {
|
|||
<div>{children}</div>
|
||||
);
|
||||
|
||||
return obscureSideBar ? (
|
||||
return obscureSideNavigation ? (
|
||||
<Wrapper>
|
||||
<div className="card navigation--placeholder">
|
||||
<div className="wrap">
|
||||
|
@ -64,29 +68,13 @@ function SideBar(props: Props) {
|
|||
<ul className="navigation-links">
|
||||
{[
|
||||
{
|
||||
...buildLink(null, __('Home'), ICONS.HOME),
|
||||
},
|
||||
// @if TARGET='app'
|
||||
{
|
||||
...buildLink(PAGES.LIBRARY, __('Library'), ICONS.LIBRARY),
|
||||
},
|
||||
// @endif
|
||||
{
|
||||
...buildLink(PAGES.CHANNELS, __('Channels'), ICONS.CHANNEL),
|
||||
...buildLink(PAGES.CHANNELS_FOLLOWING, __('Following'), ICONS.SUBSCRIBE),
|
||||
},
|
||||
{
|
||||
...buildLink(
|
||||
PAGES.PUBLISHED,
|
||||
uploadCount ? (
|
||||
<span>
|
||||
{__('Publishes')}
|
||||
<Spinner type="small" />
|
||||
</span>
|
||||
) : (
|
||||
__('Publishes')
|
||||
),
|
||||
ICONS.PUBLISH
|
||||
),
|
||||
...buildLink(PAGES.TAGS_FOLLOWING, __('Your Tags'), ICONS.TAG),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.DISCOVER, __('All Content'), ICONS.DISCOVER),
|
||||
},
|
||||
].map(linkProps => (
|
||||
<li key={linkProps.navigate}>
|
||||
|
@ -96,6 +84,28 @@ function SideBar(props: Props) {
|
|||
|
||||
{expanded &&
|
||||
[
|
||||
// @if TARGET='app'
|
||||
{
|
||||
...buildLink(PAGES.LIBRARY, __('Library'), ICONS.LIBRARY),
|
||||
},
|
||||
// @endif
|
||||
{
|
||||
...buildLink(PAGES.CHANNELS, __('Channels'), ICONS.CHANNEL),
|
||||
},
|
||||
{
|
||||
...buildLink(
|
||||
PAGES.PUBLISHED,
|
||||
uploadCount ? (
|
||||
<span>
|
||||
{__('Publishes')}
|
||||
<Spinner type="small" />
|
||||
</span>
|
||||
) : (
|
||||
__('Publishes')
|
||||
),
|
||||
ICONS.PUBLISH
|
||||
),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.WALLET, __('Wallet'), ICONS.WALLET),
|
||||
},
|
||||
|
@ -126,27 +136,20 @@ function SideBar(props: Props) {
|
|||
</li>
|
||||
))
|
||||
)}
|
||||
|
||||
<li>
|
||||
<Button
|
||||
navigate={`/$/${PAGES.FOLLOWING}`}
|
||||
label={__('Customize')}
|
||||
icon={ICONS.EDIT}
|
||||
className="navigation-link"
|
||||
activeClass="navigation-link--active"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<section className="navigation-links__inline">
|
||||
<ul className="navigation-links--small tags--vertical">
|
||||
{pathname.includes(PAGES.TAGS_FOLLOWING) && (
|
||||
<ul className="navigation__secondary navigation-links--small tags--vertical">
|
||||
{followedTags.map(({ name }, key) => (
|
||||
<li className="navigation-link__wrapper" key={name}>
|
||||
<Tag navigate={`/$/tags?t${name}`} name={name} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<ul className="navigation-links--small">
|
||||
)}
|
||||
|
||||
{pathname.includes(PAGES.CHANNELS_FOLLOWING) && (
|
||||
<ul className="navigation__secondary navigation-links--small">
|
||||
{subscriptions.map(({ uri, channelName }, index) => (
|
||||
<li key={uri} className="navigation-link__wrapper">
|
||||
<Button
|
||||
|
@ -158,10 +161,10 @@ function SideBar(props: Props) {
|
|||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)}
|
||||
</nav>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default SideBar;
|
||||
export default withRouter(SideNavigation);
|
||||
|
|
|
@ -78,3 +78,6 @@ export const EYE = 'Eye';
|
|||
export const EYE_OFF = 'EyeOff';
|
||||
export const SIGN_OUT = 'SignOut';
|
||||
export const SIGN_IN = 'SignIn';
|
||||
export const TRENDING = 'Trending';
|
||||
export const TOP = 'Top';
|
||||
export const NEW = 'New';
|
||||
|
|
|
@ -3,6 +3,7 @@ exports.AUTH_VERIFY = 'verify';
|
|||
exports.BACKUP = 'backup';
|
||||
exports.CHANNEL = 'channel';
|
||||
exports.DISCOVER = 'discover';
|
||||
exports.HOME = 'home';
|
||||
exports.DOWNLOADED = 'downloaded';
|
||||
exports.HELP = 'help';
|
||||
exports.LIBRARY = 'library';
|
||||
|
@ -16,10 +17,13 @@ exports.SEND = 'send';
|
|||
exports.SETTINGS = 'settings';
|
||||
exports.SHOW = 'show';
|
||||
exports.ACCOUNT = 'account';
|
||||
exports.FOLLOWING = 'following';
|
||||
exports.SEARCH = 'search';
|
||||
exports.TRANSACTIONS = 'transactions';
|
||||
exports.TAGS = 'tags';
|
||||
exports.TAGS_FOLLOWING = 'following/tags';
|
||||
exports.CHANNELS_FOLLOWING = 'following/channels';
|
||||
exports.CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage';
|
||||
exports.FOLLOWING = 'following';
|
||||
exports.WALLET = 'wallet';
|
||||
exports.BLOCKED = 'blocked';
|
||||
exports.CHANNELS = 'channels';
|
||||
|
|
20
ui/page/channelsFollowing/index.js
Normal file
20
ui/page/channelsFollowing/index.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectUserVerifiedEmail } from 'lbryinc';
|
||||
import { selectSubscriptions, selectSuggestedChannels } from 'redux/selectors/subscriptions';
|
||||
import { doFetchRecommendedSubscriptions } from 'redux/actions/subscriptions';
|
||||
import DiscoverPage from './view';
|
||||
|
||||
const select = state => ({
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
email: selectUserVerifiedEmail(state),
|
||||
suggestedSubscriptions: selectSuggestedChannels(state),
|
||||
});
|
||||
|
||||
const perform = {
|
||||
doFetchRecommendedSubscriptions,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(DiscoverPage);
|
56
ui/page/channelsFollowing/view.jsx
Normal file
56
ui/page/channelsFollowing/view.jsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import ClaimListDiscover from 'component/claimListDiscover';
|
||||
import ClaimList from 'component/claimList';
|
||||
import Page from 'component/page';
|
||||
import Button from 'component/button';
|
||||
|
||||
import { TYPE_NEW } from 'component/claimListDiscover/view';
|
||||
|
||||
type Props = {
|
||||
email: string,
|
||||
subscribedChannels: Array<Subscription>,
|
||||
doFetchRecommendedSubscriptions: () => void,
|
||||
suggestedSubscriptions: Array<{ uri: string }>,
|
||||
};
|
||||
|
||||
function ChannelsFollowing(props: Props) {
|
||||
const { subscribedChannels, suggestedSubscriptions, doFetchRecommendedSubscriptions } = props;
|
||||
const hasSubsribedChannels = subscribedChannels.length > 0;
|
||||
const [showTab, setShowTab] = React.useState(!hasSubsribedChannels);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!hasSubsribedChannels) {
|
||||
doFetchRecommendedSubscriptions();
|
||||
}
|
||||
}, [doFetchRecommendedSubscriptions, hasSubsribedChannels]);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{showTab ? (
|
||||
<div className="card">
|
||||
<ClaimList
|
||||
header={__('Find Channels To Follow')}
|
||||
headerAltControls={
|
||||
<Button
|
||||
button="link"
|
||||
label={hasSubsribedChannels && __('View Your Feed')}
|
||||
onClick={() => setShowTab(false)}
|
||||
/>
|
||||
}
|
||||
uris={suggestedSubscriptions.map(sub => `lbry://${sub.uri}`)}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<ClaimListDiscover
|
||||
defaultTypeSort={TYPE_NEW}
|
||||
channelIds={subscribedChannels.map(sub => sub.uri.split('#')[1])}
|
||||
meta={<Button button="link" label={__('Manage')} navigate={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`} />}
|
||||
/>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChannelsFollowing;
|
16
ui/page/channelsFollowingManage/index.js
Normal file
16
ui/page/channelsFollowingManage/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectSubscriptions, selectSuggestedChannels } from 'redux/selectors/subscriptions';
|
||||
import { doFetchRecommendedSubscriptions } from 'redux/actions/subscriptions';
|
||||
import ChannelsFollowingManagePage from './view';
|
||||
|
||||
const select = state => ({
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
suggestedSubscriptions: selectSuggestedChannels(state),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
{
|
||||
doFetchRecommendedSubscriptions,
|
||||
}
|
||||
)(ChannelsFollowingManagePage);
|
57
ui/page/channelsFollowingManage/view.jsx
Normal file
57
ui/page/channelsFollowingManage/view.jsx
Normal file
|
@ -0,0 +1,57 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React, { useEffect } from 'react';
|
||||
import Page from 'component/page';
|
||||
import ClaimList from 'component/claimList';
|
||||
import Button from 'component/button';
|
||||
|
||||
type Props = {
|
||||
subscribedChannels: Array<Subscription>,
|
||||
location: { search: string },
|
||||
history: { push: string => void },
|
||||
doFetchRecommendedSubscriptions: () => void,
|
||||
suggestedSubscriptions: Array<{ uri: string }>,
|
||||
};
|
||||
|
||||
function ChannelsFollowingManagePage(props: Props) {
|
||||
const { subscribedChannels, location, history, doFetchRecommendedSubscriptions, suggestedSubscriptions } = props;
|
||||
const hasSubscriptions = !!subscribedChannels.length;
|
||||
const channelUris = subscribedChannels.map(({ uri }) => uri);
|
||||
|
||||
const { search } = location;
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const viewingSuggestedSubs = urlParams.get('view') || !hasSubscriptions;
|
||||
|
||||
function onClick() {
|
||||
let url = `/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`;
|
||||
if (!viewingSuggestedSubs) {
|
||||
url += '?view=discover';
|
||||
}
|
||||
|
||||
history.push(url);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
doFetchRecommendedSubscriptions();
|
||||
}, [doFetchRecommendedSubscriptions]);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div className="card">
|
||||
<ClaimList
|
||||
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
|
||||
headerAltControls={
|
||||
<Button
|
||||
button="link"
|
||||
label={viewingSuggestedSubs ? hasSubscriptions && __('View Your Channels') : __('Find New Channels')}
|
||||
onClick={() => onClick()}
|
||||
/>
|
||||
}
|
||||
uris={viewingSuggestedSubs ? suggestedSubscriptions.map(sub => `lbry://${sub.uri}`) : channelUris}
|
||||
/>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChannelsFollowingManagePage;
|
|
@ -1,28 +1,12 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import ClaimListDiscover from 'component/claimListDiscover';
|
||||
import TagsSelect from 'component/tagsSelect';
|
||||
import Page from 'component/page';
|
||||
import Button from 'component/button';
|
||||
|
||||
type Props = {
|
||||
followedTags: Array<Tag>,
|
||||
email: string,
|
||||
};
|
||||
|
||||
function DiscoverPage(props: Props) {
|
||||
const { followedTags, email } = props;
|
||||
|
||||
function DiscoverPage() {
|
||||
return (
|
||||
<Page>
|
||||
{(email || !IS_WEB) && <TagsSelect showClose title={__('Customize Your Homepage')} />}
|
||||
<ClaimListDiscover
|
||||
hideCustomization={IS_WEB && !email}
|
||||
personalView
|
||||
tags={followedTags.map(tag => tag.name)}
|
||||
meta={<Button button="link" label={__('Customize')} requiresAuth={IS_WEB} navigate={`/$/${PAGES.FOLLOWING}`} />}
|
||||
/>
|
||||
<ClaimListDiscover />
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
|
18
ui/page/home/index.js
Normal file
18
ui/page/home/index.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectFollowedTags } from 'lbry-redux';
|
||||
import { selectUserVerifiedEmail } from 'lbryinc';
|
||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import DiscoverPage from './view';
|
||||
|
||||
const select = state => ({
|
||||
followedTags: selectFollowedTags(state),
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
email: selectUserVerifiedEmail(state),
|
||||
});
|
||||
|
||||
const perform = {};
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(DiscoverPage);
|
22
ui/page/home/view.jsx
Normal file
22
ui/page/home/view.jsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
// import Button from 'component/button';
|
||||
|
||||
// type Props = {};
|
||||
|
||||
function HomePage() {
|
||||
// props: Props
|
||||
// const {} = props;
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{/* TODO */}
|
||||
{/* Recent From Following */}
|
||||
{/* Trending for your tags */}
|
||||
{/* Trending for everyone */}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default HomePage;
|
18
ui/page/tagsFollowing/index.js
Normal file
18
ui/page/tagsFollowing/index.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectFollowedTags } from 'lbry-redux';
|
||||
import { selectUserVerifiedEmail } from 'lbryinc';
|
||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import DiscoverPage from './view';
|
||||
|
||||
const select = state => ({
|
||||
followedTags: selectFollowedTags(state),
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
email: selectUserVerifiedEmail(state),
|
||||
});
|
||||
|
||||
const perform = {};
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(DiscoverPage);
|
30
ui/page/tagsFollowing/view.jsx
Normal file
30
ui/page/tagsFollowing/view.jsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import ClaimListDiscover from 'component/claimListDiscover';
|
||||
import TagsSelect from 'component/tagsSelect';
|
||||
import Page from 'component/page';
|
||||
import Button from 'component/button';
|
||||
|
||||
type Props = {
|
||||
followedTags: Array<Tag>,
|
||||
email: string,
|
||||
};
|
||||
|
||||
function DiscoverPage(props: Props) {
|
||||
const { followedTags, email } = props;
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{(email || !IS_WEB) && <TagsSelect showClose title={__('Find New Tags To Follow')} />}
|
||||
<ClaimListDiscover
|
||||
hideCustomization={IS_WEB && !email}
|
||||
personalView
|
||||
tags={followedTags.map(tag => tag.name)}
|
||||
meta={<Button button="link" label={__('Customize')} requiresAuth={IS_WEB} navigate={`/$/${PAGES.FOLLOWING}`} />}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
export default DiscoverPage;
|
|
@ -467,6 +467,7 @@ export function doGetAndPopulatePreferences() {
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
doPreferenceGet('shared', successCb, failCb);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -64,3 +64,42 @@ svg + .button__label,
|
|||
.button__label + svg {
|
||||
margin-left: var(--spacing-small);
|
||||
}
|
||||
|
||||
.button-toggle {
|
||||
padding: 0 var(--spacing-medium);
|
||||
height: var(--height-button);
|
||||
font-size: var(--font-base);
|
||||
border: 1px solid var(--color-border);
|
||||
border-left-width: 0;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
|
||||
svg {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
border-left-width: 1px;
|
||||
border-top-left-radius: var(--border-radius);
|
||||
border-bottom-left-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-top-right-radius: var(--border-radius);
|
||||
border-bottom-right-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.button-toggle--active {
|
||||
color: var(--color-primary);
|
||||
background-color: var(--color-primary-alt);
|
||||
|
||||
svg {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: default;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
.claim-list__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 4.5rem;
|
||||
min-height: 6rem;
|
||||
padding: var(--spacing-medium);
|
||||
font-size: var(--font-body);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
|
@ -15,10 +15,6 @@
|
|||
border-top-left-radius: var(--card-radius);
|
||||
border-top-right-radius: var(--card-radius);
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
fieldset-section {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
|
@ -34,6 +30,7 @@
|
|||
margin-bottom: 0;
|
||||
padding: 0 var(--spacing-medium);
|
||||
padding-right: var(--spacing-large);
|
||||
margin-left: var(--spacing-medium);
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
font-size: var(--font-small);
|
||||
|
@ -42,6 +39,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.claim-list__header-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.claim-list__conjuction {
|
||||
color: var(--color-text-subtitle);
|
||||
font-size: var(--font-small);
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: var(--height-input);
|
||||
}
|
||||
|
||||
.header__menu {
|
||||
|
@ -113,7 +114,18 @@
|
|||
.header__navigation-item--back,
|
||||
.header__navigation-item--forward,
|
||||
.header__navigation-item--icon {
|
||||
width: 3rem;
|
||||
width: var(--height-button);
|
||||
background-color: var(--color-header-button);
|
||||
border-radius: 1.5rem;
|
||||
margin-left: var(--spacing-small);
|
||||
|
||||
svg {
|
||||
stroke: var(--color-text);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-primary-alt);
|
||||
}
|
||||
}
|
||||
|
||||
.header__navigation-item--lbry {
|
||||
|
@ -125,3 +137,7 @@
|
|||
width: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.header__navigation-item--balance {
|
||||
margin: 0 var(--spacing-medium);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.modal {
|
||||
@extend .card;
|
||||
background-color: var(--color-card-background);
|
||||
background-color: var(--color-modal-background);
|
||||
line-height: 1.55;
|
||||
min-width: 500px;
|
||||
max-width: var(--modal-width);
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.navigation__secondary {
|
||||
margin-top: var(--spacing-large);
|
||||
}
|
||||
|
||||
.navigation--placeholder {
|
||||
@extend .navigation;
|
||||
padding: 2rem 1.5rem;
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
@extend .tags;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin: 0;
|
||||
margin-top: var(--spacing-small);
|
||||
|
||||
li:last-child .tag {
|
||||
margin-bottom: 0;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
font-size: var(--font-small);
|
||||
height: var(--height-input);
|
||||
|
||||
> .icon {
|
||||
top: 0;
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
outline: none;
|
||||
background-color: var(--color-menu-background);
|
||||
border-top: none;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-reach-menu-item] {
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
// Generic html styles used across the App
|
||||
// component specific styling should go in the component scss file
|
||||
|
||||
.top-bid {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
background-color: var(--color-primary-alt);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
*::selection {
|
||||
background-color: var(--color-text-selection-bg);
|
||||
color: var(--color-text-selection);
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
/* #5a6570; - 25% */
|
||||
|
||||
[theme='dark'] {
|
||||
--color-primary-alt: #30574e;
|
||||
--color-primary: #60e1ba;
|
||||
--color-primary-alt: #3e675d;
|
||||
--color-primary: #74dfbf;
|
||||
|
||||
// Button
|
||||
--color-link: #38d9a9;
|
||||
--color-link: var(--color-primary);
|
||||
--color-link-hover: #60e1ba;
|
||||
--color-link-active: #60e1ba;
|
||||
--color-link-icon: #89939e;
|
||||
|
@ -21,6 +21,7 @@
|
|||
--color-button-secondary-bg: #395877;
|
||||
--color-button-secondary-bg-hover: #4b6d8f;
|
||||
--color-button-secondary-text: #a3c1e0;
|
||||
--color-header-button: var(--color-link-icon);
|
||||
|
||||
// Color
|
||||
--color-focus: #2d69a5;
|
||||
|
@ -34,6 +35,7 @@
|
|||
--color-tab-text: var(--color-white);
|
||||
--color-tabs-background: #434b53;
|
||||
--color-tab-divider: var(--color-white);
|
||||
--color-modal-background: var(--color-header-background);
|
||||
|
||||
// Text
|
||||
--color-text: #eeeeee;
|
||||
|
@ -49,7 +51,7 @@
|
|||
--color-input: #f4f4f5;
|
||||
--color-input-label: #d4d4d4;
|
||||
--color-input-placeholder: #f4f4f5;
|
||||
--color-input-bg: #7d8894;
|
||||
--color-input-bg: #5d6772;
|
||||
--color-input-bg-copyable: #434b53;
|
||||
--color-input-border: var(--color-border);
|
||||
--color-input-border-active: var(--color-secondary);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
:root {
|
||||
// Button
|
||||
--color-link-icon: var(--color-gray-5);
|
||||
--color-link-icon: var(--color-gray-4);
|
||||
--color-link-active: var(--color-primary);
|
||||
--color-navigation-link: var(--color-link-icon);
|
||||
--color-navigation-link: var(--color-gray-5);
|
||||
--color-header-button: #f7f7f7;
|
||||
|
||||
// Color
|
||||
--color-background: #f7f7f7;
|
||||
|
@ -34,6 +35,7 @@
|
|||
--color-file-viewer-background: var(--color-card-background);
|
||||
--color-tabs-background: var(--color-secondary-alt);
|
||||
--color-tab-divider: var(--color-secondary);
|
||||
--color-modal-background: var(--color-card-background);
|
||||
|
||||
// Menu
|
||||
--color-menu-background: var(--color-header-background);
|
||||
|
|
Loading…
Reference in a new issue