Event listeners
This commit is contained in:
parent
500bac0b32
commit
0e9703f770
1 changed files with 47 additions and 81 deletions
|
@ -39,8 +39,16 @@ class FolderWatcher {
|
|||
private currentEvent: WatchEvent;
|
||||
// TODO(MR): dedup if possible
|
||||
private isEventRunning: boolean = false;
|
||||
/**
|
||||
* If the file system directory corresponding to the (root) folder path of a
|
||||
* folder watch is deleted on disk, we note down that in this queue so that
|
||||
* we can ignore any file system events that come for it next.
|
||||
*
|
||||
* TODO (MR): is this really even coming into play? the mappings are
|
||||
* pre-checked first.
|
||||
*/
|
||||
private deletedFolderPaths: string[] = [];
|
||||
private currentlySyncedMapping: FolderWatch;
|
||||
private trashingDirQueue: string[] = [];
|
||||
private filePathToUploadedFileIDMap = new Map<string, EncryptedEnteFile>();
|
||||
private unUploadableFilePaths = new Set<string>();
|
||||
private setElectronFiles: (files: ElectronFile[]) => void;
|
||||
|
@ -139,12 +147,11 @@ class FolderWatcher {
|
|||
|
||||
private async syncWithDisk() {
|
||||
try {
|
||||
const electron = ensureElectron();
|
||||
const mappings = await electron.getWatchMappings();
|
||||
if (!mappings) return;
|
||||
const watches = await this.getWatches();
|
||||
if (!watches) return;
|
||||
|
||||
this.eventQueue = [];
|
||||
const { events } = await deduceEvents(mappings);
|
||||
const events = await deduceEvents(watches);
|
||||
log.info(`Folder watch deduced ${events.length} events`);
|
||||
this.eventQueue = this.eventQueue.concat(events);
|
||||
|
||||
|
@ -160,22 +167,40 @@ class FolderWatcher {
|
|||
this.debouncedRunNextEvent();
|
||||
}
|
||||
|
||||
async pushTrashedDir(path: string) {
|
||||
this.trashingDirQueue.push(path);
|
||||
}
|
||||
|
||||
private registerListeners() {
|
||||
const watch = ensureElectron().watcher;
|
||||
const watch = ensureElectron().watch;
|
||||
|
||||
// [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,
|
||||
);
|
||||
|
||||
watch.onAddFile((path: string, watch: FolderWatch) => {
|
||||
this.pushEvent({
|
||||
action: "upload",
|
||||
collectionName: collectionNameForPath(path, watch),
|
||||
folderPath: watch.folderPath,
|
||||
filePath: path,
|
||||
});
|
||||
});
|
||||
|
||||
watch.onRemoveFile((path: string, watch: FolderWatch) => {
|
||||
this.pushEvent({
|
||||
action: "trash",
|
||||
collectionName: collectionNameForPath(path, watch),
|
||||
folderPath: watch.folderPath,
|
||||
filePath: path,
|
||||
});
|
||||
});
|
||||
|
||||
watch.onRemoveDir((path: string, watch: FolderWatch) => {
|
||||
if (path == watch.folderPath) {
|
||||
log.info(
|
||||
`Received file system delete event for a watched folder at ${path}`,
|
||||
);
|
||||
this.deletedFolderPaths.push(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async runNextEvent() {
|
||||
|
@ -446,7 +471,7 @@ class FolderWatcher {
|
|||
|
||||
private async processTrashEvent() {
|
||||
try {
|
||||
if (this.checkAndIgnoreIfFileEventsFromTrashedDir()) {
|
||||
if (this.pruneFileEventsFromDeletedFolderPaths()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -502,19 +527,14 @@ class FolderWatcher {
|
|||
}
|
||||
}
|
||||
|
||||
private checkAndIgnoreIfFileEventsFromTrashedDir() {
|
||||
if (this.trashingDirQueue.length !== 0) {
|
||||
this.ignoreFileEventsFromTrashedDir(this.trashingDirQueue[0]);
|
||||
this.trashingDirQueue.shift();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private pruneFileEventsFromDeletedFolderPaths() {
|
||||
const deletedFolderPath = this.deletedFolderPaths.shift();
|
||||
if (!deletedFolderPath) return false;
|
||||
|
||||
private ignoreFileEventsFromTrashedDir(trashingDir: string) {
|
||||
this.eventQueue = this.eventQueue.filter((event) =>
|
||||
event.paths.every((path) => !path.startsWith(trashingDir)),
|
||||
this.eventQueue = this.eventQueue.filter(
|
||||
(event) => !event.filePath.startsWith(deletedFolderPath),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
async getCollectionNameAndFolderPath(filePath: string) {
|
||||
|
@ -594,60 +614,6 @@ interface WatchEvent {
|
|||
filePath: string;
|
||||
}
|
||||
|
||||
const onAddFile = async (path: string) => {
|
||||
const collectionNameAndFolderPath =
|
||||
await watcher.getCollectionNameAndFolderPath(path);
|
||||
|
||||
if (!collectionNameAndFolderPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { collectionName, folderPath } = collectionNameAndFolderPath;
|
||||
|
||||
watcher.pushEvent({
|
||||
action: "upload",
|
||||
collectionName,
|
||||
folderPath,
|
||||
path: file.path,
|
||||
});
|
||||
};
|
||||
|
||||
async function diskFileRemovedCallback(filePath: string) {
|
||||
const collectionNameAndFolderPath =
|
||||
await watcher.getCollectionNameAndFolderPath(filePath);
|
||||
|
||||
if (!collectionNameAndFolderPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { collectionName, folderPath } = collectionNameAndFolderPath;
|
||||
|
||||
const event: EventQueueItem = {
|
||||
type: "trash",
|
||||
collectionName,
|
||||
folderPath,
|
||||
path: filePath,
|
||||
};
|
||||
watcher.pushEvent(event);
|
||||
}
|
||||
|
||||
async function diskFolderRemovedCallback(folderPath: string) {
|
||||
try {
|
||||
const mappings = await watcher.getWatchMappings();
|
||||
const mapping = mappings.find(
|
||||
(mapping) => mapping.folderPath === folderPath,
|
||||
);
|
||||
if (!mapping) {
|
||||
log.info(`folder not found in mappings, ${folderPath}`);
|
||||
throw Error(`Watch mapping not found`);
|
||||
}
|
||||
watcher.pushTrashedDir(folderPath);
|
||||
log.info(`added trashedDir, ${folderPath}`);
|
||||
} catch (e) {
|
||||
log.error("error while calling diskFolderRemovedCallback", e);
|
||||
}
|
||||
}
|
||||
|
||||
export function getValidFilesToUpload(
|
||||
files: ElectronFile[],
|
||||
mapping: FolderWatch,
|
||||
|
|
Loading…
Reference in a new issue