lbry-desktop/ui/component/navigationButton/view.jsx

98 lines
3.2 KiB
React
Raw Normal View History

// @flow
import React, { useState, useCallback } from 'react';
import * as ICONS from 'constants/icons';
import Button from 'component/button';
2020-01-28 01:46:43 +01:00
// the maximum length of history to show per button
const MAX_HISTORY_SIZE = 12;
type Props = {
isBackward: boolean,
history: {
2020-02-13 02:48:28 +01:00
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)
2020-01-28 01:46:43 +01:00
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(
2020-02-13 02:48:28 +01:00
(entry: { pathname: string, title: string, key: string }, index: number) => {
// difference between the current index and the index of the entry
2020-01-28 01:46:43 +01:00
const backwardDif = index - (currentIndex < MAX_HISTORY_SIZE ? currentIndex : MAX_HISTORY_SIZE);
const forwardDif = index + 1;
return (
<li
2020-02-13 02:48:28 +01:00
className="header__navigation-button"
role="link"
key={entry.key}
onMouseDown={() => {
setShowHistory(false);
2020-01-28 01:46:43 +01:00
go(isBackward ? backwardDif : forwardDif);
}}
>
2020-02-13 02:48:28 +01:00
<span>{entry.title}</span>
<span className="header__navigation-button-help">{entry.pathname === '/' ? __('Home') : entry.pathname}</span>
</li>
);
},
[currentIndex, isBackward, go]
);
2020-01-28 01:46:43 +01:00
const slicedEntries = sliceEntries(currentIndex, entries, historyLength, isBackward, MAX_HISTORY_SIZE);
return (
<div
// @if TARGET='app'
onDoubleClick={e => {
e.stopPropagation();
}}
// @endif
>
<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}
2020-01-28 00:39:04 +01:00
disabled={slicedEntries.length === 0}
/>
2020-02-13 02:48:28 +01:00
{showHistory && <ul className={'header__navigation-dropdown'}>{slicedEntries.map(makeItem)}</ul>}
</div>
);
};
export default NavigationButton;