mirror of
https://github.com/rhysd/Mstdn.git
synced 2025-02-01 05:52:11 +01:00
give plugins the ability to make custom key shortcuts
This commit is contained in:
parent
f01dea80ea
commit
bfbb758ff7
37
README.md
37
README.md
@ -312,7 +312,7 @@ Make `package.json` manually or by `$ npm init` in the directory.
|
||||
}
|
||||
```
|
||||
|
||||
Finally make `index.js` as below:
|
||||
And make `index.js` as below:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
@ -324,7 +324,31 @@ module.exports = {
|
||||
|
||||
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`.
|
||||
The function receives two parameters `config` and `account`.
|
||||
|
||||
By defining `keymaps` key you can define plugin-defined key shortcut action.
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
preload(config, account) {
|
||||
console.log('Hello from plugin!', config, account);
|
||||
},
|
||||
keymaps: {
|
||||
'alert-hello'(event, config, account) {
|
||||
event.preventDefault();
|
||||
alert('Hello, ' + account.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The object of `keymaps` has keymap action name (key) and its handler (value). Here 'alert-hello'
|
||||
key shortcut action is defined. Key shortcut handler takes 3 arguments. `config` and `account`
|
||||
is the same as `preload`'s. `event` is a `KeyboardEvent` browser event on the key shortcut
|
||||
being called. You can cancel default event behavior by `.preventDefault()` method.
|
||||
|
||||
User can specify the key shortcut as `plugin:{plugin name}:{action name}`. In above example,
|
||||
`plugin:hello:alert-hello` is available in `keymaps` section in config.json.
|
||||
|
||||
Note that you can use below APIs in the script.
|
||||
|
||||
@ -354,6 +378,8 @@ $ npm install mstdn-plugin-hello
|
||||
|
||||
And then write what plugin should be loaded to `"plugins"` section of your account in `config.json`.
|
||||
`"hello"` should be added to the list.
|
||||
If listed plugin defines some keymaps, you can specify it in `keymaps` section with
|
||||
`plugin:{name}:{action}` format.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -368,12 +394,17 @@ And then write what plugin should be loaded to `"plugins"` section of your accou
|
||||
]
|
||||
}
|
||||
],
|
||||
"keymaps": {
|
||||
...
|
||||
|
||||
"ctrl+h": "plugin:hello:alert-hello"
|
||||
},
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can enable different plugin for each your accounts.
|
||||
Note that you can enable different plugin for each your accounts.
|
||||
|
||||
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.
|
||||
|
@ -6,6 +6,6 @@ import PluginsLoader from './plugins';
|
||||
Ipc.on('mstdn:config', (c: Config, a: Account) => {
|
||||
const loader = new PluginsLoader(c, a);
|
||||
loader.loadAfterAppPrepared();
|
||||
setupKeymaps(c, a);
|
||||
setupKeymaps(c, a, loader);
|
||||
document.title = `${document.title} @${a.name}@${a.host}`;
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import {remote} from 'electron';
|
||||
import * as Mousetrap from 'mousetrap';
|
||||
import * as Ipc from './ipc';
|
||||
import log from './log';
|
||||
import PluginsLoader from './plugins';
|
||||
import {Config, Account} from '../main/config';
|
||||
|
||||
function scrollable() {
|
||||
@ -58,6 +59,7 @@ const ShortcutActions = {
|
||||
export default function setupKeymaps(
|
||||
config: Config,
|
||||
account: Account,
|
||||
loader: PluginsLoader,
|
||||
) {
|
||||
const dataDir = config.__DATA_DIR || '/';
|
||||
for (const key in config.keymaps) {
|
||||
@ -85,6 +87,16 @@ export default function setupKeymaps(
|
||||
log.error('Failed to run shortcut script ' + script, e);
|
||||
}
|
||||
});
|
||||
} else if (action.startsWith('plugin:')) {
|
||||
// Format is 'plugin:{name}:{action}'
|
||||
const split = action.split(':').slice(1);
|
||||
if (split.length <= 1) {
|
||||
log.error('Invalid format keymap. Plugin-defined action should be "plugin:{name}:{action}":', action);
|
||||
continue;
|
||||
}
|
||||
Mousetrap.bind(key, e => {
|
||||
loader.runKeyShortcut(e, split[0], split[1]);
|
||||
});
|
||||
} else if (action.startsWith('/')) {
|
||||
Mousetrap.bind(key, e => {
|
||||
e.preventDefault();
|
||||
|
@ -3,7 +3,10 @@ import {Config, Account} from '../main/config';
|
||||
import log from './log';
|
||||
|
||||
interface Plugin {
|
||||
preload(c: Config, a: Account): void;
|
||||
preload?(c: Config, a: Account): void;
|
||||
keymaps?: {
|
||||
[action: string]: (e: KeyboardEvent, c: Config, a: Account) => void;
|
||||
};
|
||||
}
|
||||
interface Plugins {
|
||||
[module_path: string]: Plugin;
|
||||
@ -83,4 +86,34 @@ export default class PluginsLoader {
|
||||
log.info('Plugins were loaded:', this.preloads);
|
||||
return true;
|
||||
}
|
||||
|
||||
findPluginByName(name: string): Plugin | null {
|
||||
const pluginName = `mstdn-plugin-${name}`;
|
||||
for (const p in this.preloads) {
|
||||
if (p.endsWith(pluginName)) {
|
||||
return this.preloads[p];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
runKeyShortcut(event: KeyboardEvent, name: string, action: string) {
|
||||
const plugin = this.findPluginByName(name);
|
||||
if (plugin === null) {
|
||||
log.error(`While trying to execute key shortcut '${action}', plugin for '${name}' not found:`, this.preloads);
|
||||
return;
|
||||
}
|
||||
|
||||
const f = (plugin.keymaps || {})[action];
|
||||
if (!f) {
|
||||
log.error(`There is no key shortcut action '${action}' in plugin '${name}'`, plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
f(event, this.config, this.account);
|
||||
} catch (e) {
|
||||
log.error(`Error while executing plugin-defined key short action: ${action} with plugin '${name}'`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user