Merge pull request #2399 from lbryio/routing-updates
Update sidebar: combine history and downloads page
This commit is contained in:
commit
a31fd62e20
29 changed files with 316 additions and 212 deletions
|
@ -107,9 +107,11 @@ class Button extends React.PureComponent<Props> {
|
|||
to={path}
|
||||
title={title}
|
||||
onClick={e => e.stopPropagation()}
|
||||
getProps={({ isCurrent }) => ({
|
||||
getProps={({ isCurrent, isPartiallyCurrent }) => ({
|
||||
className:
|
||||
isCurrent && activeClass ? `${combinedClassName} ${activeClass}` : combinedClassName,
|
||||
(path === '/' ? isCurrent : isPartiallyCurrent) && activeClass
|
||||
? `${combinedClassName} ${activeClass}`
|
||||
: combinedClassName,
|
||||
})}
|
||||
>
|
||||
{content}
|
||||
|
|
|
@ -15,7 +15,7 @@ class CardMedia extends React.PureComponent<Props> {
|
|||
style={
|
||||
thumbnail
|
||||
? { backgroundImage: `url('${thumbnail}')` }
|
||||
: { backgroundImage: `url(${Placeholder})` }
|
||||
: { backgroundImage: `url(/${Placeholder})` }
|
||||
}
|
||||
className="media__thumb"
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import type { Node } from 'react';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React, { Fragment } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
type IconProps = {
|
||||
size: number,
|
||||
|
@ -8,7 +9,7 @@ type IconProps = {
|
|||
};
|
||||
|
||||
// Returns a react component
|
||||
const buildIcon = iconStrokes => (props: IconProps) => {
|
||||
const buildIcon = (iconStrokes: Node, options?: {} = {}) => (props: IconProps) => {
|
||||
const { size = 24, color = 'currentColor', ...otherProps } = props;
|
||||
return (
|
||||
<svg
|
||||
|
@ -16,11 +17,12 @@ const buildIcon = iconStrokes => (props: IconProps) => {
|
|||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
fill="solid"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
{...options}
|
||||
{...otherProps}
|
||||
>
|
||||
{iconStrokes}
|
||||
|
@ -114,16 +116,11 @@ export const customIcons = {
|
|||
[ICONS.UNSUBSCRIBE]: buildIcon(
|
||||
<path d="M 12,5.67 10.94,4.61 C 5.7533356,-0.57666427 -2.0266644,7.2033357 3.16,12.39 l 1.06,1.06 7.78,7.78 7.78,-7.78 1.06,-1.06 c 2.149101,-2.148092 2.149101,-5.6319078 0,-7.78 -2.148092,-2.1491008 -5.631908,-2.1491008 -7.78,0 L 9.4481298,8.2303201 15.320603,9.2419066 11.772427,13.723825" />
|
||||
),
|
||||
[ICONS.LBRY]: buildIcon(
|
||||
<Fragment>
|
||||
<path
|
||||
transform="scale(0.15)"
|
||||
d="M296.05, 85.9l0, 14.1l-138.8, 85.3l-104.6, -51.3l0.2, -7.9l104, 51.2l132.2, -81.2l0, -5.8l-124.8, -60.2l-139.2, 86.1l0, 38.5l131.8, 65.2l137.6, -84.4l3.9, 6l-141.1, 86.4l-139.2, -68.8l0, -46.8l145.8, -90.2l132.2, 63.8Z"
|
||||
/>
|
||||
<path
|
||||
transform="scale(0.15)"
|
||||
d="M294.25, 150.9l2, -12.6l-12.2, -2.1l0.8, -4.9l17.1, 2.9l-2.8, 17.5l-4.9, -0.8Z"
|
||||
/>
|
||||
</Fragment>
|
||||
// The LBRY icon is different from the base icon set so don't use buildIcon()
|
||||
[ICONS.LBRY]: props => (
|
||||
<svg stroke="currentColor" fill="currentColor" transform="scale(0.1)" {...props}>
|
||||
<path d="M296.05, 85.9l0, 14.1l-138.8, 85.3l-104.6, -51.3l0.2, -7.9l104, 51.2l132.2, -81.2l0, -5.8l-124.8, -60.2l-139.2, 86.1l0, 38.5l131.8, 65.2l137.6, -84.4l3.9, 6l-141.1, 86.4l-139.2, -68.8l0, -46.8l145.8, -90.2l132.2, 63.8Z" />
|
||||
<path d="M294.25, 150.9l2, -12.6l-12.2, -2.1l0.8, -4.9l17.1, 2.9l-2.8, 17.5l-4.9, -0.8Z" />
|
||||
</svg>
|
||||
),
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import Tooltip from 'component/common/tooltip';
|
||||
import classnames from 'classnames';
|
||||
import { customIcons } from './icon-custom';
|
||||
|
||||
let featherIcons = false;
|
||||
|
@ -35,6 +36,7 @@ type Props = {
|
|||
tooltip?: string, // tooltip direction
|
||||
iconColor?: string,
|
||||
size?: number,
|
||||
className?: string,
|
||||
};
|
||||
|
||||
class IconComponent extends React.PureComponent<Props> {
|
||||
|
@ -63,7 +65,7 @@ class IconComponent extends React.PureComponent<Props> {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { icon, tooltip, iconColor, size } = this.props;
|
||||
const { icon, tooltip, iconColor, size, className } = this.props;
|
||||
const Icon = customIcons[this.props.icon] || LazyFeatherIcons[this.props.icon];
|
||||
|
||||
if (!Icon) {
|
||||
|
@ -83,9 +85,16 @@ class IconComponent extends React.PureComponent<Props> {
|
|||
}
|
||||
const inner = (
|
||||
<React.Suspense
|
||||
fallback={<svg height={iconSize} width={iconSize} className="icon" color={color} />}
|
||||
fallback={
|
||||
<svg
|
||||
height={iconSize}
|
||||
width={iconSize}
|
||||
className={classnames('icon', className)}
|
||||
color={color}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Icon size={iconSize} className="icon" color={color} />
|
||||
<Icon size={iconSize} className={classnames('icon', className)} color={color} />
|
||||
</React.Suspense>
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as React from 'react';
|
|||
import Button from 'component/button';
|
||||
import LbcSymbol from 'component/common/lbc-symbol';
|
||||
import WunderBar from 'component/wunderbar';
|
||||
import Icon from 'component/common/icon';
|
||||
|
||||
type Props = {
|
||||
autoUpdateDownloaded: boolean,
|
||||
|
@ -37,42 +38,26 @@ const Header = (props: Props) => {
|
|||
<header className="header">
|
||||
<div className="header__navigation">
|
||||
{/* @if TARGET='app' */}
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--wallet"
|
||||
description={__('Your wallet')}
|
||||
title={`Your balance is ${balance} LBRY Credits`}
|
||||
label={
|
||||
<React.Fragment>
|
||||
<span>{roundedBalance}</span>
|
||||
<LbcSymbol />
|
||||
</React.Fragment>
|
||||
}
|
||||
navigate="/$/wallet"
|
||||
/>
|
||||
<div className="header__navigation-app">
|
||||
<Icon className="lbry-icon" icon={ICONS.LBRY} />
|
||||
<div className="header__navigation-arrows">
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--back"
|
||||
description={__('Navigate back')}
|
||||
onClick={() => window.history.back()}
|
||||
icon={ICONS.ARROW_LEFT}
|
||||
iconSize={15}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--back"
|
||||
description={__('Navigate back')}
|
||||
onClick={() => window.history.back()}
|
||||
icon={ICONS.ARROW_LEFT}
|
||||
iconSize={15}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--forward"
|
||||
description={__('Navigate forward')}
|
||||
onClick={() => window.history.forward()}
|
||||
icon={ICONS.ARROW_RIGHT}
|
||||
iconSize={15}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--home"
|
||||
description={__('Home')}
|
||||
icon={ICONS.HOME}
|
||||
iconSize={15}
|
||||
navigate="/"
|
||||
/>
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--forward"
|
||||
description={__('Navigate forward')}
|
||||
onClick={() => window.history.forward()}
|
||||
icon={ICONS.ARROW_RIGHT}
|
||||
iconSize={15}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* @endif */}
|
||||
{/* @if TARGET='web' */}
|
||||
<Button
|
||||
|
@ -94,6 +79,19 @@ const Header = (props: Props) => {
|
|||
iconSize={15}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--wallet"
|
||||
description={__('Your wallet')}
|
||||
title={`Your balance is ${balance} LBRY Credits`}
|
||||
label={
|
||||
<React.Fragment>
|
||||
<span>{roundedBalance}</span>
|
||||
<LbcSymbol />
|
||||
</React.Fragment>
|
||||
}
|
||||
navigate="/$/wallet"
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="header__navigation-item header__navigation-item--right-action"
|
||||
description={__('Publish content')}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content';
|
||||
import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux';
|
||||
import { doClearContentHistoryUri } from 'redux/actions/content';
|
||||
import UserHistory from './view';
|
||||
|
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
|||
import Button from 'component/button';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import ReactPaginate from 'react-paginate';
|
||||
import UserHistoryItem from 'component/userHistoryItem';
|
||||
import NavigationHistoryItem from 'component/navigationHistoryItem';
|
||||
import { navigate } from '@reach/router';
|
||||
|
||||
type HistoryItem = {
|
||||
|
@ -52,8 +52,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
changePage(pageNumber: number) {
|
||||
console.log('new', pageNumber);
|
||||
navigate(`/$/user_history?page=${pageNumber}`);
|
||||
navigate(`?page=${pageNumber}`);
|
||||
}
|
||||
|
||||
paginate(e: SyntheticKeyboardEvent<*>) {
|
||||
|
@ -94,7 +93,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
|
||||
render() {
|
||||
const { history = [], page, pageCount } = this.props;
|
||||
console.log('this.props', this.props);
|
||||
|
||||
const { itemsSelected } = this.state;
|
||||
const allSelected = Object.keys(itemsSelected).length === history.length;
|
||||
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
||||
|
@ -118,7 +117,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
{!!history.length && (
|
||||
<section className="card__content item-list">
|
||||
{history.map(item => (
|
||||
<UserHistoryItem
|
||||
<NavigationHistoryItem
|
||||
key={item.uri}
|
||||
uri={item.uri}
|
||||
lastViewed={item.lastViewed}
|
68
src/ui/component/navigationHistoryItem/view.jsx
Normal file
68
src/ui/component/navigationHistoryItem/view.jsx
Normal file
|
@ -0,0 +1,68 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import type { Claim } from 'types/claim';
|
||||
import moment from 'moment';
|
||||
import classnames from 'classnames';
|
||||
import Button from 'component/button';
|
||||
import { FormField } from 'component/common/form';
|
||||
import { navigate } from '@reach/router';
|
||||
import { formatLbryUriForWeb } from 'util/uri';
|
||||
|
||||
type Props = {
|
||||
lastViewed: number,
|
||||
uri: string,
|
||||
claim: ?Claim,
|
||||
selected: boolean,
|
||||
onSelect?: () => void,
|
||||
resolveUri: string => void,
|
||||
slim: boolean,
|
||||
};
|
||||
|
||||
class NavigationHistoryItem extends React.PureComponent<Props> {
|
||||
static defaultProps = {
|
||||
slim: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { claim, uri, resolveUri } = this.props;
|
||||
|
||||
if (!claim) {
|
||||
resolveUri(uri);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { lastViewed, selected, onSelect, claim, uri, slim } = this.props;
|
||||
|
||||
let name;
|
||||
let title;
|
||||
if (claim && claim.value && claim.value.stream) {
|
||||
({ name } = claim);
|
||||
({ title } = claim.value.stream.metadata);
|
||||
}
|
||||
|
||||
const navigatePath = formatLbryUriForWeb(uri);
|
||||
const onClick =
|
||||
onSelect ||
|
||||
function() {
|
||||
navigate(navigatePath);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
onClick={onClick}
|
||||
className={classnames('item-list__row', {
|
||||
'item-list__row--selected': selected,
|
||||
})}
|
||||
>
|
||||
{!slim && <FormField checked={selected} type="checkbox" onChange={onSelect} />}
|
||||
<span className="time time--ago">{moment(lastViewed).from(moment())}</span>
|
||||
<Button className="item-list__element" constrict button="link" label={uri} navigate={uri} />
|
||||
<span className="item-list__element">{title}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NavigationHistoryItem;
|
12
src/ui/component/navigationHistoryRecent/index.js
Normal file
12
src/ui/component/navigationHistoryRecent/index.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectRecentHistory } from 'redux/selectors/content';
|
||||
import RecentUserHistory from './view';
|
||||
|
||||
const select = (state, props) => ({
|
||||
history: selectRecentHistory(state),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
null
|
||||
)(RecentUserHistory);
|
37
src/ui/component/navigationHistoryRecent/view.jsx
Normal file
37
src/ui/component/navigationHistoryRecent/view.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
// @flow
|
||||
import React, { Fragment } from 'react';
|
||||
import Button from 'component/button';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import ReactPaginate from 'react-paginate';
|
||||
import NavigationHistoryItem from 'component/navigationHistoryItem';
|
||||
import { navigate } from '@reach/router';
|
||||
|
||||
type HistoryItem = {
|
||||
uri: string,
|
||||
lastViewed: number,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
history: Array<HistoryItem>,
|
||||
page: number,
|
||||
pageCount: number,
|
||||
clearHistoryUri: string => void,
|
||||
params: { page: number },
|
||||
};
|
||||
|
||||
export default function UserHistoryRecent(props: Props) {
|
||||
const { history = [], page, pageCount } = props;
|
||||
|
||||
return history.length ? (
|
||||
<div className="item-list">
|
||||
<section className="card__content">
|
||||
{history.map(({ lastViewed, uri }) => (
|
||||
<NavigationHistoryItem slim key={uri} uri={uri} lastViewed={lastViewed} />
|
||||
))}
|
||||
</section>
|
||||
<div className="card__actions">
|
||||
<Button navigate="/$/history/all" button="link" label={__('See All Visited Links')} />
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
}
|
|
@ -4,7 +4,7 @@ import { Router } from '@reach/router';
|
|||
import SettingsPage from 'page/settings';
|
||||
import HelpPage from 'page/help';
|
||||
import ReportPage from 'page/report';
|
||||
import WalletPage from 'page/wallet';
|
||||
import AccountPage from 'page/account';
|
||||
import ShowPage from 'page/show';
|
||||
import PublishPage from 'page/publish';
|
||||
import DiscoverPage from 'page/discover';
|
||||
|
@ -18,6 +18,8 @@ import BackupPage from 'page/backup';
|
|||
import SubscriptionsPage from 'page/subscriptions';
|
||||
import SearchPage from 'page/search';
|
||||
import UserHistoryPage from 'page/userHistory';
|
||||
import SendCreditsPage from 'page/sendCredits';
|
||||
import NavigationHistory from 'page/navigationHistory';
|
||||
|
||||
export default function AppRouter(props) {
|
||||
return (
|
||||
|
@ -38,9 +40,12 @@ export default function AppRouter(props) {
|
|||
<SearchPage path={`$/${PAGES.SEARCH}`} />
|
||||
<SettingsPage path={`$/${PAGES.SETTINGS}`} />
|
||||
<SubscriptionsPage path={`$/${PAGES.SUBSCRIPTIONS}`} />
|
||||
<TransactionHistoryPage path={`$/${PAGES.HISTORY}`} />
|
||||
<UserHistoryPage path={`$/${PAGES.USER_HISTORY}`} />
|
||||
<WalletPage path={`$/${PAGES.WALLET}`} />
|
||||
<TransactionHistoryPage path={`$/${PAGES.TRANSACTIONS}`} />
|
||||
<UserHistoryPage path={`$/${PAGES.HISTORY}`} />
|
||||
<AccountPage path={`$/${PAGES.ACCOUNT}`} />
|
||||
<SendCreditsPage path={`$/${PAGES.SEND}`} />
|
||||
<UserHistoryPage path={`$/${PAGES.HISTORY}`} />
|
||||
<NavigationHistory path={`$/${PAGES.HISTORY}/all`} />
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class SideBar extends React.PureComponent<Props> {
|
|||
<ul className="navigation__links">
|
||||
{[
|
||||
{
|
||||
...buildLink(null, __('Home'), ICONS.HOME),
|
||||
...buildLink(null, __('Discover'), ICONS.DISCOVER),
|
||||
},
|
||||
{
|
||||
...buildLink(
|
||||
|
@ -54,53 +54,46 @@ class SideBar extends React.PureComponent<Props> {
|
|||
ICONS.SUBSCRIPTION
|
||||
),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.PUBLISHED, 'Publishes', ICONS.PUBLISHED),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.HISTORY, 'History', ICONS.HISTORY),
|
||||
},
|
||||
].map(renderLink)}
|
||||
</ul>
|
||||
|
||||
<div className="navigation__link navigation__link--title">My LBRY</div>
|
||||
|
||||
<div className="navigation__links">
|
||||
<ul>
|
||||
{[
|
||||
{
|
||||
...buildLink(PAGES.DOWNLOADED, 'Downloads', ICONS.LOCAL),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.PUBLISHED, 'Publishes', ICONS.PUBLISHED),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.USER_HISTORY, 'History', ICONS.HISTORY),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.INVITE, 'Invite', ICONS.INVITE),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.REWARDS, 'Rewards', ICONS.FEATURED),
|
||||
},
|
||||
].map(renderLink)}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="navigation__link navigation__link--title">Wallet</div>
|
||||
<div className="navigation__link navigation__link--title">Account</div>
|
||||
|
||||
<ul className="navigation__links">
|
||||
{[
|
||||
{
|
||||
...buildLink(PAGES.WALLET, 'Overview', ICONS.WALLET),
|
||||
...buildLink(PAGES.ACCOUNT, 'Overview', ICONS.ACCOUNT),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.HISTORY, 'Transactions', ICONS.TRANSACTIONS),
|
||||
...buildLink(PAGES.INVITE, 'Invite', ICONS.INVITE),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.REWARDS, 'Rewards', ICONS.FEATURED),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.SEND, 'Send & Recieve', ICONS.SEND),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.TRANSACTIONS, 'Transactions', ICONS.TRANSACTIONS),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.SETTINGS, 'Settings', ICONS.SETTINGS),
|
||||
},
|
||||
// @if TARGET='app'
|
||||
{
|
||||
...buildLink(PAGES.BACKUP, 'Backup', ICONS.BACKUP),
|
||||
},
|
||||
// @endif
|
||||
].map(renderLink)}
|
||||
</ul>
|
||||
|
||||
<ul className="navigation__links navigation__links--bottom">
|
||||
{[
|
||||
{
|
||||
...buildLink(PAGES.SETTINGS, 'Settings', ICONS.SETTINGS),
|
||||
},
|
||||
{
|
||||
...buildLink(PAGES.HELP, 'Help', ICONS.HELP),
|
||||
},
|
||||
|
|
|
@ -35,7 +35,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
|
|||
|
||||
<p className="card__subtitle">
|
||||
{__('To view all of your transactions, navigate to the')}{' '}
|
||||
<Button button="link" navigate="/$/history" label={__('transactions page')} />.
|
||||
<Button button="link" navigate="/$/transactions" label={__('transactions page')} />.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
|
@ -57,7 +57,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
|
|||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
navigate="/$/history"
|
||||
navigate="/$/transactions"
|
||||
label={__('Full History')}
|
||||
icon={icons.HISTORY}
|
||||
/>
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import type { Claim } from 'types/claim';
|
||||
import moment from 'moment';
|
||||
import classnames from 'classnames';
|
||||
import Button from 'component/button';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
type Props = {
|
||||
lastViewed: number,
|
||||
uri: string,
|
||||
claim: ?Claim,
|
||||
selected: boolean,
|
||||
onSelect: () => void,
|
||||
resolveUri: string => void,
|
||||
};
|
||||
|
||||
class UserHistoryItem extends React.PureComponent<Props> {
|
||||
componentDidMount() {
|
||||
const { claim, uri, resolveUri } = this.props;
|
||||
|
||||
if (!claim) {
|
||||
resolveUri(uri);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { lastViewed, selected, onSelect, claim } = this.props;
|
||||
|
||||
let name;
|
||||
let title;
|
||||
let uri;
|
||||
if (claim && claim.value && claim.value.stream) {
|
||||
({ name } = claim);
|
||||
({ title } = claim.value.stream.metadata);
|
||||
uri = claim.permanent_url;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
onClick={onSelect}
|
||||
className={classnames('item-list__item', {
|
||||
'item-list__item--selected': selected,
|
||||
})}
|
||||
>
|
||||
<FormField checked={selected} type="checkbox" onChange={onSelect} />
|
||||
<span className="time time--ago">{moment(lastViewed).from(moment())}</span>
|
||||
<span className="item-list__item--cutoff">{title}</span>
|
||||
<Button
|
||||
constrict
|
||||
button="link"
|
||||
label={name ? `lbry://${name}` : `lbry://...`}
|
||||
navigate={uri}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default UserHistoryItem;
|
|
@ -1 +0,0 @@
|
|||
export const HISTORY_ITEMS_PER_PAGE = 50;
|
|
@ -37,7 +37,7 @@ export const VIEW = 'Eye';
|
|||
export const PLAY = 'Play';
|
||||
export const FACEBOOK = 'Facebook';
|
||||
export const TWITTER = 'Twitter';
|
||||
export const WALLET = 'CreditCard';
|
||||
export const ACCOUNT = 'User';
|
||||
export const SETTINGS = 'Settings';
|
||||
export const INVITE = 'Users';
|
||||
export const FILE = 'File';
|
||||
|
@ -51,3 +51,5 @@ export const MENU = 'Menu';
|
|||
export const BACKUP = 'Database';
|
||||
export const TRANSACTIONS = 'FileText';
|
||||
export const LBRY = 'Lbry';
|
||||
export const SEND = 'Send';
|
||||
export const DISCOVER = 'Compass';
|
||||
|
|
|
@ -14,7 +14,7 @@ export const REWARDS = 'rewards';
|
|||
export const SEND = 'send';
|
||||
export const SETTINGS = 'settings';
|
||||
export const SHOW = 'show';
|
||||
export const WALLET = 'wallet';
|
||||
export const ACCOUNT = 'account';
|
||||
export const SUBSCRIPTIONS = 'subscriptions';
|
||||
export const SEARCH = 'search';
|
||||
export const USER_HISTORY = 'user_history';
|
||||
export const TRANSACTIONS = 'transactions';
|
||||
|
|
|
@ -17,7 +17,9 @@ class FileListDownloaded extends React.PureComponent<Props> {
|
|||
const hasDownloads = fileInfos && Object.values(fileInfos).length > 0;
|
||||
|
||||
return (
|
||||
<Page notContained loading={fetching}>
|
||||
// Removed the <Page> wapper to try combining this page with UserHistory
|
||||
// This should eventually move into /components if we want to keep it this way
|
||||
<React.Fragment>
|
||||
{hasDownloads ? (
|
||||
<FileList fileInfos={fileInfos} sortBy={sortBy} page={PAGES.DOWNLOADED} />
|
||||
) : (
|
||||
|
@ -37,7 +39,7 @@ class FileListDownloaded extends React.PureComponent<Props> {
|
|||
</section>
|
||||
</div>
|
||||
)}
|
||||
</Page>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
3
src/ui/page/navigationHistory/index.js
Normal file
3
src/ui/page/navigationHistory/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import UserHistoryPage from './view';
|
||||
|
||||
export default UserHistoryPage;
|
13
src/ui/page/navigationHistory/view.jsx
Normal file
13
src/ui/page/navigationHistory/view.jsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import NavigationHistory from 'component/navigationHistory';
|
||||
|
||||
export default function NavigationHistoryPage(props: any) {
|
||||
// Pass `props` into the component for reach router props
|
||||
return (
|
||||
<Page>
|
||||
<NavigationHistory {...props} />
|
||||
</Page>
|
||||
);
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import UserHistory from 'component/userHistory';
|
||||
import UserHistory from 'component/navigationHistoryRecent';
|
||||
import DownloadList from 'page/fileListDownloaded';
|
||||
|
||||
type Props = {};
|
||||
|
||||
|
@ -10,6 +11,7 @@ class UserHistoryPage extends React.PureComponent<Props> {
|
|||
return (
|
||||
<Page>
|
||||
<UserHistory {...this.props} />
|
||||
<DownloadList {...this.props} />
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ import {
|
|||
selectClaimsByUri,
|
||||
makeSelectClaimsInChannelForCurrentPageState,
|
||||
} from 'lbry-redux';
|
||||
import { HISTORY_ITEMS_PER_PAGE } from 'constants/content';
|
||||
|
||||
const RECENT_HISTORY_AMOUNT = 10;
|
||||
const HISTORY_ITEMS_PER_PAGE = 50;
|
||||
|
||||
export const selectState = (state: any) => state.content || {};
|
||||
|
||||
|
@ -33,39 +35,40 @@ export const makeSelectContentPositionForUri = (uri: string) =>
|
|||
}
|
||||
);
|
||||
|
||||
export const selectHistoryPageCount = createSelector(
|
||||
export const selectHistory = createSelector(
|
||||
selectState,
|
||||
state => Math.ceil(state.history.length / HISTORY_ITEMS_PER_PAGE)
|
||||
state => state.history || []
|
||||
);
|
||||
|
||||
export const selectHistoryPageCount = createSelector(
|
||||
selectHistory,
|
||||
history => Math.ceil(history.length / HISTORY_ITEMS_PER_PAGE)
|
||||
);
|
||||
|
||||
export const makeSelectHistoryForPage = (page: number) =>
|
||||
createSelector(
|
||||
selectState,
|
||||
selectHistory,
|
||||
selectClaimsByUri,
|
||||
(state, claimsByUri) => {
|
||||
(history, claimsByUri) => {
|
||||
const left = page * HISTORY_ITEMS_PER_PAGE;
|
||||
const historyItems = state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
||||
|
||||
// See if we have the claim info for the uris in your history
|
||||
// If not, it will need to be fetched in the component
|
||||
return historyItems.map(historyItem => {
|
||||
const { uri, lastViewed } = historyItem;
|
||||
const claimAtUri = claimsByUri[uri];
|
||||
|
||||
if (claimAtUri) {
|
||||
return { lastViewed, uri, ...claimAtUri };
|
||||
}
|
||||
return historyItem;
|
||||
});
|
||||
const historyItemsForPage = history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
||||
return historyItemsForPage;
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectHistoryForUri = (uri: string) =>
|
||||
createSelector(
|
||||
selectState,
|
||||
state => state.history.find(i => i.uri === uri)
|
||||
selectHistory,
|
||||
history => history.find(i => i.uri === uri)
|
||||
);
|
||||
|
||||
export const selectRecentHistory = createSelector(
|
||||
selectHistory,
|
||||
history => {
|
||||
return history.slice(0, RECENT_HISTORY_AMOUNT);
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectCategoryListUris = (uris: ?Array<string>, channel: string) =>
|
||||
createSelector(
|
||||
makeSelectClaimsInChannelForCurrentPageState(channel),
|
||||
|
|
|
@ -19,20 +19,10 @@
|
|||
display: flex;
|
||||
|
||||
&:first-of-type {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
|
||||
// Main navigation collapses into a menu button
|
||||
// at smaller screen widths
|
||||
|
||||
@media (min-width: 601px) {
|
||||
/* @if TARGET='app' */
|
||||
width: 250px;
|
||||
/* @endif */
|
||||
/* @if TARGET='web' */
|
||||
width: 170px;
|
||||
/* @endif */
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
|
@ -41,6 +31,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
.header__navigation-app {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
// LBRY logo in the top left corner
|
||||
.lbry-icon {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
padding-left: 3.5rem;
|
||||
padding-top: 1.5rem;
|
||||
margin-right: 3.6rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.header__navigation-arrows {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-left: 1px solid $lbry-gray-1;
|
||||
}
|
||||
}
|
||||
|
||||
.header__navigation-item {
|
||||
height: var(--header-height);
|
||||
display: flex;
|
||||
|
@ -73,6 +86,7 @@
|
|||
.header__navigation-item--home,
|
||||
.header__navigation-item--menu {
|
||||
width: var(--header-height);
|
||||
|
||||
svg {
|
||||
&:only-child {
|
||||
// Header icons are a little different because they are larger
|
||||
|
@ -95,7 +109,7 @@
|
|||
overflow: visible;
|
||||
color: $lbry-white;
|
||||
opacity: 1;
|
||||
top: -0.2rem;
|
||||
top: -0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +144,7 @@
|
|||
|
||||
.header__navigation-item--wallet {
|
||||
border-right: 1px solid $lbry-gray-1;
|
||||
width: calc(100% - (var(--header-height) * 3));
|
||||
width: 10rem;
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-5;
|
||||
|
|
|
@ -1,37 +1,42 @@
|
|||
.item-list {
|
||||
background-color: $lbry-white;
|
||||
margin-top: var(--spacing-vertical-large);
|
||||
margin-bottom: var(--spacing-vertical-large);
|
||||
padding: var(--spacing-vertical-large);
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
|
||||
.card__actions {
|
||||
margin-top: var(--spacing-vertical-medium);
|
||||
margin-left: var(--spacing-vertical-small);
|
||||
}
|
||||
}
|
||||
|
||||
.item-list__item {
|
||||
.item-list__row {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: var(--spacing-vertical-small);
|
||||
|
||||
input,
|
||||
.item-list__item--cutoff {
|
||||
margin-right: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
fieldset-section {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.item-list__item--cutoff {
|
||||
max-width: 350px;
|
||||
.item-list__element {
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(:first-of-type) {
|
||||
padding-left: var(--spacing-vertical-small);
|
||||
}
|
||||
}
|
||||
|
||||
.item-list__item--selected {
|
||||
background-color: $lbry-gray-1;
|
||||
.item-list__row:hover,
|
||||
.item-list__row--selected {
|
||||
background-color: rgba($lbry-black, 0.1);
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-black, 0.5);
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
padding-top: var(--spacing-vertical-large);
|
||||
padding-right: var(--spacing-vertical-small);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: overlay;
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-black;
|
||||
|
@ -15,7 +18,7 @@
|
|||
// on smaller screen widths
|
||||
|
||||
@media (min-width: 601px) {
|
||||
min-width: 171px; // 1px is for the border
|
||||
width: 171px; // 1px is for the border
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
|
@ -53,8 +56,8 @@
|
|||
}
|
||||
|
||||
.navigation__links--bottom {
|
||||
position: absolute;
|
||||
bottom: var(--spacing-vertical-large);
|
||||
margin-top: auto;
|
||||
margin-bottom: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
.navigation__link {
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
}
|
||||
|
||||
.time--ago {
|
||||
min-width: 160px;
|
||||
min-width: 140px;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue