Feat/62 logger (#79)

* feat/62-logger request log data in app
* feat/62-logger refact osc integration
* feat/62-logger feedback on osc
* feat/62-logger refact broadcast on triggers
* feat/62-logger log triggers
* feat/62-logger add link to studio
* feat/62-logger replace toasts with logger context
* feat/62-logger style improvements
* feat/62-logger refactor code duplications
* feat/62-logger cleanup and version bump
This commit is contained in:
Carlos Valente
2021-12-25 19:39:40 +01:00
committed by GitHub
parent 160ccabebc
commit 9fc154955a
46 changed files with 3830 additions and 598 deletions
+4 -6
View File
@@ -15,11 +15,10 @@ export default function Info() {
titleNext: '',
subtitleNext: '',
presenterNext: '',
noteNext: '',
noteNext: ''
});
const [selected, setSelected] = useState('No events');
const [playback, setPlayback] = useState(null);
const logData = [];
// handle incoming messages
useEffect(() => {
@@ -61,20 +60,19 @@ export default function Info() {
};
}, [socket]);
// TODO: Put this in use effect
// prepare data
const titlesNow = {
title: titles.titleNow,
subtitle: titles.subtitleNow,
presenter: titles.presenterNow,
note: titles.noteNow,
note: titles.noteNow
};
const titlesNext = {
title: titles.titleNext,
subtitle: titles.subtitleNext,
presenter: titles.presenterNext,
note: titles.noteNext,
note: titles.noteNext
};
return (
@@ -83,10 +81,10 @@ export default function Info() {
<span>{`Running on port 4001`}</span>
<span>{selected}</span>
</div>
{/* <InfoLogger logData={logData} /> */}
<InfoNif />
<InfoTitle title={'Now'} data={titlesNow} roll={playback === 'roll'} />
<InfoTitle title={'Next'} data={titlesNext} roll={playback === 'roll'} />
<InfoLogger />
</>
);
}
+17 -32
View File
@@ -1,4 +1,6 @@
.container {
@use '../../main' as *;
@mixin container {
margin-top: 1em;
display: flex;
flex-direction: column;
@@ -8,9 +10,13 @@
padding: 8px;
}
.container {
@include container;
}
.main {
font-size: 0.9em;
color: #ff7597;
color: $ontime-pink;
display: flex;
justify-content: space-between;
}
@@ -20,17 +26,17 @@
padding: 0;
margin: 0;
font-size: 0.9em;
color: #ccc;
color: $header-gray;
display: flex;
justify-content: space-between;
}
.header {
color: #ccc;
color: $header-gray;
}
.headerRoll {
color: #2b6cb0;
color: $ontime-roll;
}
.collapsedTitle {
@@ -57,7 +63,7 @@
.label {
font-size: 0.9em;
color: #aaa;
color: $label-gray;
}
.label::after {
@@ -70,43 +76,22 @@
}
.notes {
color: #d69e2e;
color: $notes-color;
overflow: hidden;
text-overflow: ellipsis;
}
.if {
font-size: 0.8em;
color: #4bffabcc;
background-color: rgba(0, 0, 0, 0.13);
border-radius: 2px;
padding: 0 0.5em;
margin: 0 0.5em;
color: $ontime-accent;
@include container-bg;
}
.log {
overflow-y: scroll;
height: 30vh;
ul > li {
font-size: 0.9em;
color: #fff;
}
}
.info {
ul > li {
font-size: 0.9em;
color: #fff;
}
.error {
color: red;
}
.client {
color: lightblue;
}
.moreExpanded,
.moreCollapsed {
cursor: pointer;
+108 -25
View File
@@ -1,34 +1,117 @@
import { Icon } from '@chakra-ui/react';
import { useState } from 'react';
import { FiChevronUp } from 'react-icons/fi';
import style from './Info.module.scss';
import { useContext, useEffect, useState } from 'react';
import style from './InfoLogger.module.scss';
import CollapseBar from "../../common/components/collapseBar/CollapseBar";
import { LoggingContext } from '../../app/context/LoggingContext';
export default function InfoLogger(props) {
export default function InfoLogger() {
const { logData, clearLog } = useContext(LoggingContext);
const [data, setData] = useState([]);
const [collapsed, setCollapsed] = useState(false);
// Todo: save in local storage
const [showClient, setShowClient] = useState(true);
const [showServer, setShowServer] = useState(true);
const [showRx, setShowRx] = useState(true);
const [showTx, setShowTx] = useState(true);
const [showPlayback, setShowPlayback] = useState(true);
const [showUser, setShowUser] = useState(true);
const { logData } = props;
useEffect(() => {
const matchers = [];
if (showUser) {
matchers.push('USER');
}
if (showClient) {
matchers.push('CLIENT');
}
if (showServer) {
matchers.push('SERVER');
}
if (showRx) {
matchers.push('RX');
}
if (showTx) {
matchers.push('TX');
}
if (showPlayback) {
matchers.push('PLAYBACK');
}
const d = logData.filter((d) => (
matchers.some((m) => d.origin === m)
))
setData(d);
},[logData, showUser, showClient, showServer, showPlayback, showRx, showTx])
const disableOthers = (toEnable) => {
toEnable === 'USER' ? setShowUser(true) : setShowUser(false);
toEnable === 'CLIENT' ? setShowClient(true) : setShowClient(false);
toEnable === 'SERVER' ? setShowServer(true) : setShowServer(false);
toEnable === 'RX' ? setShowRx(true) : setShowRx(false);
toEnable === 'TX' ? setShowTx(true) : setShowTx(false);
toEnable === 'PLAYBACK' ? setShowPlayback(true) : setShowPlayback(false);
}
return (
<div className={style.container}>
<div className={style.header}>
Log
<Icon
className={collapsed ? style.moreCollapsed : style.moreExpanded}
as={FiChevronUp}
onClick={() => setCollapsed((c) => !c)}
/>
</div>
<div className={collapsed ? style.container : style.container__expanded}>
<CollapseBar title={'Log'} isCollapsed={collapsed} onClick={() => setCollapsed((c) => !c)}/>
{!collapsed && (
<ul className={style.log}>
<li className={style.info}>10:35:23 [PLAYBACK] Next</li>
<li className={style.client}>
10:32:10 [CLIENT] New socket client (total: 3)
</li>
<li className={style.info}>10:28:23 [PLAYBACK] Next</li>
<li className={style.info}>10:25:23 [PLAYBACK] Play</li>
<li className={style.info}>10:23:13 [SERVER] Server Reconnected</li>
<li className={style.error}>10:23:10 [SERVER] Server Disconnected</li>
</ul>
<>
<div className={style.toggleBar}>
<div
onClick={() => setShowUser((s) => !s)}
onAuxClick={() => disableOthers('USER')}
className={(showUser) ? style.active : null}>
USER
</div>
<div
onClick={() => setShowClient((s) => !s)}
onAuxClick={() => disableOthers('CLIENT')}
className={(showClient) ? style.active : null}>
CLIENT
</div>
<div
onClick={() => setShowServer((s) => !s)}
onAuxClick={() => disableOthers('SERVER')}
className={(showServer) ? style.active : null}>
SERVER
</div>
<div
onClick={() => setShowPlayback((s) => !s)}
onAuxClick={() => disableOthers('PLAYBACK')}
className={(showPlayback) ? style.active : null}>
Playback
</div>
<div
onClick={() => setShowRx((s) => !s)}
onAuxClick={() => disableOthers('RX')}
className={(showRx) ? style.active : null}>
RX
</div>
<div
onClick={() => setShowTx((s) => !s)}
onAuxClick={() => disableOthers('TX')}
className={(showTx) ? style.active : null}>
TX
</div>
<div
onClick={clearLog}
className={style.clear}>
Clear
</div>
</div>
<ul className={style.log}>
{data.map((d) => (
<li key={d.id} className={d.level === 'INFO' ? style.info : d.level === 'WARN' ? style.warn : d.level === 'ERROR' ? style.error : ''}>
<div
className={style.time}
>{d.time}</div>
<div className={style.origin}>{d.origin}</div>
<div className={style.msg}>{d.text}</div>
</li>
))}
</ul>
</>
)}
</div>
);
@@ -0,0 +1,89 @@
@use 'Info.module' as *;
@use '../../main' as *;
.container,
.container__expanded{
@include container;
max-height: 80%;
}
.container__expanded {
min-height: 50%;
height: 100%
}
.log {
height: 100%;
overflow-y: scroll;
font-size: 0.8em;
user-select:text;
@include container-bg;
li {
display: flex;
margin-bottom: 2px;
.time {
width: 13%;
}
.origin {
width: 18%;
}
.msg {
width: 70%;
}
}
li.info {
color: #aaa;
}
li.warn {
color: #dd6b20;
}
li.error {
color: #f00;
}
.entry:hover {
color: #ddd;
}
}
.info {
color: #fff;
}
.error {
color: red;
}
.client {
color: lightblue;
}
.toggleBar {
display: flex;
font-size: 0.7em;
justify-content: flex-start;
gap: 1em;
padding: 0.5em 0;
font-weight: 600;
div {
padding: 2px 8px;
background: #0002;
border: 1px solid #fff1;
border-radius: 2px;
cursor: pointer;
}
div.active {
background: $ontime-accent;
color: darken($ontime-accent, 70%);
}
.clear {
border: 1px solid rgba($ontime-pink, 0.5);
}
}
+3 -12
View File
@@ -1,10 +1,9 @@
import { Icon } from '@chakra-ui/react';
import { useState } from 'react';
import { FiChevronUp } from 'react-icons/fi';
import { APP_TABLE } from 'app/api/apiConstants';
import { getInfo, ontimePlaceholderInfo } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch';
import style from './Info.module.scss';
import CollapseBar from '../../common/components/collapseBar/CollapseBar';
export default function InfoNif() {
const { data, status } = useFetch(APP_TABLE, getInfo, {
@@ -22,16 +21,8 @@ export default function InfoNif() {
};
return (
<div className={style.container}>
<div className={style.header}>
Network Info
<Icon
className={collapsed ? style.moreCollapsed : style.moreExpanded}
as={FiChevronUp}
onClick={() => setCollapsed((c) => !c)}
/>
</div>
<div className={style.container}>
<CollapseBar title={'Network Info'} isCollapsed={collapsed} onClick={() => setCollapsed((c) => !c)}/>
{!collapsed && (
<div>
{status === 'success' && (