1
0
mirror of https://github.com/rhysd/Mstdn.git synced 2025-01-21 20:52:11 +01:00

move plugins config into account config

This commit is contained in:
rhysd 2017-04-25 17:30:18 +09:00
parent 73c0a73e14
commit 3d4237e677
3 changed files with 51 additions and 28 deletions

View File

@ -134,12 +134,15 @@ You need to write up this config at first.
If `true` is specified, Chromium's native sandbox is enabled (and default value is `true`). If `true` is specified, Chromium's native sandbox is enabled (and default value is `true`).
Sandbox provides some OS level security protection such as resource access control like tabs Sandbox provides some OS level security protection such as resource access control like tabs
in Chromium. However, sandbox also blocks preload scripts for Electron application. in Chromium. However, sandbox also blocks plugins for Electron application.
If `false` is specified, you can use some advanced features (user CSS and key shortcut plugin). If `false` is specified, you can use some advanced features (user CSS and key shortcut plugin).
Before setting `false` to this value, please read and understand [sandbox documentation in Electron repo][sandbox doc] Before setting `false` to this value, please read and understand [sandbox documentation in Electron repo][sandbox doc]
to know what you're doing. to know what you're doing.
Please note that this sandbox feature is different from Node.js integration in Electron. Node.js
integration is always disabled.
### `keymaps` ### `keymaps`
Object whose key is a key sequence and whose value is an action name. Object whose key is a key sequence and whose value is an action name.
@ -281,27 +284,27 @@ body {
} }
``` ```
## Preload Plugin (experimental) ## Plugin (experimental)
You can make a Node.js package which is preloaded before loading inner mastodon page. You can make a Node.js package which is run inner mastodon page.
Preload plugin is enabled if `chromium_sandbox` option is set to `false`. Please read above Plugin is enabled if `chromium_sandbox` option is set to `false`. Please read above
configuration section before using any plugin. configuration section before using any plugin.
### How to make a plugin ### How to make a plugin
Create `node_modules` directory in your application directory at first. And then, please make Create `node_modules` directory in your application directory at first. And then, please make
`mstdn-preload-hello` directory. It consists a node package. `mstdn-plugin-hello` directory. It consists a node package.
Package name must start with `mastdn-preload-`. Package name must start with `mastdn-plugin-`.
Make `package.json` manually or by `$ npm init` in the directory. Make `package.json` manually or by `$ npm init` in the directory.
```json ```json
{ {
"name": "mstdn-preload-hello", "name": "mstdn-plugin-hello",
"version": "0.0.0", "version": "0.0.0",
"description": "sample of preload plugin of Mstdn.app", "description": "Sample plugin of Mstdn.app",
"main": "index.js", "main": "index.js",
"author": "Your name", "author": "Your name",
"license": "Some license" "license": "Some license"
@ -311,12 +314,16 @@ Make `package.json` manually or by `$ npm init` in the directory.
Finally make `index.js` as below: Finally make `index.js` as below:
```javascript ```javascript
module.exports = (config, account) => { module.exports = {
preload(config, account) {
console.log('Hello from plugin!', config, account); console.log('Hello from plugin!', config, account);
} }
};
``` ```
Package must export one function which receives two parameters `config` and `account`. Package must export one object.
If the object has a function as a value of `preload` key, it will be called at page being loaded.
The function which receives two parameters `config` and `account`.
Note that you can use below APIs in the script. Note that you can use below APIs in the script.
@ -337,28 +344,36 @@ window.my_require = require;
### How to use ### How to use
If you didn't try above 'How to make' section, please install plugin package at first. If you didn't try above 'How to make' section, please install plugin package at first.
Below will install 'hello' plugin to `{app directory}/node_modules/mstdn-preload-hello`. Below will install 'hello' plugin to `{app directory}/node_modules/mstdn-plugin-hello`.
``` ```
$ cd {Your application directory} $ cd {Your application directory}
$ npm install mstdn-preload-hello $ npm install mstdn-plugin-hello
``` ```
And then write what plugin should be loaded to `"preload"` section of your `config.json`. And then write what plugin should be loaded to `"plugins"` section of your account in `config.json`.
`"hello"` should be added to the list. `"hello"` should be added to the list.
```json ```json
{ {
... ...
"preload" [ "accounts": [
{
...
"plugins": [
"hello" "hello"
]
}
], ],
... ...
} }
``` ```
You can enable different plugin for each your accounts.
Finally open Mstdn.app and see DevTools via [Menu] -> [View] -> [Developper Tools] -> console. Finally open Mstdn.app and see DevTools via [Menu] -> [View] -> [Developper Tools] -> console.
If window is too small to see DevTools, please make window size bigger. If window is too small to see DevTools, please make window size bigger.

View File

@ -7,6 +7,7 @@ export interface Account {
host: string; host: string;
name: string; name: string;
default_page: string; default_page: string;
plugins: string[];
} }
export interface Config { export interface Config {
@ -20,7 +21,6 @@ export interface Config {
chromium_sandbox: boolean; chromium_sandbox: boolean;
__DATA_DIR?: string; __DATA_DIR?: string;
keymaps: {[key: string]: string}; keymaps: {[key: string]: string};
preload: string[];
} }
function makeDefaultConfig(): Config { function makeDefaultConfig(): Config {
@ -39,6 +39,7 @@ function makeDefaultConfig(): Config {
name: '', name: '',
host: '', host: '',
default_page: '/web/timelines/home', default_page: '/web/timelines/home',
plugins: [],
}], }],
keymaps: { keymaps: {
j: 'scroll-down', j: 'scroll-down',
@ -52,7 +53,6 @@ function makeDefaultConfig(): Config {
5: '/web/timelines/public', 5: '/web/timelines/public',
6: '/web/getting-started' 6: '/web/getting-started'
}, },
preload: [],
}; };
} }

