diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/Logs.js | 68 | ||||
| -rw-r--r-- | src/components/Logs.module.scss | 11 |
2 files changed, 47 insertions, 32 deletions
diff --git a/src/components/Logs.js b/src/components/Logs.js index ad551ee..43f64a9 100644 --- a/src/components/Logs.js +++ b/src/components/Logs.js @@ -1,11 +1,13 @@ -import React, { useState, useEffect } from 'react'; +import React, { memo, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { useStoreState, useActions } from 'm/store'; import { getClashAPIConfig } from 'd/app'; import Icon from 'c/Icon'; +import { FixedSizeList as List, areEqual } from 'react-window'; import ContentHeader from 'c/ContentHeader'; +import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight'; // TODO move this into a redux action import { fetchLogs } from '../api/logs'; import { getLogsForDisplay, appendLog } from 'd/logs'; @@ -13,6 +15,7 @@ import { getLogsForDisplay, appendLog } from 'd/logs'; import yacd from 's/yacd.svg'; import s0 from 'c/Logs.module.scss'; +const paddingBottom = 30; const colors = { debug: 'none', // debug: '#8a8a8a', @@ -23,9 +26,9 @@ const colors = { }; function LogLine({ time, even, payload, type }) { - const className = cx({ even }); + const className = cx({ even }, s0.log); return ( - <li className={className}> + <div className={className}> <div className={s0.logMeta}> <div className={s0.logTime}>{time}</div> <div className={s0.logType} style={{ backgroundColor: colors[type] }}> @@ -33,16 +36,23 @@ function LogLine({ time, even, payload, type }) { </div> <div className={s0.logText}>{payload}</div> </div> - </li> + </div> ); } -LogLine.propTypes = { - time: PropTypes.string, - even: PropTypes.bool, - type: PropTypes.string.isRequired, - payload: PropTypes.string.isRequired -}; +function itemKey(index, data) { + const item = data[index]; + return item.id; +} + +const Row = memo(({ index, style, data }) => { + const r = data[index]; + return ( + <div style={style}> + <LogLine {...r} /> + </div> + ); +}, areEqual); const actions = { appendLog }; @@ -57,26 +67,34 @@ export default function Logs() { }, [hostname, port, secret] ); + const [refLogsContainer, containerHeight] = useRemainingViewPortHeight(); return ( <div> <ContentHeader title="Logs" /> - {logs.length === 0 ? ( - <div className={s0.logPlaceholder}> - <div className={s0.logPlaceholderIcon}> - <Icon id={yacd.id} width={200} height={200} /> + <div ref={refLogsContainer} style={{ paddingBottom }}> + {logs.length === 0 ? ( + <div className={s0.logPlaceholder}> + <div className={s0.logPlaceholderIcon}> + <Icon id={yacd.id} width={200} height={200} /> + </div> + <div>No logs yet, hang tight...</div> </div> - <div>No logs yet, hang tight...</div> - </div> - ) : ( - <div className={s0.logs}> - <ul className={s0.logUl}> - {logs.map(l => ( - <LogLine key={l.id} {...l} /> - ))} - </ul> - </div> - )} + ) : ( + <div className={s0.logsWrapper}> + <List + height={containerHeight - paddingBottom} + width="100%" + itemCount={logs.length} + itemSize={80} + itemData={logs} + itemKey={itemKey} + > + {Row} + </List> + </div> + )} + </div> </div> ); } diff --git a/src/components/Logs.module.scss b/src/components/Logs.module.scss index adc6f0f..4351bcb 100644 --- a/src/components/Logs.module.scss +++ b/src/components/Logs.module.scss @@ -40,10 +40,9 @@ $heightHeader: 76px; ////////// -.logUl { +.logsWrapper { margin: 0; padding: 0; - list-style: none; color: var(--color-text); :global { @@ -56,14 +55,12 @@ $heightHeader: 76px; } } -///////// - -.logs { +.log { padding: 10px 40px; - height: calc(100vh - #{$heightHeader}); - overflow: scroll; } +///////// + .logPlaceholder { height: calc(100vh - #{$heightHeader}); display: flex; |
