Revert "Right Click to Navigate History (#3547)"
This reverts commit 6d88d87ff2
.
This commit is contained in:
parent
ebe78c50f3
commit
f1742eca25
10 changed files with 48 additions and 208 deletions
|
@ -915,7 +915,12 @@
|
||||||
"Support %amount% LBC": "Support %amount% LBC",
|
"Support %amount% LBC": "Support %amount% LBC",
|
||||||
"You deposited %amount% LBC as a support!": "You deposited %amount% LBC as a support!",
|
"You deposited %amount% LBC as a support!": "You deposited %amount% LBC as a support!",
|
||||||
"LBRY Link": "LBRY Link",
|
"LBRY Link": "LBRY Link",
|
||||||
|
"Publish to %uri%": "Publish to %uri%",
|
||||||
"Your wallet": "Your wallet",
|
"Your wallet": "Your wallet",
|
||||||
"Publish a file, or create a channel": "Publish a file, or create a channel",
|
"Publish a file, or create a channel": "Publish a file, or create a channel",
|
||||||
"Your account": "Your account"
|
"Your account": "Your account",
|
||||||
|
"Channel profile picture": "Channel profile picture",
|
||||||
|
"refreshing the app": "refreshing the app",
|
||||||
|
"Follower": "Follower",
|
||||||
|
"%repost_channel_link% reposted": "%repost_channel_link% reposted"
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import WunderBar from 'component/wunderbar';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||||
import Tooltip from 'component/common/tooltip';
|
import Tooltip from 'component/common/tooltip';
|
||||||
import NavigationButton from 'component/navigationButton';
|
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
import { IS_MAC } from 'component/app/view';
|
import { IS_MAC } from 'component/app/view';
|
||||||
// @endif
|
// @endif
|
||||||
|
@ -19,15 +18,7 @@ import { IS_MAC } from 'component/app/view';
|
||||||
type Props = {
|
type Props = {
|
||||||
balance: string,
|
balance: string,
|
||||||
roundedBalance: number,
|
roundedBalance: number,
|
||||||
history: {
|
history: { push: string => void, goBack: () => void, goForward: () => void, location: { pathname: string } },
|
||||||
entities: {}[],
|
|
||||||
goBack: () => void,
|
|
||||||
goForward: () => void,
|
|
||||||
index: number,
|
|
||||||
length: number,
|
|
||||||
location: { pathname: string },
|
|
||||||
push: string => void,
|
|
||||||
},
|
|
||||||
currentTheme: string,
|
currentTheme: string,
|
||||||
automaticDarkModeEnabled: boolean,
|
automaticDarkModeEnabled: boolean,
|
||||||
setClientSetting: (string, boolean | string) => void,
|
setClientSetting: (string, boolean | string) => void,
|
||||||
|
@ -114,8 +105,21 @@ const Header = (props: Props) => {
|
||||||
{/* @if TARGET='app' */}
|
{/* @if TARGET='app' */}
|
||||||
{!authHeader && (
|
{!authHeader && (
|
||||||
<div className="header__navigation-arrows">
|
<div className="header__navigation-arrows">
|
||||||
<NavigationButton isBackward history={history} />
|
<Button
|
||||||
<NavigationButton isBackward={false} history={history} />
|
className="header__navigation-item header__navigation-item--back"
|
||||||
|
description={__('Navigate back')}
|
||||||
|
onClick={() => history.goBack()}
|
||||||
|
icon={ICONS.ARROW_LEFT}
|
||||||
|
iconSize={18}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className="header__navigation-item header__navigation-item--forward"
|
||||||
|
description={__('Navigate forward')}
|
||||||
|
onClick={() => history.goForward()}
|
||||||
|
icon={ICONS.ARROW_RIGHT}
|
||||||
|
iconSize={18}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
import NavigationButton from './view';
|
|
||||||
|
|
||||||
export default NavigationButton;
|
|
|
@ -1,91 +0,0 @@
|
||||||
// @flow
|
|
||||||
import React, { useState, useCallback } from 'react';
|
|
||||||
import * as ICONS from 'constants/icons';
|
|
||||||
import Button from 'component/button';
|
|
||||||
|
|
||||||
// the maximum length of history to show per button
|
|
||||||
const MAX_HISTORY_SIZE = 12;
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
isBackward: boolean,
|
|
||||||
history: {
|
|
||||||
entries: Array<{ key: string, title: string, pathname: string }>,
|
|
||||||
go: number => void,
|
|
||||||
goBack: () => void,
|
|
||||||
goForward: () => void,
|
|
||||||
index: number,
|
|
||||||
length: number,
|
|
||||||
location: { pathname: string },
|
|
||||||
push: string => void,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// determines which slice of entries should make up the back or forward button drop-downs (isBackward vs !isBackward respectively)
|
|
||||||
const sliceEntries = (currentIndex, entries, historyLength, isBackward, maxSize) => {
|
|
||||||
let l = isBackward ? 0 : currentIndex + 1;
|
|
||||||
let r = isBackward ? currentIndex : historyLength;
|
|
||||||
const exceedsMax = maxSize < r - l;
|
|
||||||
if (!exceedsMax) {
|
|
||||||
return entries.slice(l, r);
|
|
||||||
} else if (isBackward) {
|
|
||||||
l = r - maxSize;
|
|
||||||
} else {
|
|
||||||
r = l + maxSize;
|
|
||||||
}
|
|
||||||
return entries.slice(l, r);
|
|
||||||
};
|
|
||||||
|
|
||||||
const NavigationButton = (props: Props) => {
|
|
||||||
const { isBackward, history } = props;
|
|
||||||
const { entries, go } = history;
|
|
||||||
const currentIndex = history.index;
|
|
||||||
const historyLength = history.length;
|
|
||||||
const [showHistory, setShowHistory] = useState(false);
|
|
||||||
|
|
||||||
// creates an <li> intended for the button's <ul>
|
|
||||||
const makeItem = useCallback(
|
|
||||||
(entry: { pathname: string, title: string, key: string }, index: number) => {
|
|
||||||
// difference between the current index and the index of the entry
|
|
||||||
const backwardDif = index - (currentIndex < MAX_HISTORY_SIZE ? currentIndex : MAX_HISTORY_SIZE);
|
|
||||||
const forwardDif = index + 1;
|
|
||||||
return (
|
|
||||||
<li
|
|
||||||
className="header__navigation-button"
|
|
||||||
role="link"
|
|
||||||
key={entry.key}
|
|
||||||
onMouseDown={() => {
|
|
||||||
setShowHistory(false);
|
|
||||||
go(isBackward ? backwardDif : forwardDif);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>{entry.title}</span>
|
|
||||||
<span className="header__navigation-button-help">{entry.pathname === '/' ? __('Home') : entry.pathname}</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[currentIndex, isBackward, go]
|
|
||||||
);
|
|
||||||
const slicedEntries = sliceEntries(currentIndex, entries, historyLength, isBackward, MAX_HISTORY_SIZE);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
className={`header__navigation-item header__navigation-item--${isBackward ? 'back' : 'forward'}`}
|
|
||||||
description={isBackward ? __('Navigate back') : __('Navigate forward')}
|
|
||||||
onBlur={() => setShowHistory(false)}
|
|
||||||
onClick={() => (isBackward ? history.goBack() : history.goForward())}
|
|
||||||
onContextMenu={e => {
|
|
||||||
setShowHistory(!showHistory);
|
|
||||||
// the following three lines prevent the regular context menu (right click menu) from appearing
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
return false;
|
|
||||||
}}
|
|
||||||
icon={isBackward ? ICONS.ARROW_LEFT : ICONS.ARROW_RIGHT}
|
|
||||||
iconSize={18}
|
|
||||||
disabled={slicedEntries.length === 0}
|
|
||||||
/>
|
|
||||||
{showHistory && <ul className={'header__navigation-dropdown'}>{slicedEntries.map(makeItem)}</ul>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default NavigationButton;
|
|
|
@ -2,31 +2,10 @@ import { connect } from 'react-redux';
|
||||||
import { selectUserVerifiedEmail } from 'lbryinc';
|
import { selectUserVerifiedEmail } from 'lbryinc';
|
||||||
import { selectScrollStartingPosition } from 'redux/selectors/app';
|
import { selectScrollStartingPosition } from 'redux/selectors/app';
|
||||||
import Router from './view';
|
import Router from './view';
|
||||||
import { normalizeURI, makeSelectTitleForUri } from 'lbry-redux';
|
|
||||||
|
|
||||||
const select = state => {
|
const select = state => ({
|
||||||
const { pathname, hash } = state.router.location;
|
|
||||||
const urlPath = pathname + hash;
|
|
||||||
// Remove the leading "/" added by the browser
|
|
||||||
const path = urlPath.slice(1).replace(/:/g, '#');
|
|
||||||
|
|
||||||
let uri;
|
|
||||||
try {
|
|
||||||
uri = normalizeURI(path);
|
|
||||||
} catch (e) {
|
|
||||||
const match = path.match(/[#/:]/);
|
|
||||||
|
|
||||||
if (!path.startsWith('$/') && match && match.index) {
|
|
||||||
uri = `lbry://${path.slice(0, match.index)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
uri,
|
|
||||||
title: makeSelectTitleForUri(uri)(state),
|
|
||||||
currentScroll: selectScrollStartingPosition(state),
|
currentScroll: selectScrollStartingPosition(state),
|
||||||
isAuthenticated: selectUserVerifiedEmail(state),
|
isAuthenticated: selectUserVerifiedEmail(state),
|
||||||
};
|
});
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(select)(Router);
|
export default connect(select)(Router);
|
||||||
|
|
|
@ -29,8 +29,6 @@ import SignInPage from 'page/signIn';
|
||||||
import SignInVerifyPage from 'page/signInVerify';
|
import SignInVerifyPage from 'page/signInVerify';
|
||||||
import ChannelsPage from 'page/channels';
|
import ChannelsPage from 'page/channels';
|
||||||
import EmbedWrapperPage from 'page/embedWrapper';
|
import EmbedWrapperPage from 'page/embedWrapper';
|
||||||
import { parseURI } from 'lbry-redux';
|
|
||||||
import { SITE_TITLE } from 'config';
|
|
||||||
|
|
||||||
// Tell the browser we are handling scroll restoration
|
// Tell the browser we are handling scroll restoration
|
||||||
if ('scrollRestoration' in history) {
|
if ('scrollRestoration' in history) {
|
||||||
|
@ -63,19 +61,6 @@ type Props = {
|
||||||
currentScroll: number,
|
currentScroll: number,
|
||||||
location: { pathname: string, search: string },
|
location: { pathname: string, search: string },
|
||||||
isAuthenticated: boolean,
|
isAuthenticated: boolean,
|
||||||
history: {
|
|
||||||
entries: { title: string }[],
|
|
||||||
goBack: () => void,
|
|
||||||
goForward: () => void,
|
|
||||||
index: number,
|
|
||||||
length: number,
|
|
||||||
location: { pathname: string },
|
|
||||||
push: string => void,
|
|
||||||
state: {},
|
|
||||||
replaceState: ({}, string, string) => void,
|
|
||||||
},
|
|
||||||
uri: string,
|
|
||||||
title: string,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function AppRouter(props: Props) {
|
function AppRouter(props: Props) {
|
||||||
|
@ -83,37 +68,7 @@ function AppRouter(props: Props) {
|
||||||
currentScroll,
|
currentScroll,
|
||||||
location: { pathname },
|
location: { pathname },
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
history,
|
|
||||||
uri,
|
|
||||||
title,
|
|
||||||
} = props;
|
} = props;
|
||||||
const { entries } = history;
|
|
||||||
const entryIndex = history.index;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (uri) {
|
|
||||||
const { channelName, streamName } = parseURI(uri);
|
|
||||||
|
|
||||||
if (typeof title !== 'undefined' && title !== '') {
|
|
||||||
document.title = title;
|
|
||||||
} else if (streamName) {
|
|
||||||
document.title = streamName;
|
|
||||||
} else if (channelName) {
|
|
||||||
document.title = channelName;
|
|
||||||
} else {
|
|
||||||
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
|
|
||||||
}
|
|
||||||
|
|
||||||
// @if TARGET='app'
|
|
||||||
entries[entryIndex].title = document.title;
|
|
||||||
// @endif
|
|
||||||
return () => {
|
|
||||||
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
|
|
||||||
};
|
|
||||||
}, [entries, entryIndex, title, uri]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.scrollTo(0, currentScroll);
|
window.scrollTo(0, currentScroll);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import { parseURI } from 'lbry-redux';
|
||||||
import BusyIndicator from 'component/common/busy-indicator';
|
import BusyIndicator from 'component/common/busy-indicator';
|
||||||
import ChannelPage from 'page/channel';
|
import ChannelPage from 'page/channel';
|
||||||
import FilePage from 'page/file';
|
import FilePage from 'page/file';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import { SITE_TITLE } from 'config';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -22,7 +24,8 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function ShowPage(props: Props) {
|
function ShowPage(props: Props) {
|
||||||
const { isResolvingUri, resolveUri, uri, claim, blackListedOutpoints, location, claimIsMine } = props;
|
const { isResolvingUri, resolveUri, uri, claim, blackListedOutpoints, location, title, claimIsMine } = props;
|
||||||
|
const { channelName, streamName } = parseURI(uri);
|
||||||
const signingChannel = claim && claim.signing_channel;
|
const signingChannel = claim && claim.signing_channel;
|
||||||
const canonicalUrl = claim && claim.canonical_url;
|
const canonicalUrl = claim && claim.canonical_url;
|
||||||
const claimExists = claim !== null && claim !== undefined;
|
const claimExists = claim !== null && claim !== undefined;
|
||||||
|
@ -43,6 +46,22 @@ function ShowPage(props: Props) {
|
||||||
}
|
}
|
||||||
}, [resolveUri, isResolvingUri, canonicalUrl, uri, claimExists, haventFetchedYet]);
|
}, [resolveUri, isResolvingUri, canonicalUrl, uri, claimExists, haventFetchedYet]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (title) {
|
||||||
|
document.title = title;
|
||||||
|
} else if (streamName) {
|
||||||
|
document.title = streamName;
|
||||||
|
} else if (channelName) {
|
||||||
|
document.title = channelName;
|
||||||
|
} else {
|
||||||
|
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.title = IS_WEB ? SITE_TITLE : 'LBRY';
|
||||||
|
};
|
||||||
|
}, [title, channelName, streamName]);
|
||||||
|
|
||||||
let innerContent = '';
|
let innerContent = '';
|
||||||
|
|
||||||
if (!claim || (claim && !claim.name)) {
|
if (!claim || (claim && !claim.name)) {
|
||||||
|
|
|
@ -147,29 +147,3 @@
|
||||||
.header__navigation-item--balance {
|
.header__navigation-item--balance {
|
||||||
margin: 0 var(--spacing-medium);
|
margin: 0 var(--spacing-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__navigation-dropdown {
|
|
||||||
@extend .menu__list--header;
|
|
||||||
padding: 0;
|
|
||||||
position: absolute;
|
|
||||||
list-style-type: none;
|
|
||||||
background-color: var(--color-header-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-button {
|
|
||||||
margin: 0;
|
|
||||||
padding: var(--spacing-miniscule) var(--spacing-medium);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: var(--color-menu-background--active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__navigation-button-help {
|
|
||||||
@extend .help;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-left: var(--spacing-small);
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,8 +55,6 @@
|
||||||
margin-left: calc(var(--spacing-medium) * -1);
|
margin-left: calc(var(--spacing-medium) * -1);
|
||||||
box-shadow: var(--card-box-shadow);
|
box-shadow: var(--card-box-shadow);
|
||||||
animation: menu-animate-in var(--animation-duration) var(--animation-style);
|
animation: menu-animate-in var(--animation-duration) var(--animation-style);
|
||||||
border-bottom-left-radius: var(--border-radius);
|
|
||||||
border-bottom-right-radius: var(--border-radius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__link {
|
.menu__link {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { createFilter, createBlacklistFilter } from 'redux-persist-transform-fil
|
||||||
import localForage from 'localforage';
|
import localForage from 'localforage';
|
||||||
import { createStore, applyMiddleware, compose } from 'redux';
|
import { createStore, applyMiddleware, compose } from 'redux';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
import { createMemoryHistory, createBrowserHistory } from 'history';
|
import { createHashHistory, createBrowserHistory } from 'history';
|
||||||
import { routerMiddleware } from 'connected-react-router';
|
import { routerMiddleware } from 'connected-react-router';
|
||||||
import createRootReducer from './reducers';
|
import createRootReducer from './reducers';
|
||||||
import { buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
|
import { buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
|
||||||
|
@ -96,7 +96,7 @@ const persistOptions = {
|
||||||
|
|
||||||
let history;
|
let history;
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
history = createMemoryHistory();
|
history = createHashHistory();
|
||||||
// @endif
|
// @endif
|
||||||
// @if TARGET='web'
|
// @if TARGET='web'
|
||||||
history = createBrowserHistory();
|
history = createBrowserHistory();
|
||||||
|
|
Loading…
Reference in a new issue