Work towards it
This commit is contained in:
parent
8a728abffe
commit
275b763648
3 changed files with 82 additions and 40 deletions
|
@ -5,7 +5,6 @@ import path from "node:path";
|
|||
import { FolderWatch } from "../../types/ipc";
|
||||
import log from "../log";
|
||||
import { watchStore } from "../stores/watch";
|
||||
import { getElectronFile } from "./fs";
|
||||
|
||||
/**
|
||||
* Create and return a new file system watcher.
|
||||
|
@ -16,42 +15,41 @@ import { getElectronFile } from "./fs";
|
|||
* pertinent file system events.
|
||||
*/
|
||||
export const createWatcher = (mainWindow: BrowserWindow) => {
|
||||
const mappings = getWatchMappings();
|
||||
const folderPaths = mappings.map((mapping) => {
|
||||
return mapping.folderPath;
|
||||
});
|
||||
const send = (eventName: string) => (path: string) =>
|
||||
mainWindow.webContents.send(eventName, ...eventData(path));
|
||||
|
||||
const folderPaths = folderWatches().map((watch) => watch.folderPath);
|
||||
|
||||
const watcher = chokidar.watch(folderPaths, {
|
||||
awaitWriteFinish: true,
|
||||
});
|
||||
|
||||
watcher
|
||||
.on("add", async (path) => {
|
||||
mainWindow.webContents.send(
|
||||
"watch-add",
|
||||
await getElectronFile(normalizeToPOSIX(path)),
|
||||
);
|
||||
})
|
||||
.on("unlink", (path) => {
|
||||
mainWindow.webContents.send("watch-unlink", normalizeToPOSIX(path));
|
||||
})
|
||||
.on("unlinkDir", (path) => {
|
||||
mainWindow.webContents.send(
|
||||
"watch-unlink-dir",
|
||||
normalizeToPOSIX(path),
|
||||
);
|
||||
})
|
||||
.on("error", (error) => {
|
||||
log.error("Error while watching files", error);
|
||||
});
|
||||
.on("add", send("addFile"))
|
||||
.on("unlink", send("removeFile"))
|
||||
.on("unlinkDir", send("removeDir"))
|
||||
.on("error", (error) => log.error("Error while watching files", error));
|
||||
|
||||
return watcher;
|
||||
};
|
||||
|
||||
const eventData = (path: string): [string, FolderWatch] => {
|
||||
path = posixPath(path);
|
||||
|
||||
const watch = folderWatches().find((watch) =>
|
||||
path.startsWith(watch.folderPath + "/"),
|
||||
);
|
||||
|
||||
if (!watch) throw new Error(`No folder watch was found for path ${path}`);
|
||||
|
||||
return [path, watch];
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a file system {@link filePath} that uses the local system specific
|
||||
* path separators into a path that uses POSIX file separators.
|
||||
*/
|
||||
const normalizeToPOSIX = (filePath: string) =>
|
||||
const posixPath = (filePath: string) =>
|
||||
filePath.split(path.sep).join(path.posix.sep);
|
||||
|
||||
export const findFiles = async (dirPath: string) => {
|
||||
|
@ -156,10 +154,10 @@ export function updateWatchMappingIgnoredFiles(
|
|||
setWatchMappings(watchMappings);
|
||||
}
|
||||
|
||||
export function getWatchMappings() {
|
||||
export const folderWatches = () => {
|
||||
const mappings = watchStore.get("mappings") ?? [];
|
||||
return mappings;
|
||||
}
|
||||
};
|
||||
|
||||
function setWatchMappings(watchMappings: WatchStoreType["mappings"]) {
|
||||
watchStore.set("mappings", watchMappings);
|
||||
|
|
|
@ -96,7 +96,7 @@ class FolderWatcher {
|
|||
this.setCollectionName = setCollectionName;
|
||||
this.syncWithRemote = syncWithRemote;
|
||||
this.setWatchFolderServiceIsRunning = setWatchFolderServiceIsRunning;
|
||||
this.setupWatcherFunctions();
|
||||
this.registerListeners();
|
||||
await this.syncWithDisk();
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ class FolderWatcher {
|
|||
* collection do files belonging to nested directories go to.
|
||||
*/
|
||||
async addWatch(folderPath: string, mapping: CollectionMapping) {
|
||||
await ensureElectron().watch.add(folderPath, mapping);
|
||||
await ensureElectron().watcher.add(folderPath, mapping);
|
||||
this.syncWithDisk();
|
||||
}
|
||||
|
||||
|
@ -165,8 +165,14 @@ class FolderWatcher {
|
|||
this.trashingDirQueue.push(path);
|
||||
}
|
||||
|
||||
private setupWatcherFunctions() {
|
||||
ensureElectron().registerWatcherFunctions(
|
||||
private registerListeners() {
|
||||
const watch = ensureElectron().watcher;
|
||||
|
||||
// [Note: File renames during folder watch]
|
||||
//
|
||||
// Renames come as two file system events - an `onAddFile` + an
|
||||
// `onRemoveFile` - in an arbitrary order.
|
||||
watch.onAddFile(
|
||||
diskFileAddedCallback,
|
||||
diskFileRemovedCallback,
|
||||
diskFolderRemovedCallback,
|
||||
|
@ -594,9 +600,9 @@ interface WatchEvent {
|
|||
filePath: string;
|
||||
}
|
||||
|
||||
async function diskFileAddedCallback(file: ElectronFile) {
|
||||
const onAddFile = async (path: string) => {
|
||||
const collectionNameAndFolderPath =
|
||||
await watcher.getCollectionNameAndFolderPath(file.path);
|
||||
await watcher.getCollectionNameAndFolderPath(path);
|
||||
|
||||
if (!collectionNameAndFolderPath) {
|
||||
return;
|
||||
|
@ -604,13 +610,12 @@ async function diskFileAddedCallback(file: ElectronFile) {
|
|||
|
||||
const { collectionName, folderPath } = collectionNameAndFolderPath;
|
||||
|
||||
const event: EventQueueItem = {
|
||||
type: "upload",
|
||||
watcher.pushEvent({
|
||||
action: "upload",
|
||||
collectionName,
|
||||
folderPath,
|
||||
path: file.path,
|
||||
};
|
||||
watcher.pushEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
async function diskFileRemovedCallback(filePath: string) {
|
||||
|
@ -701,7 +706,7 @@ const deduceEvents = async (
|
|||
for (const watch of activeWatches) {
|
||||
const folderPath = watch.folderPath;
|
||||
|
||||
const paths = (await electron.watch.findFiles(folderPath))
|
||||
const paths = (await electron.watcher.findFiles(folderPath))
|
||||
// Filter out hidden files (files whose names begins with a dot)
|
||||
.filter((path) => !isHiddenFile(path));
|
||||
|
||||
|
@ -741,7 +746,7 @@ const isSyncedOrIgnoredPath = (path: string, watch: FolderWatch) =>
|
|||
|
||||
const collectionNameForPath = (filePath: string, watch: FolderWatch) =>
|
||||
watch.collectionMapping == "root"
|
||||
? watch.rootFolderName
|
||||
? dirname(watch.folderPath)
|
||||
: parentDirectoryName(filePath);
|
||||
|
||||
const parentDirectoryName = (path: string) => basename(dirname(path));
|
||||
|
|
|
@ -275,7 +275,7 @@ export interface Electron {
|
|||
// - Watch
|
||||
|
||||
/**
|
||||
* Functions tailored for the folder watch functionality
|
||||
* Interface with the file system watcher running in our Node.js layer.
|
||||
*
|
||||
* [Note: Folder vs Directory in the context of FolderWatch-es]
|
||||
*
|
||||
|
@ -288,7 +288,7 @@ export interface Electron {
|
|||
* dragged/dropped or selected to set up the folder watch, will be referred
|
||||
* to as a folder when naming things.
|
||||
*/
|
||||
watch: {
|
||||
watcher: {
|
||||
/**
|
||||
* Return the paths of all the files under the given folder.
|
||||
*
|
||||
|
@ -333,6 +333,45 @@ export interface Electron {
|
|||
* is no longer present, and returns this pruned list of watches.
|
||||
*/
|
||||
get: () => Promise<FolderWatch[]>;
|
||||
|
||||
/**
|
||||
* Register the function to invoke when a file is added in one of the
|
||||
* folders we are watching.
|
||||
*
|
||||
* The callback function is passed the path to the file that was added,
|
||||
* and the folder watch it was associated with.
|
||||
*
|
||||
* The path is guaranteed to use POSIX separators ('/').
|
||||
*/
|
||||
onAddFile: (
|
||||
f: (path: string, watch: FolderWatch) => void,
|
||||
) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Register the function to invoke when a file is removed in one of the
|
||||
* folders we are watching.
|
||||
*
|
||||
* The callback function is passed the path to the file that was
|
||||
* removed, and the folder watch it was associated with.
|
||||
*
|
||||
* The path is guaranteed to use POSIX separators ('/').
|
||||
*/
|
||||
onRemoveFile: (
|
||||
f: (path: string, watch: FolderWatch) => void,
|
||||
) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Register the function to invoke when a directory is removed in one of
|
||||
* the folders we are watching.
|
||||
*
|
||||
* The callback function is passed the path to the directory that was
|
||||
* removed, and the folder watch it was associated with.
|
||||
*
|
||||
* The path is guaranteed to use POSIX separators ('/').
|
||||
*/
|
||||
onRemoveDir: (
|
||||
f: (path: string, watch: FolderWatch) => void,
|
||||
) => Promise<void>;
|
||||
};
|
||||
|
||||
registerWatcherFunctions: (
|
||||
|
|
Loading…
Reference in a new issue