Skip to content
23 changes: 12 additions & 11 deletions examples/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ const handlers = { handleAdd, handleHydrate, handleDehydrate, handleChangeSize }
const notify = { onTaskSuccess: async () => undefined, onTaskProcessing: async () => undefined };
const queueManager = new QueueManager(handlers, notify, settings.queuePersistPath);

drive.registerSyncRoot(settings.driveName, settings.driveVersion, settings.providerid, callbacks, settings.iconPath);
drive.connectSyncRoot();

try {
initInfoItems();
drive.watchAndWait(settings.syncRootPath, queueManager, settings.watcherLogPath);
} catch (error) {
logger.error(error);
drive.disconnectSyncRoot();
VirtualDrive.unregisterSyncRoot(settings.syncRootPath);
}
drive.registerSyncRoot(settings.driveName, settings.driveVersion, settings.providerid, callbacks, settings.iconPath).then(() => {
drive.connectSyncRoot();

try {
initInfoItems();
drive.watchAndWait(settings.syncRootPath, queueManager, settings.watcherLogPath);
} catch (error) {
logger.error(error);
drive.disconnectSyncRoot();
VirtualDrive.unregisterSyncRoot(settings.syncRootPath);
}
});
30 changes: 30 additions & 0 deletions src/get-placeholder-states.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { readdir } from "fs/promises";
import { join } from "path";

import { isFileInDevice } from "./is-file-in-device";
import VirtualDrive from "./virtual-drive";

type TProps = {
self: VirtualDrive;
path: string;
};

export const getPlaceholderStates = async ({ self, path }: TProps) => {
const files = await readdir(path, { withFileTypes: true });

const promises = files.map(async (file) => {
const filePath = join(path, file.name);

if (file.isDirectory()) {
return getPlaceholderStates({ self, path: filePath });
} else {
const status = self.getPlaceholderState(filePath);
if (isFileInDevice(status)) {
const id = self.getFileIdentity(filePath);
self.watcher.fileInDevice.add(id);
}
}
});

await Promise.all(promises);
};
12 changes: 12 additions & 0 deletions src/is-file-in-device.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PinState, SyncState } from "./types/placeholder.type";

type TProps = {
syncState: SyncState;
pinState: PinState;
};

export const isFileInDevice = ({ syncState, pinState }: TProps) => {
const inSync = syncState === SyncState.InSync;
const isHydrated = pinState === PinState.AlwaysLocal || pinState === PinState.Unspecified;
return inSync && isHydrated;
};
17 changes: 16 additions & 1 deletion src/virtual-drive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IQueueManager } from "./queue/queueManager";

import { createLogger } from "./logger";
import { Addon } from "./addon-wrapper";
import { getPlaceholderStates } from "./get-placeholder-states";
import winston from "winston";

const addon = new Addon();
Expand Down Expand Up @@ -154,7 +155,21 @@ class VirtualDrive {
callbacks: Callbacks,
logoPath: string
): Promise<any> {
this.callbacks = callbacks;
this.callbacks = {
...callbacks,
fetchDataCallback: (...args) => {
const id = args[0];
this.watcher.fileInDevice.add(id);
return callbacks.fetchDataCallback?.(...args);
}
};

try {
await getPlaceholderStates({ self: this, path: this.syncRootPath});
} catch (exc) {
this.logger.error("getPlaceholderStates", exc)
}

return addon.registerSyncRoot({
providerName,
providerVersion,
Expand Down
57 changes: 18 additions & 39 deletions src/watcher/detect-context-menu-action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class DetectContextMenuActionService {

const status = self.addon.getPlaceholderState({ path });
const itemId = self.addon.getFileIdentity({ path });
const isInDevice = self.fileInDevice.has(path);
const isInDevice = self.fileInDevice.has(itemId) || self.fileInDevice.has(path);

self.logger.info({
event: "change",
Expand All @@ -31,48 +31,27 @@ export class DetectContextMenuActionService {
},
});

if (
prev.size === curr.size &&
prev.ctimeMs !== curr.ctimeMs &&
prev.mtimeMs === curr.mtimeMs &&
status.pinState === PinState.AlwaysLocal &&
status.syncState === SyncState.InSync &&
!isInDevice
) {
self.fileInDevice.add(path);

if (curr.blocks !== 0) {
// This event is triggered from the addon
return "Doble click en el archivo";
}

self.queueManager.enqueue({ path, type: typeQueue.hydrate, isFolder, fileId: itemId });
return "Mantener siempre en el dispositivo";
}

if (
prev.size === curr.size &&
prev.ctimeMs !== curr.ctimeMs &&
status.pinState == PinState.OnlineOnly &&
status.syncState == SyncState.InSync
) {
// TODO: we need to disable this for now even if dehydate it's called two times
// because files that are a .zip have blocks === 0, so they never dehydrate
// because it's seems that it's already been dehydrated
// if (curr.blocks === 0) {
// return "Liberando espacio";
// }

self.fileInDevice.delete(path);
self.queueManager.enqueue({ path, type: typeQueue.dehydrate, isFolder, fileId: itemId });
return "Liberar espacio";
}

// TODO: check same size but different content
if (prev.size !== curr.size) {
self.queueManager.enqueue({ path, type: typeQueue.changeSize, isFolder, fileId: itemId });
self.fileInDevice.add(path);
self.fileInDevice.add(itemId);
return "Cambio de tamaño";
}

if (prev.ctimeMs !== curr.ctimeMs && status.syncState === SyncState.InSync) {
if (status.pinState === PinState.AlwaysLocal && !isInDevice) {
self.fileInDevice.add(itemId);
self.queueManager.enqueue({ path, type: typeQueue.hydrate, isFolder, fileId: itemId });
return "Mantener siempre en el dispositivo";
}

if (status.pinState == PinState.OnlineOnly && isInDevice) {
self.fileInDevice.delete(path);
self.fileInDevice.delete(itemId);
self.queueManager.enqueue({ path, type: typeQueue.dehydrate, isFolder, fileId: itemId });
return "Liberar espacio";
}
}
}
}

Expand Down