diff --git a/src/components/log/BlinkingCursor.tsx b/src/components/log/BlinkingCursor.tsx new file mode 100644 index 0000000..1e86be3 --- /dev/null +++ b/src/components/log/BlinkingCursor.tsx @@ -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 ( +
{this.state.showText ? "_" : " "}
+ ); + } +} diff --git a/src/components/log/LiveLog.tsx b/src/components/log/LiveLog.tsx index 88aa83e..8120b1f 100644 --- a/src/components/log/LiveLog.tsx +++ b/src/components/log/LiveLog.tsx @@ -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 { - 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
{display}
; - } + scrollEnabled: boolean; } let nextId = 0; -let newdata = false; class LiveLog extends Component { 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 { }); } - checkBoxChange() { - this.scrollEnabled = !this.scrollEnabled; - this.scrollToBottom(); + toggleScroll() { + this.setState(prevState => ({ + scrollEnabled: !prevState.scrollEnabled + })); } render() { @@ -109,8 +89,8 @@ class LiveLog extends Component { this.checkBoxChange()} + checked={this.state.scrollEnabled} + onChange={() => this.toggleScroll()} /> {t("Automatic scrolling on update")} @@ -123,7 +103,7 @@ class LiveLog extends Component { {getTimeFromTimestamp(item.timestamp) + " :: " + item.message} ))} - + @@ -131,8 +111,8 @@ class LiveLog extends Component { this.checkBoxChange()} + checked={this.state.scrollEnabled} + onChange={() => this.toggleScroll()} /> {t("Automatic scrolling on update")} @@ -144,7 +124,7 @@ class LiveLog extends Component { export const TranslatedLiveLog = withTranslation(["live-log"])(LiveLog); -export default (props: any) => ( +export default () => ( { 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 => } + renderOk={data => ( + + )} renderErr={() => null} /> );