Reload user settings when changed externally (#4097)

* Reload user settings when changed externally

* Fix to not use any

* Make sure listener doesn't already exist

* Fix up projects reloading

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
This commit is contained in:
49fl
2024-10-07 23:07:18 -04:00
committed by GitHub
parent 7de0b74c16
commit 24cd1b2ea5
11 changed files with 151 additions and 79 deletions

View File

@ -1,4 +1,5 @@
import { isDesktop } from 'lib/isDesktop'
import { reportRejection } from 'lib/trap'
import { useEffect, useState, useRef } from 'react'
type Path = string
@ -11,13 +12,13 @@ type Path = string
// watcher.addListener(() => { ... }).
export const useFileSystemWatcher = (
callback: (path: Path) => void,
callback: (path: Path) => Promise<void>,
dependencyArray: Path[]
): void => {
// Track a ref to the callback. This is how we get the callback updated
// across the NodeJS<->Browser boundary.
const callbackRef = useRef<{ fn: (path: Path) => void }>({
fn: (_path) => {},
const callbackRef = useRef<{ fn: (path: Path) => Promise<void> }>({
fn: async (_path) => {},
})
useEffect(() => {
@ -35,7 +36,9 @@ export const useFileSystemWatcher = (
if (!isDesktop()) return
return () => {
window.electron.watchFileObliterate()
for (let path of dependencyArray) {
window.electron.watchFileOff(path)
}
}
}, [])
@ -46,6 +49,9 @@ export const useFileSystemWatcher = (
]
}
const hasDiff =
difference(dependencyArray, dependencyArrayTracked)[0].length !== 0
// Removing 1 watcher at a time is only possible because in a filesystem,
// a path is unique (there can never be two paths with the same name).
// Otherwise we would have to obliterate() the whole list and reconstruct it.
@ -53,6 +59,8 @@ export const useFileSystemWatcher = (
// The hook is useless on web.
if (!isDesktop()) return
if (!hasDiff) return
const [pathsRemoved, pathsRemaining] = difference(
dependencyArrayTracked,
dependencyArray
@ -62,10 +70,10 @@ export const useFileSystemWatcher = (
}
const [pathsAdded] = difference(dependencyArray, dependencyArrayTracked)
for (let path of pathsAdded) {
window.electron.watchFileOn(path, (_eventType: string, path: Path) =>
callbackRef.current.fn(path)
)
window.electron.watchFileOn(path, (_eventType: string, path: Path) => {
callbackRef.current.fn(path).catch(reportRejection)
})
}
setDependencyArrayTracked(pathsRemaining.concat(pathsAdded))
}, [difference(dependencyArray, dependencyArrayTracked)[0].length !== 0])
}, [hasDiff])
}