View File

@ -3,7 +3,9 @@ import {Config, Account} from '../main/config';
import r from './require'; import r from './require';
import log from './log'; import log from './log';
type Plugin = (c: Config, a: Account) => void; interface Plugin {
preload(c: Config, a: Account): void;
}
interface Plugins { interface Plugins {
[module_path: string]: Plugin; [module_path: string]: Plugin;
} }
@ -17,13 +19,13 @@ export default class PluginsLoader {
this.preloads = {}; this.preloads = {};
if (config.chromium_sandbox) { if (config.chromium_sandbox) {
log.info('Chromium sandbox is enabled. Preload plugin is disabled.'); log.info('Chromium sandbox is enabled. Plugin is disabled.');
return; return;
} }
const dir_base = path.join(config.__DATA_DIR!, 'node_modules'); const dir_base = path.join(config.__DATA_DIR!, 'node_modules');
for (const plugin of config.preload || []) { for (const plugin of this.account.plugins || []) {
const plugin_path = path.join(dir_base, `mstdn-preload-${plugin}`); const plugin_path = path.join(dir_base, `mstdn-plugin-${plugin}`);
try { try {
this.preloads[plugin_path] = r(plugin_path) as Plugin; this.preloads[plugin_path] = r(plugin_path) as Plugin;
} catch (e) { } catch (e) {
@ -34,7 +36,7 @@ export default class PluginsLoader {
loadAfterAppPrepared() { loadAfterAppPrepared() {
if (Object.keys(this.preloads).length === 0) { if (Object.keys(this.preloads).length === 0) {
log.info('No preload plugin found. Skip loading'); log.info('No Plugin found. Skip loading');
this.loaded = true; this.loaded = true;
return; return;
} }
@ -43,7 +45,7 @@ export default class PluginsLoader {
// In order not to prevent application's initial loading, load preload plugins // In order not to prevent application's initial loading, load preload plugins
// on an idle callback. // on an idle callback.
window.requestIdleCallback(() => { window.requestIdleCallback(() => {
log.debug('Start loading preload plugins', this.config, this.account); log.debug('Start loading plugins', this.preloads);
if (this.tryLoading()) { if (this.tryLoading()) {
return resolve(); return resolve();
} }
@ -55,6 +57,8 @@ export default class PluginsLoader {
observeAppPrepared(callback: () => void) { observeAppPrepared(callback: () => void) {
// TODO: // TODO:
// Make an instance of MutationObserver to observe React root. // Make an instance of MutationObserver to observe React root.
// But it may be unnecessary because application shell is rendered
// in server side.
return Promise.resolve(callback()); return Promise.resolve(callback());
} }
@ -65,15 +69,19 @@ export default class PluginsLoader {
} }
for (const key in this.preloads) { for (const key in this.preloads) {
const f = this.preloads[key]; const f = this.preloads[key].preload;
if (!f) {
log.info('Plugin does not have preload function. Skipped:', key);
continue;
}
try { try {
f(this.config, this.account); f(this.config, this.account);
} catch (e) { } catch (e) {
log.error(`Error while loading preload plugin '${key}':`, e); log.error(`Error while loading plugin '${key}':`, e);
} }
} }
log.info('Preload plugins were loaded:', this.preloads); log.info('Plugins were loaded:', this.preloads);
return true; return true;
} }
} }