summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Logs.js68
-rw-r--r--src/components/Logs.module.scss11
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;