fix(ui): improve scan status handling (again) (#4115)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { useNotify, useTranslate } from 'react-admin'
|
import { useNotify, useTranslate } from 'react-admin'
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
@@ -15,11 +15,11 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
} from '@material-ui/core'
|
} from '@material-ui/core'
|
||||||
import { FiActivity } from 'react-icons/fi'
|
import { FiActivity } from 'react-icons/fi'
|
||||||
import { BiError, BiCheckCircle } from 'react-icons/bi'
|
import { BiError } from 'react-icons/bi'
|
||||||
import { VscSync } from 'react-icons/vsc'
|
import { VscSync } from 'react-icons/vsc'
|
||||||
import { GiMagnifyingGlass } from 'react-icons/gi'
|
import { GiMagnifyingGlass } from 'react-icons/gi'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import { scanStatusUpdate } from '../actions'
|
import { useInitialScanStatus } from './useInitialScanStatus'
|
||||||
import { useInterval } from '../common'
|
import { useInterval } from '../common'
|
||||||
import { useScanElapsedTime } from './useScanElapsedTime'
|
import { useScanElapsedTime } from './useScanElapsedTime'
|
||||||
import { formatDuration, formatShortDuration } from '../utils'
|
import { formatDuration, formatShortDuration } from '../utils'
|
||||||
@@ -80,24 +80,12 @@ const ActivityPanel = () => {
|
|||||||
const notify = useNotify()
|
const notify = useNotify()
|
||||||
const [anchorEl, setAnchorEl] = useState(null)
|
const [anchorEl, setAnchorEl] = useState(null)
|
||||||
const open = Boolean(anchorEl)
|
const open = Boolean(anchorEl)
|
||||||
const dispatch = useDispatch()
|
useInitialScanStatus()
|
||||||
|
|
||||||
const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)
|
const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)
|
||||||
const handleMenuClose = () => setAnchorEl(null)
|
const handleMenuClose = () => setAnchorEl(null)
|
||||||
const triggerScan = (full) => () => subsonic.startScan({ fullScan: full })
|
const triggerScan = (full) => () => subsonic.startScan({ fullScan: full })
|
||||||
|
|
||||||
// Get updated status on component mount
|
|
||||||
useEffect(() => {
|
|
||||||
subsonic
|
|
||||||
.getScanStatus()
|
|
||||||
.then((resp) => resp.json['subsonic-response'])
|
|
||||||
.then((data) => {
|
|
||||||
if (data.status === 'ok') {
|
|
||||||
dispatch(scanStatusUpdate(data.scanStatus))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [dispatch])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (serverStart.version && serverStart.version !== config.version) {
|
if (serverStart.version && serverStart.version !== config.version) {
|
||||||
notify('ra.notification.new_version', 'info', {}, false, 604800000 * 50)
|
notify('ra.notification.new_version', 'info', {}, false, 604800000 * 50)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
import subsonic from '../subsonic'
|
||||||
|
import { scanStatusUpdate } from '../actions'
|
||||||
|
|
||||||
|
export const useInitialScanStatus = () => {
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
useEffect(() => {
|
||||||
|
subsonic
|
||||||
|
.getScanStatus()
|
||||||
|
.then((resp) => resp.json['subsonic-response'])
|
||||||
|
.then((data) => {
|
||||||
|
if (data.status === 'ok') {
|
||||||
|
dispatch(scanStatusUpdate(data.scanStatus))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [dispatch])
|
||||||
|
}
|
||||||
@@ -6,16 +6,17 @@ export const useScanElapsedTime = (scanning, elapsedTime) => {
|
|||||||
const prevScanningRef = useRef(scanning)
|
const prevScanningRef = useRef(scanning)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Only update from server when scan starts or stops
|
|
||||||
const prevScanning = prevScanningRef.current
|
const prevScanning = prevScanningRef.current
|
||||||
if (!prevScanning && scanning) {
|
const serverElapsed = Number(elapsedTime) || 0
|
||||||
// Scan just started - initialize with server value
|
|
||||||
setElapsed(Number(elapsedTime) || 0)
|
if (scanning !== prevScanning) {
|
||||||
} else if (prevScanning && !scanning) {
|
// Scan has just started or stopped - sync with server value
|
||||||
// Scan just finished - use final server value
|
setElapsed(serverElapsed)
|
||||||
setElapsed(Number(elapsedTime) || 0)
|
} else if (!scanning) {
|
||||||
|
// Not scanning -> always reflect server value (initial load or after finish)
|
||||||
|
setElapsed(serverElapsed)
|
||||||
}
|
}
|
||||||
// Update ref for next comparison
|
|
||||||
prevScanningRef.current = scanning
|
prevScanningRef.current = scanning
|
||||||
}, [scanning, elapsedTime])
|
}, [scanning, elapsedTime])
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,20 @@ describe('useScanElapsedTime', () => {
|
|||||||
expect(result.current).toBe(12e9)
|
expect(result.current).toBe(12e9)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('updates elapsed time when not scanning and server value changes', () => {
|
||||||
|
const { result, rerender } = renderHook(
|
||||||
|
({ scanning, elapsed }) => useScanElapsedTime(scanning, elapsed),
|
||||||
|
{
|
||||||
|
initialProps: { scanning: false, elapsed: 0 },
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Server reports new elapsed time without changing scanning state
|
||||||
|
rerender({ scanning: false, elapsed: 8e9 })
|
||||||
|
|
||||||
|
expect(result.current).toBe(8e9)
|
||||||
|
})
|
||||||
|
|
||||||
it('ignores server updates during scanning', () => {
|
it('ignores server updates during scanning', () => {
|
||||||
const { result, rerender } = renderHook(
|
const { result, rerender } = renderHook(
|
||||||
({ scanning, elapsed }) => useScanElapsedTime(scanning, elapsed),
|
({ scanning, elapsed }) => useScanElapsedTime(scanning, elapsed),
|
||||||
|
|||||||
Reference in New Issue
Block a user