@launchmenu/core
Version:
An environment for visual keyboard controlled applets
270 lines • 16.9 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LaunchMenu = void 0;
const react_1 = __importStar(require("react"));
const path_1 = __importDefault(require("path"));
const model_react_1 = require("model-react");
const KeyHandler_1 = require("../keyHandler/KeyHandler");
const ThemeContext_1 = require("../styling/theming/ThemeContext");
const loadTheme_1 = require("../styling/theming/loadTheme");
const defaultTheme_1 = require("../styling/theming/defaultTheme");
const Transition_1 = require("../components/context/stacks/transitions/Transition");
const AppletManager_1 = require("./applets/AppletManager");
const SettingsFile_1 = require("../settings/storage/fileTypes/SettingsFile");
const baseSettings_1 = require("./settings/baseSettings/baseSettings");
const SessionManager_1 = require("./LMSession/SessionManager");
const SettingsManager_1 = require("./settings/SettingsManager");
const electron_1 = require("electron");
const useLM_1 = require("./hooks/useLM");
const wait_helper_1 = require("../_tests/wait.helper");
const GlobalKeyHandler_1 = require("../keyHandler/globalKeyHandler/GlobalKeyHandler");
/**
* The main LM class
*/
class LaunchMenu {
/***
* Creates a new instance of the LaunchMenu application,
* requires setup to be called before doing anything.
* @param config The application configuration
*/
constructor(config) {
this.devMode = new model_react_1.Field(false);
// Whether the LM window should be opened (A window manager applet will 'visualize' this state)
this.windowVisible = new model_react_1.Field(false);
this.windowWrapper = new model_react_1.Field(({ children }) => (react_1.default.createElement(react_1.Fragment, null, children)));
this.dataDirectory = path_1.default.join(config.root, "data");
this.settingsDirectory = path_1.default.join(this.dataDirectory, "settings");
}
/**
* Disposes of all runtime data
*/
destroy() {
const destroyables = [
this.keyHandler,
this.appletManager,
this.sessionManager,
this.sessionManager,
this.appletObserver,
this.globalKeyHandler,
];
// Destroy all items individually, making sure that if 1 item errors, the others still get destroyed
for (let destroyable of destroyables) {
try {
destroyable.destroy();
}
catch (e) {
console.error(e);
}
}
}
// Initialization
/**
* A method to initialize LaunchMenu
*/
async setup() {
if (this.keyHandler)
throw Error("Instance has already been set up");
this.setupKeyHandler();
this.setupTheme();
this.setupSettings();
this.setupApplets();
this.setupView();
this.setupGlobalKeyHandler();
this.sessionManager = new SessionManager_1.SessionManager(this);
this.sessionManager.addSession();
}
/**
* Initializes the theme
*/
setupTheme() {
// TODO: make theme local io context data
loadTheme_1.loadTheme(defaultTheme_1.defaultTheme);
}
/**
* Initializes the key handler for the application
*/
setupKeyHandler() {
this.keyHandler = new KeyHandler_1.KeyHandler(window).listen(key => {
var _a;
const top = (_a = this.sessionManager) === null || _a === void 0 ? void 0 : _a.getSelectedSession();
return top === null || top === void 0 ? void 0 : top.emit(key);
});
}
/**
* Initializes the the view
*/
setupView() {
this.view = (react_1.default.createElement(ThemeContext_1.ThemeProvider, null,
react_1.default.createElement(useLM_1.LaunchMenuProvider, { value: this },
react_1.default.createElement(model_react_1.Loader, null, h => {
var _a;
const Wrapper = this.windowWrapper.get(h);
return (react_1.default.createElement(Wrapper, null,
react_1.default.createElement(Transition_1.Transition, { skipMountAnimation: true }, (_a = this.sessionManager.getSelectedSession(h)) === null || _a === void 0 ? void 0 : _a.view)));
}))));
}
/**
* Initializes the applets manager
*/
setupApplets() {
this.appletManager = new AppletManager_1.AppletManager(this, {
directory: this.settingsDirectory,
getSettings: (applet, version) => this.settingsManager.updateAppletSettings(applet, version),
removeSettings: appletID => this.settingsManager.destroyAppletSetting(appletID),
});
// Add an observer, making sure that applets always instantly reload, even if no other component requests them.
// This is important because applets can have side effects, so even if nothing needs the applet, the applet may affect the system.
this.appletObserver = new model_react_1.Observer(h => this.appletManager.getApplets(h)).listen(() => { });
}
/**
* Initializes the settings
*/
setupSettings() {
this.settingsManager = new SettingsManager_1.SettingsManager(this, this.settingsDirectory, this.dataDirectory);
// Add the base settings
baseSettings_1.baseSettings.ID = "Base";
const settings = new SettingsFile_1.SettingsFile({
...baseSettings_1.baseSettings,
path: path_1.default.join(this.settingsDirectory, "baseSettings.json"),
});
this.settingsManager.addSettings(baseSettings_1.baseSettings.ID, settings);
}
/**
* Initialized the global key handler
*/
setupGlobalKeyHandler() {
const context = this.settingsManager.getSettingsContext();
const customGlobalKeyListener = context.get(baseSettings_1.baseSettings).customGlobalKeyListener;
this.globalKeyHandler = new GlobalKeyHandler_1.GlobalKeyHandler(h => !customGlobalKeyListener.get(h));
}
// Dev mode
/**
* Changes whether LaunchMenu is running in dev-mode
* @param enabled Whether in dev-mode
*/
setDevMode(enabled) {
this.devMode.set(enabled);
}
/**
* Retrieves whether LaunchMenu is running in dev-mode
* @param hook The hook to subscribe to changes
* @returns Whether dev mode is enabled
*/
isInDevMode(hook) {
return this.devMode.get(hook);
}
// Window
/**
* Retrieves whether the LaunchMenu window is currently opened
* @param hook The hook to subscribe to changes
* @returns Whether the window should be opened
*/
isWindowOpen(hook) {
return this.windowVisible.get(hook);
}
/**
* Sets whether the window should be opened
* @param open Whether the window should be opened
*/
async setWindowOpen(open) {
this.windowVisible.set(open);
// Add some delay for safety, since closing the window usually doesn't close instantly
// TODO: look into the possibility of making model-react listen for promises of listeners to resolve
return wait_helper_1.wait(10);
}
/**
* Sets the frame component to wrap all LM sessions in
* @param frame The component to use
*/
setWindowFrame(frame) {
this.windowWrapper.set(frame);
}
/**
* Retrieves the currently used frame component
* @param hook The hook to subscribe to changes
* @returns The functional component to use as the window frame
*/
getWindowFrame(hook) {
return this.windowWrapper.get(hook);
}
// Utils
/**
* Fully restarts the LaunchMenu window
*/
restart() {
electron_1.ipcRenderer.send("restart");
}
/**
* Fully shutdown LaunchMenu
*/
shutdown() {
electron_1.ipcRenderer.send("shutdown");
}
// General getters
/**
* Retrieves the key handler that listens for keyboard events and dispatches them
* @returns The key handler
*/
getKeyHandler() {
return this.keyHandler;
}
/**
* Retrieves the directory that all settings are stored in
* @returns The settings directory path
*/
getSettingsDirectory() {
return this.settingsDirectory;
}
/**
* Retrieves the applet manager that loads all applets
* @returns The applet manager
*/
getAppletManager() {
return this.appletManager;
}
/**
* Retrieves the session manager that manages the opened sessions
* @returns The session manager
*/
getSessionManager() {
return this.sessionManager;
}
/**
* Retrieves the settings manager that manages all applet and global settings
* @returns The settings manager
*/
getSettingsManager() {
return this.settingsManager;
}
/**
* Retrieves the global key handler that can be used to register keyboard callbacks even when LM is hidden
* @returns The global keyboard handler
*/
getGlobalKeyHandler() {
return this.globalKeyHandler;
}
}
exports.LaunchMenu = LaunchMenu;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGF1bmNoTWVudS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcHBsaWNhdGlvbi9MYXVuY2hNZW51LnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQTBDO0FBQzFDLGdEQUF3QjtBQUN4Qiw2Q0FBK0Q7QUFDL0QseURBQW9EO0FBQ3BELGtFQUE4RDtBQUM5RCw0REFBdUQ7QUFDdkQsa0VBQTZEO0FBQzdELG9GQUErRTtBQUMvRSwyREFBc0Q7QUFDdEQsNkVBQXdFO0FBQ3hFLHVFQUFrRTtBQUNsRSwrREFBMEQ7QUFDMUQsZ0VBQTJEO0FBRTNELHVDQUFxQztBQUNyQyx5Q0FBaUQ7QUFDakQsdURBQTJDO0FBQzNDLHNGQUFpRjtBQUlqRjs7R0FFRztBQUNILE1BQWEsVUFBVTtJQXNCbkI7Ozs7T0FJRztJQUNILFlBQW1CLE1BQTBCO1FBMUJuQyxZQUFPLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBZXJDLCtGQUErRjtRQUNyRixrQkFBYSxHQUFHLElBQUksbUJBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxrQkFBYSxHQUFHLElBQUksbUJBQUssQ0FBd0IsQ0FBQyxFQUFDLFFBQVEsRUFBQyxFQUFFLEVBQUUsQ0FBQyxDQUN2RSw4QkFBQyxnQkFBUSxRQUFFLFFBQVEsQ0FBWSxDQUNsQyxDQUFDLENBQUM7UUFRQyxJQUFJLENBQUMsYUFBYSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU87UUFDVixNQUFNLFlBQVksR0FBRztZQUNqQixJQUFJLENBQUMsVUFBVTtZQUNmLElBQUksQ0FBQyxhQUFhO1lBQ2xCLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxnQkFBZ0I7U0FDeEIsQ0FBQztRQUVGLG9HQUFvRztRQUNwRyxLQUFLLElBQUksV0FBVyxJQUFJLFlBQVksRUFBRTtZQUNsQyxJQUFJO2dCQUNBLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUN6QjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDcEI7U0FDSjtJQUNMLENBQUM7SUFFRCxpQkFBaUI7SUFDakI7O09BRUc7SUFDSSxLQUFLLENBQUMsS0FBSztRQUNkLElBQUksSUFBSSxDQUFDLFVBQWlCO1lBQUUsTUFBTSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSwrQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ08sVUFBVTtRQUNoQix5Q0FBeUM7UUFDekMscUJBQVMsQ0FBQywyQkFBWSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ08sZUFBZTtRQUNyQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksdUJBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUU7O1lBQ2xELE1BQU0sR0FBRyxTQUFHLElBQUksQ0FBQyxjQUFjLDBDQUFFLGtCQUFrQixFQUFFLENBQUM7WUFDdEQsT0FBTyxHQUFHLGFBQUgsR0FBRyx1QkFBSCxHQUFHLENBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUMxQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7T0FFRztJQUNPLFNBQVM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLENBQ1IsOEJBQUMsNEJBQWE7WUFDViw4QkFBQywwQkFBa0IsSUFBQyxLQUFLLEVBQUUsSUFBSTtnQkFDM0IsOEJBQUMsb0JBQU0sUUFDRixDQUFDLENBQUMsRUFBRTs7b0JBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzFDLE9BQU8sQ0FDSCw4QkFBQyxPQUFPO3dCQUNKLDhCQUFDLHVCQUFVLElBQUMsa0JBQWtCLGdCQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQywwQ0FBRSxJQUFJLENBQ3ZDLENBQ1AsQ0FDYixDQUFDO2dCQUNOLENBQUMsQ0FDSSxDQUNRLENBQ1QsQ0FDbkIsQ0FBQztJQUNOLENBQUM7SUFFRDs7T0FFRztJQUNPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDZCQUFhLENBQUMsSUFBSSxFQUFFO1lBQ3pDLFNBQVMsRUFBRSxJQUFJLENBQUMsaUJBQWlCO1lBQ2pDLFdBQVcsRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUM3QixJQUFJLENBQUMsZUFBZSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7WUFDOUQsY0FBYyxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDO1NBQzFELENBQUMsQ0FBQztRQUVILCtHQUErRztRQUMvRyxrSUFBa0k7UUFDbEksSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLHNCQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FDNUUsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUNYLENBQUM7SUFDTixDQUFDO0lBRUQ7O09BRUc7SUFDTyxhQUFhO1FBQ25CLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxpQ0FBZSxDQUN0QyxJQUFJLEVBQ0osSUFBSSxDQUFDLGlCQUFpQixFQUN0QixJQUFJLENBQUMsYUFBYSxDQUNyQixDQUFDO1FBRUYsd0JBQXdCO1FBQ3hCLDJCQUFZLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUN6QixNQUFNLFFBQVEsR0FBRyxJQUFJLDJCQUFZLENBQUM7WUFDOUIsR0FBRywyQkFBWTtZQUNmLElBQUksRUFBRSxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxtQkFBbUIsQ0FBQztTQUMvRCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQywyQkFBWSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7O09BRUc7SUFDTyxxQkFBcUI7UUFDM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFELE1BQU0sdUJBQXVCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBWSxDQUFDLENBQUMsdUJBQXVCLENBQUM7UUFDbEYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksbUNBQWdCLENBQ3hDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQ3ZDLENBQUM7SUFDTixDQUFDO0lBRUQsV0FBVztJQUNYOzs7T0FHRztJQUNJLFVBQVUsQ0FBQyxPQUFnQjtRQUM5QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFdBQVcsQ0FBQyxJQUFnQjtRQUMvQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxTQUFTO0lBQ1Q7Ozs7T0FJRztJQUNJLFlBQVksQ0FBQyxJQUFnQjtRQUNoQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsYUFBYSxDQUFDLElBQWE7UUFDcEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0IsdUZBQXVGO1FBQ3ZGLG9HQUFvRztRQUNwRyxPQUFPLGtCQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7T0FHRztJQUNJLGNBQWMsQ0FBQyxLQUE0QjtRQUM5QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLGNBQWMsQ0FBQyxJQUFnQjtRQUNsQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxRQUFRO0lBQ1I7O09BRUc7SUFDSSxPQUFPO1FBQ1Ysc0JBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksUUFBUTtRQUNYLHNCQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxrQkFBa0I7SUFDbEI7OztPQUdHO0lBQ0ksYUFBYTtRQUNoQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7T0FHRztJQUNJLG9CQUFvQjtRQUN2QixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksZ0JBQWdCO1FBQ25CLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM5QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksaUJBQWlCO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksa0JBQWtCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksbUJBQW1CO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO0lBQ2pDLENBQUM7Q0FDSjtBQTFSRCxnQ0EwUkMifQ==