236 lines
5.9 KiB
JavaScript
236 lines
5.9 KiB
JavaScript
// An interface used by the Desktop app to interact with SN
|
|
import _ from 'lodash';
|
|
import { isDesktopApplication } from '@/utils';
|
|
import { SFItemParams, SFModelManager } from 'snjs';
|
|
|
|
const COMPONENT_DATA_KEY_INSTALL_ERROR = 'installError';
|
|
const COMPONENT_CONTENT_KEY_PACKAGE_INFO = 'package_info';
|
|
const COMPONENT_CONTENT_KEY_LOCAL_URL = 'local_url';
|
|
|
|
export class DesktopManager {
|
|
/* @ngInject */
|
|
constructor(
|
|
$rootScope,
|
|
$timeout,
|
|
modelManager,
|
|
syncManager,
|
|
authManager,
|
|
passcodeManager,
|
|
appState
|
|
) {
|
|
this.passcodeManager = passcodeManager;
|
|
this.modelManager = modelManager;
|
|
this.authManager = authManager;
|
|
this.syncManager = syncManager;
|
|
this.$rootScope = $rootScope;
|
|
this.appState = appState;
|
|
this.timeout = $timeout;
|
|
this.updateObservers = [];
|
|
this.componentActivationObservers = [];
|
|
|
|
this.isDesktop = isDesktopApplication();
|
|
|
|
$rootScope.$on("initial-data-loaded", () => {
|
|
this.dataLoaded = true;
|
|
if(this.dataLoadHandler) {
|
|
this.dataLoadHandler();
|
|
}
|
|
});
|
|
|
|
$rootScope.$on("major-data-change", () => {
|
|
if(this.majorDataChangeHandler) {
|
|
this.majorDataChangeHandler();
|
|
}
|
|
});
|
|
}
|
|
|
|
saveBackup() {
|
|
this.majorDataChangeHandler && this.majorDataChangeHandler();
|
|
}
|
|
|
|
getExtServerHost() {
|
|
console.assert(
|
|
this.extServerHost,
|
|
'extServerHost is null'
|
|
);
|
|
return this.extServerHost;
|
|
}
|
|
|
|
/*
|
|
Sending a component in its raw state is really slow for the desktop app
|
|
Keys are not passed into ItemParams, so the result is not encrypted
|
|
*/
|
|
async convertComponentForTransmission(component) {
|
|
return new SFItemParams(component).paramsForExportFile(true);
|
|
}
|
|
|
|
// All `components` should be installed
|
|
syncComponentsInstallation(components) {
|
|
if(!this.isDesktop) {
|
|
return;
|
|
}
|
|
Promise.all(components.map((component) => {
|
|
return this.convertComponentForTransmission(component);
|
|
})).then((data) => {
|
|
this.installationSyncHandler(data);
|
|
});
|
|
}
|
|
|
|
async installComponent(component) {
|
|
this.installComponentHandler(
|
|
await this.convertComponentForTransmission(component)
|
|
);
|
|
}
|
|
|
|
registerUpdateObserver(callback) {
|
|
const observer = {
|
|
callback: callback
|
|
};
|
|
this.updateObservers.push(observer);
|
|
return observer;
|
|
}
|
|
|
|
searchText(text) {
|
|
if(!this.isDesktop) {
|
|
return;
|
|
}
|
|
this.lastSearchedText = text;
|
|
this.searchHandler && this.searchHandler(text);
|
|
}
|
|
|
|
redoSearch() {
|
|
if(this.lastSearchedText) {
|
|
this.searchText(this.lastSearchedText);
|
|
}
|
|
}
|
|
|
|
deregisterUpdateObserver(observer) {
|
|
_.pull(this.updateObservers, observer);
|
|
}
|
|
|
|
// Pass null to cancel search
|
|
desktop_setSearchHandler(handler) {
|
|
this.searchHandler = handler;
|
|
}
|
|
|
|
desktop_windowGainedFocus() {
|
|
this.$rootScope.$broadcast("window-gained-focus");
|
|
}
|
|
|
|
desktop_windowLostFocus() {
|
|
this.$rootScope.$broadcast("window-lost-focus");
|
|
}
|
|
|
|
desktop_onComponentInstallationComplete(componentData, error) {
|
|
const component = this.modelManager.findItem(componentData.uuid);
|
|
if(!component) {
|
|
return;
|
|
}
|
|
if(error) {
|
|
component.setAppDataItem(
|
|
COMPONENT_DATA_KEY_INSTALL_ERROR,
|
|
error
|
|
);
|
|
} else {
|
|
const permissableKeys = [
|
|
COMPONENT_CONTENT_KEY_PACKAGE_INFO,
|
|
COMPONENT_CONTENT_KEY_LOCAL_URL
|
|
];
|
|
for(const key of permissableKeys) {
|
|
component[key] = componentData.content[key];
|
|
}
|
|
this.modelManager.notifySyncObserversOfModels(
|
|
[component],
|
|
SFModelManager.MappingSourceDesktopInstalled
|
|
);
|
|
component.setAppDataItem(
|
|
COMPONENT_DATA_KEY_INSTALL_ERROR,
|
|
null
|
|
);
|
|
}
|
|
this.modelManager.setItemDirty(component);
|
|
this.syncManager.sync();
|
|
this.timeout(() => {
|
|
for(const observer of this.updateObservers) {
|
|
observer.callback(component);
|
|
}
|
|
});
|
|
}
|
|
|
|
desktop_registerComponentActivationObserver(callback) {
|
|
const observer = {id: Math.random, callback: callback};
|
|
this.componentActivationObservers.push(observer);
|
|
return observer;
|
|
}
|
|
|
|
desktop_deregisterComponentActivationObserver(observer) {
|
|
_.pull(this.componentActivationObservers, observer);
|
|
}
|
|
|
|
/* Notify observers that a component has been registered/activated */
|
|
async notifyComponentActivation(component) {
|
|
const serializedComponent = await this.convertComponentForTransmission(
|
|
component
|
|
);
|
|
this.timeout(() => {
|
|
for(const observer of this.componentActivationObservers) {
|
|
observer.callback(serializedComponent);
|
|
}
|
|
});
|
|
}
|
|
|
|
/* Used to resolve "sn://" */
|
|
desktop_setExtServerHost(host) {
|
|
this.extServerHost = host;
|
|
this.appState.desktopExtensionsReady();
|
|
}
|
|
|
|
desktop_setComponentInstallationSyncHandler(handler) {
|
|
this.installationSyncHandler = handler;
|
|
}
|
|
|
|
desktop_setInstallComponentHandler(handler) {
|
|
this.installComponentHandler = handler;
|
|
}
|
|
|
|
desktop_setInitialDataLoadHandler(handler) {
|
|
this.dataLoadHandler = handler;
|
|
if(this.dataLoaded) {
|
|
this.dataLoadHandler();
|
|
}
|
|
}
|
|
|
|
async desktop_requestBackupFile(callback) {
|
|
let keys, authParams;
|
|
if(this.authManager.offline() && this.passcodeManager.hasPasscode()) {
|
|
keys = this.passcodeManager.keys();
|
|
authParams = this.passcodeManager.passcodeAuthParams();
|
|
} else {
|
|
keys = await this.authManager.keys();
|
|
authParams = await this.authManager.getAuthParams();
|
|
}
|
|
const nullOnEmpty = true;
|
|
this.modelManager.getAllItemsJSONData(
|
|
keys,
|
|
authParams,
|
|
nullOnEmpty
|
|
).then((data) => {
|
|
callback(data);
|
|
});
|
|
}
|
|
|
|
desktop_setMajorDataChangeHandler(handler) {
|
|
this.majorDataChangeHandler = handler;
|
|
}
|
|
|
|
desktop_didBeginBackup() {
|
|
this.appState.beganBackupDownload();
|
|
}
|
|
|
|
desktop_didFinishBackup(success) {
|
|
this.appState.endedBackupDownload({
|
|
success: success
|
|
});
|
|
}
|
|
}
|