Add Uptime to Activity Panel
This commit is contained in:
+2
-2
@@ -27,7 +27,7 @@ import createAdminStore from './store/createAdminStore'
|
||||
import { i18nProvider } from './i18n'
|
||||
import config from './config'
|
||||
import { startEventStream } from './eventStream'
|
||||
import { processEvent } from './actions'
|
||||
|
||||
const history = createHashHistory()
|
||||
|
||||
if (config.gaTrackingId) {
|
||||
@@ -60,7 +60,7 @@ const App = () => (
|
||||
const Admin = (props) => {
|
||||
const dispatch = useDispatch()
|
||||
if (config.devActivityMenu) {
|
||||
startEventStream((data) => dispatch(processEvent(data)))
|
||||
startEventStream(dispatch)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
export const EVENT_SCAN_STATUS = 'EVENT_SCAN_STATUS'
|
||||
export const EVENT_SERVER_START = 'EVENT_SERVER_START'
|
||||
|
||||
const actionsMap = { scanStatus: EVENT_SCAN_STATUS }
|
||||
const actionsMap = {
|
||||
scanStatus: EVENT_SCAN_STATUS,
|
||||
serverStart: EVENT_SERVER_START,
|
||||
}
|
||||
|
||||
export const processEvent = (data) => {
|
||||
let type = actionsMap[data.name]
|
||||
@@ -11,8 +15,12 @@ export const processEvent = (data) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const scanStatusUpdate = (data) =>
|
||||
processEvent({
|
||||
name: EVENT_SCAN_STATUS,
|
||||
data: data,
|
||||
})
|
||||
export const scanStatusUpdate = (data) => ({
|
||||
type: EVENT_SCAN_STATUS,
|
||||
data: data,
|
||||
})
|
||||
|
||||
export const serverDown = () => ({
|
||||
type: EVENT_SERVER_START,
|
||||
data: {},
|
||||
})
|
||||
|
||||
+24
-13
@@ -1,9 +1,13 @@
|
||||
import { baseUrl } from './utils'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { processEvent, serverDown } from './actions'
|
||||
|
||||
let es = null
|
||||
let onMessageHandler = null
|
||||
let timeOut = null
|
||||
let dispatch = null
|
||||
let timeout = null
|
||||
const defaultIntervalCheck = 20000
|
||||
const errorIntervalCheck = 2000
|
||||
let currentIntervalCheck = defaultIntervalCheck
|
||||
|
||||
const getEventStream = () => {
|
||||
if (es === null) {
|
||||
@@ -15,22 +19,23 @@ const getEventStream = () => {
|
||||
}
|
||||
|
||||
// Reestablish the event stream after 20 secs of inactivity
|
||||
const setTimeout = () => {
|
||||
if (timeOut != null) {
|
||||
window.clearTimeout(timeOut)
|
||||
const setTimeout = (value) => {
|
||||
currentIntervalCheck = value
|
||||
if (timeout != null) {
|
||||
window.clearTimeout(timeout)
|
||||
}
|
||||
timeOut = window.setTimeout(() => {
|
||||
timeout = window.setTimeout(() => {
|
||||
if (es != null) {
|
||||
es.close()
|
||||
}
|
||||
es = null
|
||||
startEventStream(onMessageHandler)
|
||||
}, 20000)
|
||||
startEventStream(dispatch)
|
||||
}, currentIntervalCheck)
|
||||
}
|
||||
|
||||
export const startEventStream = (messageHandler) => {
|
||||
onMessageHandler = messageHandler
|
||||
setTimeout()
|
||||
export const startEventStream = (dispatchFunc) => {
|
||||
dispatch = dispatchFunc
|
||||
setTimeout(currentIntervalCheck)
|
||||
if (!localStorage.getItem('token')) {
|
||||
console.log('Cannot create a unauthenticated EventSource')
|
||||
return
|
||||
@@ -40,11 +45,17 @@ export const startEventStream = (messageHandler) => {
|
||||
(msg) => {
|
||||
const data = JSON.parse(msg.data)
|
||||
if (data.name !== 'keepAlive') {
|
||||
onMessageHandler(data)
|
||||
dispatch(processEvent(data))
|
||||
}
|
||||
setTimeout() // Reset timeout on every received message
|
||||
setTimeout(defaultIntervalCheck) // Reset timeout on every received message
|
||||
},
|
||||
100,
|
||||
{ trailing: true }
|
||||
)
|
||||
es.onerror = (e) => {
|
||||
setTimeout(errorIntervalCheck)
|
||||
dispatch(serverDown())
|
||||
}
|
||||
|
||||
return es
|
||||
}
|
||||
|
||||
+3
-1
@@ -291,7 +291,9 @@
|
||||
"title": "Activity",
|
||||
"totalScanned": "Total Folders Scanned",
|
||||
"quickScan": "Quick Scan",
|
||||
"fullScan": "Full Scan"
|
||||
"fullScan": "Full Scan",
|
||||
"serverUptime": "Server Uptime",
|
||||
"serverDown": "OFFLINE"
|
||||
},
|
||||
"player": {
|
||||
"playListsText": "Play Queue",
|
||||
|
||||
@@ -15,14 +15,18 @@ import {
|
||||
Box,
|
||||
} from '@material-ui/core'
|
||||
import { FiActivity } from 'react-icons/fi'
|
||||
import { BiError } from 'react-icons/bi'
|
||||
import { VscSync } from 'react-icons/vsc'
|
||||
import { GiMagnifyingGlass } from 'react-icons/gi'
|
||||
import subsonic from '../subsonic'
|
||||
import { scanStatusUpdate } from '../actions'
|
||||
import { useInterval } from '../common'
|
||||
import { formatDuration } from '../utils'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
wrapper: {
|
||||
position: 'relative',
|
||||
color: (props) => (props.up ? null : 'orange'),
|
||||
},
|
||||
progress: {
|
||||
color: theme.palette.primary.light,
|
||||
@@ -36,17 +40,31 @@ const useStyles = makeStyles((theme) => ({
|
||||
zIndex: 2,
|
||||
},
|
||||
counterStatus: {
|
||||
minWidth: '16em',
|
||||
minWidth: '15em',
|
||||
},
|
||||
}))
|
||||
|
||||
const getUptime = (serverStart) =>
|
||||
formatDuration((Date.now() - serverStart.startTime) / 1000)
|
||||
|
||||
const Uptime = () => {
|
||||
const serverStart = useSelector((state) => state.activity.serverStart)
|
||||
const [uptime, setUptime] = useState(getUptime(serverStart))
|
||||
useInterval(() => {
|
||||
setUptime(getUptime(serverStart))
|
||||
}, 1000)
|
||||
return <span>{uptime}</span>
|
||||
}
|
||||
|
||||
const ActivityPanel = () => {
|
||||
const classes = useStyles()
|
||||
const serverStart = useSelector((state) => state.activity.serverStart)
|
||||
const up = serverStart && serverStart.startTime
|
||||
const classes = useStyles({ up })
|
||||
const translate = useTranslate()
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
const open = Boolean(anchorEl)
|
||||
const scanStatus = useSelector((state) => state.activity.scanStatus)
|
||||
const dispatch = useDispatch()
|
||||
const scanStatus = useSelector((state) => state.activity.scanStatus)
|
||||
|
||||
const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)
|
||||
const handleMenuClose = () => setAnchorEl(null)
|
||||
@@ -70,7 +88,7 @@ const ActivityPanel = () => {
|
||||
<Tooltip title={translate('activity.title')}>
|
||||
<IconButton className={classes.button} onClick={handleMenuOpen}>
|
||||
<Badge badgeContent={null} color="secondary">
|
||||
<FiActivity size={'20'} />
|
||||
{up ? <FiActivity size={'20'} /> : <BiError size={'20'} />}
|
||||
</Badge>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
@@ -92,6 +110,17 @@ const ActivityPanel = () => {
|
||||
onClose={handleMenuClose}
|
||||
>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Box display="flex" className={classes.counterStatus}>
|
||||
<Box component="span" flex={2}>
|
||||
{translate('activity.serverUptime')}:
|
||||
</Box>
|
||||
<Box component="span" flex={1}>
|
||||
{up ? <Uptime /> : translate('activity.serverDown')}
|
||||
</Box>
|
||||
</Box>
|
||||
</CardContent>
|
||||
<Divider />
|
||||
<CardContent>
|
||||
<Box display="flex" className={classes.counterStatus}>
|
||||
<Box component="span" flex={2}>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { EVENT_SCAN_STATUS } from '../actions'
|
||||
import { EVENT_SCAN_STATUS, EVENT_SERVER_START } from '../actions'
|
||||
|
||||
const defaultState = { scanStatus: { scanning: false, count: 0 } }
|
||||
|
||||
export const activityReducer = (
|
||||
previousState = {
|
||||
scanStatus: { scanning: false, count: 0 },
|
||||
scanStatus: defaultState,
|
||||
},
|
||||
payload
|
||||
) => {
|
||||
@@ -10,6 +12,13 @@ export const activityReducer = (
|
||||
switch (type) {
|
||||
case EVENT_SCAN_STATUS:
|
||||
return { ...previousState, scanStatus: data }
|
||||
case EVENT_SERVER_START:
|
||||
return {
|
||||
...previousState,
|
||||
serverStart: {
|
||||
startTime: data.startTime && Date.parse(data.startTime),
|
||||
},
|
||||
}
|
||||
default:
|
||||
return previousState
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user