Improve state usage in LiveLog and move BlinkingCursor to its own file

One side effect is a fixed gerDerivedStateFromProps implementation, as
it previously mixed up state and props.

Signed-off-by: Mcat12 <newtoncat12@yahoo.com>
This commit is contained in:
Mcat12
2019-12-17 16:07:58 -05:00
parent f5bbe9dafc
commit dfb1affb50
2 changed files with 75 additions and 44 deletions
+49
View File
@@ -0,0 +1,49 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2019 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* Web Interface
* Blinking cursor component
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React, { Component } from "react";
interface BlinkingCursorProps {
refreshInterval: number;
}
interface BlinkingCursorState {
showText: boolean;
}
export class BlinkingCursor extends Component<
BlinkingCursorProps,
BlinkingCursorState
> {
state: BlinkingCursorState = {
showText: true
};
constructor(props: BlinkingCursorProps) {
super(props);
// Change the state every second
setInterval(
() => {
this.setState(previousState => ({
showText: !previousState.showText
}));
},
// Define blinking time.
props.refreshInterval
);
}
render() {
return (
<div style={{ marginBottom: 10 }}>{this.state.showText ? "_" : " "}</div>
);
}
}
+26 -44
View File
@@ -15,12 +15,14 @@ import { getTimeFromTimestamp } from "../../util/dateUtils";
import api from "../../util/api";
import { Input, Container, Row, Col } from "reactstrap";
import { WithTranslation, withTranslation } from "react-i18next";
import { BlinkingCursor } from "./BlinkingCursor";
export interface LiveLogProps {
log: Array<{
timestamp: number;
message: string;
}>;
refreshInterval: number;
}
interface LiveLogState {
@@ -28,51 +30,28 @@ interface LiveLogState {
timestamp: number;
message: string;
}>;
}
const refreshingInverval = 500;
class BlinkingCursor extends Component<any, any> {
constructor(props: any) {
super(props);
this.state = { showText: true };
// Change the state every second
setInterval(
() => {
this.setState((previousState: any) => {
return { showText: !previousState.showText };
});
},
// Define blinking time.
refreshingInverval
);
}
render() {
let display = this.state.showText ? "_" : " ";
return <div style={{ marginBottom: 10 }}>{display}</div>;
}
scrollEnabled: boolean;
}
let nextId = 0;
let newdata = false;
class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
static getDerivedStateFromProps(
state: LiveLogState,
props: LiveLogProps
props: LiveLogProps,
state: LiveLogState
): LiveLogState {
newdata = state.log.length > 0;
return {
log: [...props.log, ...state.log]
...state,
log: [...state.log, ...props.log]
};
}
state: LiveLogState = { log: [] };
scrollEnabled: boolean = true;
state: LiveLogState = {
log: [],
scrollEnabled: true
};
componentDidUpdate() {
if (this.scrollEnabled && newdata) {
newdata = false;
if (this.state.scrollEnabled && this.props.log.length > 0) {
this.scrollToBottom();
}
}
@@ -90,9 +69,10 @@ class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
});
}
checkBoxChange() {
this.scrollEnabled = !this.scrollEnabled;
this.scrollToBottom();
toggleScroll() {
this.setState(prevState => ({
scrollEnabled: !prevState.scrollEnabled
}));
}
render() {
@@ -109,8 +89,8 @@ class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
<Col>
<Input
type="checkbox"
checked={this.scrollEnabled}
onChange={() => this.checkBoxChange()}
checked={this.state.scrollEnabled}
onChange={() => this.toggleScroll()}
/>
{t("Automatic scrolling on update")}
</Col>
@@ -123,7 +103,7 @@ class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
{getTimeFromTimestamp(item.timestamp) + " :: " + item.message}
</div>
))}
<BlinkingCursor />
<BlinkingCursor refreshInterval={this.props.refreshInterval} />
</pre>
</Col>
</Row>
@@ -131,8 +111,8 @@ class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
<Col>
<Input
type="checkbox"
checked={this.scrollEnabled}
onChange={() => this.checkBoxChange()}
checked={this.state.scrollEnabled}
onChange={() => this.toggleScroll()}
/>
{t("Automatic scrolling on update")}
</Col>
@@ -144,7 +124,7 @@ class LiveLog extends Component<LiveLogProps & WithTranslation, LiveLogState> {
export const TranslatedLiveLog = withTranslation(["live-log"])(LiveLog);
export default (props: any) => (
export default () => (
<WithAPIData
apiCall={() => {
return api.getLiveLog(nextId).then(response => {
@@ -152,9 +132,11 @@ export default (props: any) => (
return response;
});
}}
repeatOptions={{ interval: refreshingInverval, ignoreCancel: true }}
repeatOptions={{ interval: 500, ignoreCancel: true }}
renderInitial={() => null}
renderOk={data => <TranslatedLiveLog log={data.log} {...props} />}
renderOk={data => (
<TranslatedLiveLog log={data.log} refreshInterval={500} />
)}
renderErr={() => null}
/>
);