Off viewport tabs + favicon (#451)

* Show off-viewport selected tab to the right

* Add favicon
This commit is contained in:
Maciej Hirsz
2022-02-04 17:43:28 +01:00
committed by GitHub
parent b9f93242cd
commit 530cf6f7b0
5 changed files with 53 additions and 14 deletions
+5
View File
@@ -0,0 +1,5 @@
<svg width="278" height="278" viewBox="0 0 250 278" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M122.222 127.504L23.3996 71.0796C18.5633 68.3182 18.5334 61.3555 23.346 58.5528L122.199 0.982327C124.442 -0.3236 127.212 -0.32769 129.458 0.971606L228.12 58.0407C232.937 60.8269 232.933 67.7821 228.112 70.5624L129.42 127.488C127.194 128.772 124.454 128.778 122.222 127.504Z" fill="#E6007A"/>
<path d="M246.368 219.626L148.092 276.997C143.282 279.805 137.237 276.349 137.216 270.78L136.785 156.385C136.776 153.791 138.157 151.389 140.406 150.094L239.16 93.1846C243.981 90.4063 250.002 93.8876 250 99.4522L249.953 213.385C249.952 215.955 248.587 218.331 246.368 219.626Z" fill="#E6007A"/>
<path d="M113.198 156.338L113.745 270.133C113.771 275.702 107.756 279.21 102.923 276.443L3.63874 219.619C1.38658 218.33 -0.00209701 215.933 2.37701e-06 213.338L0.0923778 99.3597C0.0968919 93.7951 6.12245 90.3212 10.9404 93.1055L109.586 150.113C111.81 151.399 113.186 153.769 113.198 156.338Z" fill="#E6007A"/>
</svg>

After

Width:  |  Height:  |  Size: 1013 B

+1
View File
@@ -14,6 +14,7 @@
}
</style>
<script type="text/javascript" src="./Jdenticon.min.js"></script>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
</head>
<body>
<noscript>
+5 -1
View File
@@ -130,6 +130,9 @@ export default class App extends React.Component<{}, {}> {
public render() {
const { timeDiff, subscribed, status, tab } = this.appState;
const chains = this.chains();
const subscribedData = subscribed
? this.appState.chains.get(subscribed)
: null;
Ago.timeDiff = timeDiff;
@@ -156,7 +159,8 @@ export default class App extends React.Component<{}, {}> {
<OfflineIndicator status={status} />
<Chains
chains={chains}
subscribed={subscribed}
subscribedHash={subscribed}
subscribedData={subscribedData}
connection={this.connection}
/>
<Chain
+10
View File
@@ -25,6 +25,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
position: relative;
}
.Chains-extra-subscribed-chain {
position: absolute;
right: 80px;
top: 0px;
background: #e6007a;
background: linear-gradient(90deg, rgba(0,0,0,0) 0px, #e6007a 30px, #e6007a 100%);
z-index: 1;
padding-left: 34px;
}
.Chains-chain {
top: 4px;
padding: 0 12px;
+32 -13
View File
@@ -19,6 +19,7 @@ import { Connection } from '../Connection';
import { Icon } from './Icon';
import { Types, Maybe } from '../common';
import { ChainData } from '../state';
import { viewport } from '../utils';
import githubIcon from '../icons/mark-github.svg';
import listIcon from '../icons/kebab-horizontal.svg';
@@ -27,42 +28,59 @@ import './Chains.css';
export namespace Chains {
export interface Props {
chains: ChainData[];
subscribed: Maybe<Types.GenesisHash>;
subscribedHash: Maybe<Types.GenesisHash>;
subscribedData: Maybe<ChainData>;
connection: Promise<Connection>;
}
}
// How many chains should be rendered in the DOM
const VISIBLE_CAP = 16;
// Average tab width in pixels
const AVERAGE_TAB_WIDTH = 160;
// Milliseconds, sets the minimum time between the renders
const RENDER_THROTTLE = 1000;
export class Chains extends React.Component<Chains.Props, {}> {
private lastRender = performance.now();
private clicked: Maybe<Types.GenesisHash>;
private subscribedChainInView = false;
public shouldComponentUpdate(nextProps: Chains.Props) {
if (nextProps.subscribed !== this.clicked) {
this.clicked = nextProps.subscribed;
if (nextProps.subscribedHash !== this.clicked) {
this.clicked = nextProps.subscribedHash;
}
return (
this.props.subscribed !== nextProps.subscribed ||
this.props.subscribedHash !== nextProps.subscribedHash ||
performance.now() - this.lastRender > RENDER_THROTTLE
);
}
public render() {
this.lastRender = performance.now();
this.subscribedChainInView = false;
const allChainsHref = this.props.subscribed
? `#all-chains/${this.props.subscribed}`
const viewportWidth = viewport().width;
const { chains, subscribedHash, subscribedData } = this.props;
const renderedChains = chains
.slice(0, (viewportWidth / AVERAGE_TAB_WIDTH) | 0)
.map((data) => this.renderChain(data));
const allChainsHref = subscribedHash
? `#all-chains/${subscribedHash}`
: `#all-chains`;
const { chains } = this.props;
const subscribedChain =
subscribedData && !this.subscribedChainInView ? (
<div className="Chains-extra-subscribed-chain">
{this.renderChain(subscribedData)}
</div>
) : null;
return (
<div className="Chains">
{chains.slice(0, VISIBLE_CAP).map((chain) => this.renderChain(chain))}
{subscribedChain}
{renderedChains}
<a
className="Chains-all-chains"
href={allChainsHref}
@@ -82,13 +100,14 @@ export class Chains extends React.Component<Chains.Props, {}> {
);
}
private renderChain(chain: ChainData): React.ReactNode {
const { label, genesisHash, nodeCount } = chain;
private renderChain(chainData: ChainData): React.ReactNode {
const { label, genesisHash, nodeCount } = chainData;
let className = 'Chains-chain';
if (genesisHash === this.props.subscribed) {
if (genesisHash === this.props.subscribedHash) {
className += ' Chains-chain-selected';
this.subscribedChainInView = true;
}
return (