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}
|
to={path}
|
||||||
title={title}
|
title={title}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
getProps={({ isCurrent }) => ({
|
getProps={({ isCurrent, isPartiallyCurrent }) => ({
|
||||||
className:
|
className:
|
||||||
isCurrent && activeClass ? `${combinedClassName} ${activeClass}` : combinedClassName,
|
(path === '/' ? isCurrent : isPartiallyCurrent) && activeClass
|
||||||
|
? `${combinedClassName} ${activeClass}`
|
||||||
|
: combinedClassName,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class CardMedia extends React.PureComponent<Props> {
|
||||||
style={
|
style={
|
||||||
thumbnail
|
thumbnail
|
||||||
? { backgroundImage: `url('${thumbnail}')` }
|
? { backgroundImage: `url('${thumbnail}')` }
|
||||||
: { backgroundImage: `url(${Placeholder})` }
|
: { backgroundImage: `url(/${Placeholder})` }
|
||||||
}
|
}
|
||||||
className="media__thumb"
|
className="media__thumb"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import type { Node } from 'react';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
type IconProps = {
|
type IconProps = {
|
||||||
size: number,
|
size: number,
|
||||||
|
@ -8,7 +9,7 @@ type IconProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a react component
|
// Returns a react component
|
||||||
const buildIcon = iconStrokes => (props: IconProps) => {
|
const buildIcon = (iconStrokes: Node, options?: {} = {}) => (props: IconProps) => {
|
||||||
const { size = 24, color = 'currentColor', ...otherProps } = props;
|
const { size = 24, color = 'currentColor', ...otherProps } = props;
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
|
@ -16,11 +17,12 @@ const buildIcon = iconStrokes => (props: IconProps) => {
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
fill="solid"
|
fill="none"
|
||||||
stroke={color}
|
stroke={color}
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
|
{...options}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
>
|
>
|
||||||
{iconStrokes}
|
{iconStrokes}
|
||||||
|
@ -114,16 +116,11 @@ export const customIcons = {
|
||||||
[ICONS.UNSUBSCRIBE]: buildIcon(
|
[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" />
|
<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(
|
// The LBRY icon is different from the base icon set so don't use buildIcon()
|
||||||
<Fragment>
|
[ICONS.LBRY]: props => (
|
||||||
<path
|
<svg stroke="currentColor" fill="currentColor" transform="scale(0.1)" {...props}>
|
||||||
transform="scale(0.15)"
|
<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" />
|
||||||
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>
|
||||||
<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>
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Tooltip from 'component/common/tooltip';
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
import classnames from 'classnames';
|
||||||
import { customIcons } from './icon-custom';
|
import { customIcons } from './icon-custom';
|
||||||
|
|
||||||
let featherIcons = false;
|
let featherIcons = false;
|
||||||
|
@ -35,6 +36,7 @@ type Props = {
|
||||||
tooltip?: string, // tooltip direction
|
tooltip?: string, // tooltip direction
|
||||||
iconColor?: string,
|
iconColor?: string,
|
||||||
size?: number,
|
size?: number,
|
||||||
|
className?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
class IconComponent extends React.PureComponent<Props> {
|
class IconComponent extends React.PureComponent<Props> {
|
||||||
|
@ -63,7 +65,7 @@ class IconComponent extends React.PureComponent<Props> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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];
|
const Icon = customIcons[this.props.icon] || LazyFeatherIcons[this.props.icon];
|
||||||
|
|
||||||
if (!Icon) {
|
if (!Icon) {
|
||||||
|
@ -83,9 +85,16 @@ class IconComponent extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
const inner = (
|
const inner = (
|
||||||
<React.Suspense
|
<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>
|
</React.Suspense>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import * as React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import LbcSymbol from 'component/common/lbc-symbol';
|
import LbcSymbol from 'component/common/lbc-symbol';
|
||||||
import WunderBar from 'component/wunderbar';
|
import WunderBar from 'component/wunderbar';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
autoUpdateDownloaded: boolean,
|
autoUpdateDownloaded: boolean,
|
||||||
|
@ -37,19 +38,9 @@ const Header = (props: Props) => {
|
||||||
<header className="header">
|
<header className="header">
|
||||||
<div className="header__navigation">
|
<div className="header__navigation">
|
||||||
{/* @if TARGET='app' */}
|
{/* @if TARGET='app' */}
|
||||||
<Button
|
<div className="header__navigation-app">
|
||||||
className="header__navigation-item header__navigation-item--wallet"
|
<Icon className="lbry-icon" icon={ICONS.LBRY} />
|
||||||
description={__('Your wallet')}
|
<div className="header__navigation-arrows">
|
||||||
title={`Your balance is ${balance} LBRY Credits`}
|
|
||||||
label={
|
|
||||||
<React.Fragment>
|
|
||||||
<span>{roundedBalance}</span>
|
|
||||||
<LbcSymbol />
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
navigate="/$/wallet"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="header__navigation-item header__navigation-item--back"
|
className="header__navigation-item header__navigation-item--back"
|
||||||
description={__('Navigate back')}
|
description={__('Navigate back')}
|
||||||
|
@ -65,14 +56,8 @@ const Header = (props: Props) => {
|
||||||
icon={ICONS.ARROW_RIGHT}
|
icon={ICONS.ARROW_RIGHT}
|
||||||
iconSize={15}
|
iconSize={15}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<Button
|
</div>
|
||||||
className="header__navigation-item header__navigation-item--home"
|
|
||||||
description={__('Home')}
|
|
||||||
icon={ICONS.HOME}
|
|
||||||
iconSize={15}
|
|
||||||
navigate="/"
|
|
||||||
/>
|
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
{/* @if TARGET='web' */}
|
{/* @if TARGET='web' */}
|
||||||
<Button
|
<Button
|
||||||
|
@ -94,6 +79,19 @@ const Header = (props: Props) => {
|
||||||
iconSize={15}
|
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
|
<Button
|
||||||
className="header__navigation-item header__navigation-item--right-action"
|
className="header__navigation-item header__navigation-item--right-action"
|
||||||
description={__('Publish content')}
|
description={__('Publish content')}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content';
|
import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content';
|
||||||
import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux';
|
|
||||||
import { doClearContentHistoryUri } from 'redux/actions/content';
|
import { doClearContentHistoryUri } from 'redux/actions/content';
|
||||||
import UserHistory from './view';
|
import UserHistory from './view';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import { Form, FormField } from 'component/common/form';
|
import { Form, FormField } from 'component/common/form';
|
||||||
import ReactPaginate from 'react-paginate';
|
import ReactPaginate from 'react-paginate';
|
||||||
import UserHistoryItem from 'component/userHistoryItem';
|
import NavigationHistoryItem from 'component/navigationHistoryItem';
|
||||||
import { navigate } from '@reach/router';
|
import { navigate } from '@reach/router';
|
||||||
|
|
||||||
type HistoryItem = {
|
type HistoryItem = {
|
||||||
|
@ -52,8 +52,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
changePage(pageNumber: number) {
|
changePage(pageNumber: number) {
|
||||||
console.log('new', pageNumber);
|
navigate(`?page=${pageNumber}`);
|
||||||
navigate(`/$/user_history?page=${pageNumber}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paginate(e: SyntheticKeyboardEvent<*>) {
|
paginate(e: SyntheticKeyboardEvent<*>) {
|
||||||
|
@ -94,7 +93,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { history = [], page, pageCount } = this.props;
|
const { history = [], page, pageCount } = this.props;
|
||||||
console.log('this.props', this.props);
|
|
||||||
const { itemsSelected } = this.state;
|
const { itemsSelected } = this.state;
|
||||||
const allSelected = Object.keys(itemsSelected).length === history.length;
|
const allSelected = Object.keys(itemsSelected).length === history.length;
|
||||||
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
||||||
|
@ -118,7 +117,7 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
||||||
{!!history.length && (
|
{!!history.length && (
|
||||||
<section className="card__content item-list">
|
<section className="card__content item-list">
|
||||||
{history.map(item => (
|
{history.map(item => (
|
||||||
<UserHistoryItem
|
<NavigationHistoryItem
|
||||||
key={item.uri}
|
key={item.uri}
|
||||||
uri={item.uri}
|
uri={item.uri}
|
||||||
lastViewed={item.lastViewed}
|
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 SettingsPage from 'page/settings';
|
||||||
import HelpPage from 'page/help';
|
import HelpPage from 'page/help';
|
||||||
import ReportPage from 'page/report';
|
import ReportPage from 'page/report';
|
||||||
import WalletPage from 'page/wallet';
|
import AccountPage from 'page/account';
|
||||||
import ShowPage from 'page/show';
|
import ShowPage from 'page/show';
|
||||||
import PublishPage from 'page/publish';
|
import PublishPage from 'page/publish';
|
||||||
import DiscoverPage from 'page/discover';
|
import DiscoverPage from 'page/discover';
|
||||||
|
@ -18,6 +18,8 @@ import BackupPage from 'page/backup';
|
||||||
import SubscriptionsPage from 'page/subscriptions';
|
import SubscriptionsPage from 'page/subscriptions';
|
||||||
import SearchPage from 'page/search';
|
import SearchPage from 'page/search';
|
||||||
import UserHistoryPage from 'page/userHistory';
|
import UserHistoryPage from 'page/userHistory';
|
||||||
|
import SendCreditsPage from 'page/sendCredits';
|
||||||
|
import NavigationHistory from 'page/navigationHistory';
|
||||||
|
|
||||||
export default function AppRouter(props) {
|
export default function AppRouter(props) {
|
||||||
return (
|
return (
|
||||||
|
@ -38,9 +40,12 @@ export default function AppRouter(props) {
|
||||||
<SearchPage path={`$/${PAGES.SEARCH}`} />
|
<SearchPage path={`$/${PAGES.SEARCH}`} />
|
||||||
<SettingsPage path={`$/${PAGES.SETTINGS}`} />
|
<SettingsPage path={`$/${PAGES.SETTINGS}`} />
|
||||||
<SubscriptionsPage path={`$/${PAGES.SUBSCRIPTIONS}`} />
|
<SubscriptionsPage path={`$/${PAGES.SUBSCRIPTIONS}`} />
|
||||||
<TransactionHistoryPage path={`$/${PAGES.HISTORY}`} />
|
<TransactionHistoryPage path={`$/${PAGES.TRANSACTIONS}`} />
|
||||||
<UserHistoryPage path={`$/${PAGES.USER_HISTORY}`} />
|
<UserHistoryPage path={`$/${PAGES.HISTORY}`} />
|
||||||
<WalletPage path={`$/${PAGES.WALLET}`} />
|
<AccountPage path={`$/${PAGES.ACCOUNT}`} />
|
||||||
|
<SendCreditsPage path={`$/${PAGES.SEND}`} />
|
||||||
|
<UserHistoryPage path={`$/${PAGES.HISTORY}`} />
|
||||||
|
<NavigationHistory path={`$/${PAGES.HISTORY}/all`} />
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class SideBar extends React.PureComponent<Props> {
|
||||||
<ul className="navigation__links">
|
<ul className="navigation__links">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
...buildLink(null, __('Home'), ICONS.HOME),
|
...buildLink(null, __('Discover'), ICONS.DISCOVER),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...buildLink(
|
...buildLink(
|
||||||
|
@ -54,22 +54,20 @@ class SideBar extends React.PureComponent<Props> {
|
||||||
ICONS.SUBSCRIPTION
|
ICONS.SUBSCRIPTION
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
].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.PUBLISHED, 'Publishes', ICONS.PUBLISHED),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.USER_HISTORY, 'History', ICONS.HISTORY),
|
...buildLink(PAGES.HISTORY, 'History', ICONS.HISTORY),
|
||||||
|
},
|
||||||
|
].map(renderLink)}
|
||||||
|
</ul>
|
||||||
|
<div className="navigation__link navigation__link--title">Account</div>
|
||||||
|
|
||||||
|
<ul className="navigation__links">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
...buildLink(PAGES.ACCOUNT, 'Overview', ICONS.ACCOUNT),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.INVITE, 'Invite', ICONS.INVITE),
|
...buildLink(PAGES.INVITE, 'Invite', ICONS.INVITE),
|
||||||
|
@ -77,30 +75,25 @@ class SideBar extends React.PureComponent<Props> {
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.REWARDS, 'Rewards', ICONS.FEATURED),
|
...buildLink(PAGES.REWARDS, 'Rewards', ICONS.FEATURED),
|
||||||
},
|
},
|
||||||
].map(renderLink)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className="navigation__link navigation__link--title">Wallet</div>
|
|
||||||
|
|
||||||
<ul className="navigation__links">
|
|
||||||
{[
|
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.WALLET, 'Overview', ICONS.WALLET),
|
...buildLink(PAGES.SEND, 'Send & Recieve', ICONS.SEND),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.HISTORY, 'Transactions', ICONS.TRANSACTIONS),
|
...buildLink(PAGES.TRANSACTIONS, 'Transactions', ICONS.TRANSACTIONS),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
...buildLink(PAGES.SETTINGS, 'Settings', ICONS.SETTINGS),
|
||||||
|
},
|
||||||
|
// @if TARGET='app'
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.BACKUP, 'Backup', ICONS.BACKUP),
|
...buildLink(PAGES.BACKUP, 'Backup', ICONS.BACKUP),
|
||||||
},
|
},
|
||||||
|
// @endif
|
||||||
].map(renderLink)}
|
].map(renderLink)}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul className="navigation__links navigation__links--bottom">
|
<ul className="navigation__links navigation__links--bottom">
|
||||||
{[
|
{[
|
||||||
{
|
|
||||||
...buildLink(PAGES.SETTINGS, 'Settings', ICONS.SETTINGS),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
...buildLink(PAGES.HELP, 'Help', ICONS.HELP),
|
...buildLink(PAGES.HELP, 'Help', ICONS.HELP),
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
|
||||||
|
|
||||||
<p className="card__subtitle">
|
<p className="card__subtitle">
|
||||||
{__('To view all of your transactions, navigate to the')}{' '}
|
{__('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>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Button
|
<Button
|
||||||
button="primary"
|
button="primary"
|
||||||
navigate="/$/history"
|
navigate="/$/transactions"
|
||||||
label={__('Full History')}
|
label={__('Full History')}
|
||||||
icon={icons.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 PLAY = 'Play';
|
||||||
export const FACEBOOK = 'Facebook';
|
export const FACEBOOK = 'Facebook';
|
||||||
export const TWITTER = 'Twitter';
|
export const TWITTER = 'Twitter';
|
||||||
export const WALLET = 'CreditCard';
|
export const ACCOUNT = 'User';
|
||||||
export const SETTINGS = 'Settings';
|
export const SETTINGS = 'Settings';
|
||||||
export const INVITE = 'Users';
|
export const INVITE = 'Users';
|
||||||
export const FILE = 'File';
|
export const FILE = 'File';
|
||||||
|
@ -51,3 +51,5 @@ export const MENU = 'Menu';
|
||||||
export const BACKUP = 'Database';
|
export const BACKUP = 'Database';
|
||||||
export const TRANSACTIONS = 'FileText';
|
export const TRANSACTIONS = 'FileText';
|
||||||
export const LBRY = 'Lbry';
|
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 SEND = 'send';
|
||||||
export const SETTINGS = 'settings';
|
export const SETTINGS = 'settings';
|
||||||
export const SHOW = 'show';
|
export const SHOW = 'show';
|
||||||
export const WALLET = 'wallet';
|
export const ACCOUNT = 'account';
|
||||||
export const SUBSCRIPTIONS = 'subscriptions';
|
export const SUBSCRIPTIONS = 'subscriptions';
|
||||||
export const SEARCH = 'search';
|
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;
|
const hasDownloads = fileInfos && Object.values(fileInfos).length > 0;
|
||||||
|
|
||||||
return (
|
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 ? (
|
{hasDownloads ? (
|
||||||
<FileList fileInfos={fileInfos} sortBy={sortBy} page={PAGES.DOWNLOADED} />
|
<FileList fileInfos={fileInfos} sortBy={sortBy} page={PAGES.DOWNLOADED} />
|
||||||
) : (
|
) : (
|
||||||
|
@ -37,7 +39,7 @@ class FileListDownloaded extends React.PureComponent<Props> {
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</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
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import UserHistory from 'component/userHistory';
|
import UserHistory from 'component/navigationHistoryRecent';
|
||||||
|
import DownloadList from 'page/fileListDownloaded';
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ class UserHistoryPage extends React.PureComponent<Props> {
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<UserHistory {...this.props} />
|
<UserHistory {...this.props} />
|
||||||
|
<DownloadList {...this.props} />
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ import {
|
||||||
selectClaimsByUri,
|
selectClaimsByUri,
|
||||||
makeSelectClaimsInChannelForCurrentPageState,
|
makeSelectClaimsInChannelForCurrentPageState,
|
||||||
} from 'lbry-redux';
|
} 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 || {};
|
export const selectState = (state: any) => state.content || {};
|
||||||
|
|
||||||
|
@ -33,37 +35,38 @@ export const makeSelectContentPositionForUri = (uri: string) =>
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectHistoryPageCount = createSelector(
|
export const selectHistory = createSelector(
|
||||||
selectState,
|
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) =>
|
export const makeSelectHistoryForPage = (page: number) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
selectState,
|
selectHistory,
|
||||||
selectClaimsByUri,
|
selectClaimsByUri,
|
||||||
(state, claimsByUri) => {
|
(history, claimsByUri) => {
|
||||||
const left = page * HISTORY_ITEMS_PER_PAGE;
|
const left = page * HISTORY_ITEMS_PER_PAGE;
|
||||||
const historyItems = state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
const historyItemsForPage = history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
||||||
|
return historyItemsForPage;
|
||||||
// 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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const makeSelectHistoryForUri = (uri: string) =>
|
export const makeSelectHistoryForUri = (uri: string) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
selectState,
|
selectHistory,
|
||||||
state => state.history.find(i => i.uri === uri)
|
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) =>
|
export const makeSelectCategoryListUris = (uris: ?Array<string>, channel: string) =>
|
||||||
|
|
|
@ -19,20 +19,10 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
html[data-mode='dark'] & {
|
|
||||||
border-color: $lbry-gray-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main navigation collapses into a menu button
|
// Main navigation collapses into a menu button
|
||||||
// at smaller screen widths
|
// at smaller screen widths
|
||||||
|
|
||||||
@media (min-width: 601px) {
|
@media (min-width: 601px) {
|
||||||
/* @if TARGET='app' */
|
|
||||||
width: 250px;
|
|
||||||
/* @endif */
|
|
||||||
/* @if TARGET='web' */
|
|
||||||
width: 170px;
|
width: 170px;
|
||||||
/* @endif */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@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 {
|
.header__navigation-item {
|
||||||
height: var(--header-height);
|
height: var(--header-height);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -73,6 +86,7 @@
|
||||||
.header__navigation-item--home,
|
.header__navigation-item--home,
|
||||||
.header__navigation-item--menu {
|
.header__navigation-item--menu {
|
||||||
width: var(--header-height);
|
width: var(--header-height);
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
&:only-child {
|
&:only-child {
|
||||||
// Header icons are a little different because they are larger
|
// Header icons are a little different because they are larger
|
||||||
|
@ -95,7 +109,7 @@
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
color: $lbry-white;
|
color: $lbry-white;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
top: -0.2rem;
|
top: -0.8rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +144,7 @@
|
||||||
|
|
||||||
.header__navigation-item--wallet {
|
.header__navigation-item--wallet {
|
||||||
border-right: 1px solid $lbry-gray-1;
|
border-right: 1px solid $lbry-gray-1;
|
||||||
width: calc(100% - (var(--header-height) * 3));
|
width: 10rem;
|
||||||
|
|
||||||
html[data-mode='dark'] & {
|
html[data-mode='dark'] & {
|
||||||
border-color: $lbry-gray-5;
|
border-color: $lbry-gray-5;
|
||||||
|
|
|
@ -1,37 +1,42 @@
|
||||||
.item-list {
|
.item-list {
|
||||||
background-color: $lbry-white;
|
background-color: $lbry-white;
|
||||||
margin-top: var(--spacing-vertical-large);
|
margin-top: var(--spacing-vertical-large);
|
||||||
|
margin-bottom: var(--spacing-vertical-large);
|
||||||
padding: var(--spacing-vertical-large);
|
padding: var(--spacing-vertical-large);
|
||||||
|
|
||||||
html[data-mode='dark'] & {
|
html[data-mode='dark'] & {
|
||||||
background-color: rgba($lbry-white, 0.1);
|
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;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: var(--spacing-vertical-small);
|
padding: var(--spacing-vertical-small);
|
||||||
|
|
||||||
input,
|
|
||||||
.item-list__item--cutoff {
|
|
||||||
margin-right: var(--spacing-vertical-large);
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset-section {
|
fieldset-section {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-list__item--cutoff {
|
.item-list__element {
|
||||||
max-width: 350px;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:not(:first-of-type) {
|
||||||
|
padding-left: var(--spacing-vertical-small);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-list__item--selected {
|
.item-list__row:hover,
|
||||||
background-color: $lbry-gray-1;
|
.item-list__row--selected {
|
||||||
|
background-color: rgba($lbry-black, 0.1);
|
||||||
|
|
||||||
html[data-mode='dark'] & {
|
html[data-mode='dark'] & {
|
||||||
background-color: rgba($lbry-black, 0.5);
|
background-color: rgba($lbry-black, 0.5);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
padding-top: var(--spacing-vertical-large);
|
padding-top: var(--spacing-vertical-large);
|
||||||
padding-right: var(--spacing-vertical-small);
|
padding-right: var(--spacing-vertical-small);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: overlay;
|
||||||
|
|
||||||
html[data-mode='dark'] & {
|
html[data-mode='dark'] & {
|
||||||
background-color: $lbry-black;
|
background-color: $lbry-black;
|
||||||
|
@ -15,7 +18,7 @@
|
||||||
// on smaller screen widths
|
// on smaller screen widths
|
||||||
|
|
||||||
@media (min-width: 601px) {
|
@media (min-width: 601px) {
|
||||||
min-width: 171px; // 1px is for the border
|
width: 171px; // 1px is for the border
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
@ -53,8 +56,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation__links--bottom {
|
.navigation__links--bottom {
|
||||||
position: absolute;
|
margin-top: auto;
|
||||||
bottom: var(--spacing-vertical-large);
|
margin-bottom: var(--spacing-vertical-large);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation__link {
|
.navigation__link {
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.time--ago {
|
.time--ago {
|
||||||
min-width: 160px;
|
min-width: 140px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue