Files
plugin-manager/test/electron/plugins/example-plugin/index.js

238 lines
7.8 KiB
JavaScript

/**
* Example plugin — demonstrates every PluginContext API surface.
* Loaded as CommonJS by the test harness (eval'd via new Function).
*/
module.exports = {
name: 'Example Plugin',
version: '1.0.0',
/** @param {import('@paarrot/plugin-manager').PluginContext} ctx */
onLoad(ctx) {
// -------------------------------------------------------------------------
// Settings — persisted to storage automatically
// -------------------------------------------------------------------------
ctx.settings.define({
greeting: {
type: 'string',
label: 'Greeting word',
default: 'Hello',
},
autoExpand: {
type: 'boolean',
label: 'Auto-expand abbreviations (brb, omw, afk)',
default: true,
},
logLevel: {
type: 'select',
label: 'Log verbosity',
default: 'normal',
options: [
{ value: 'quiet', label: 'Quiet' },
{ value: 'normal', label: 'Normal' },
{ value: 'verbose', label: 'Verbose' },
],
},
});
// -------------------------------------------------------------------------
// Commands
// -------------------------------------------------------------------------
ctx.commands.register({
name: 'hello',
description: 'Greet someone',
args: [{ name: 'name', type: 'string', required: false, description: 'Who to greet' }],
run(args) {
const greeting = ctx.settings.get('greeting') ?? 'Hello';
return `${greeting}, ${args.name || 'World'}!`;
},
});
ctx.commands.register({
name: 'echo',
description: 'Echo text back',
args: [{ name: 'text', type: 'string', description: 'Text to echo' }],
run: (args) => args.text || '(nothing)',
});
ctx.commands.register({
name: 'roll',
description: 'Roll a dice — /roll <sides>',
args: [{ name: 'sides', type: 'number', description: 'Number of sides (default 6)' }],
run(args) {
const sides = parseInt(args.sides, 10) || 6;
const result = Math.floor(Math.random() * sides) + 1;
return `Rolled a d${sides}: ${result}`;
},
});
ctx.commands.register({
name: 'setting',
description: 'Read a plugin setting — /setting <key>',
args: [{ name: 'key', type: 'string' }],
run(args) {
const val = ctx.settings.get(args.key);
return val !== undefined ? `${args.key} = ${JSON.stringify(val)}` : `Setting "${args.key}" not found`;
},
});
// -------------------------------------------------------------------------
// Message interceptors
// -------------------------------------------------------------------------
ctx.messages.onBeforeSend((msg) => {
if (!ctx.settings.get('autoExpand')) return;
msg.content = msg.content
.replace(/\bbrb\b/gi, 'be right back')
.replace(/\bomw\b/gi, 'on my way')
.replace(/\bafk\b/gi, 'away from keyboard');
if (ctx.settings.get('logLevel') === 'verbose') {
ctx.log('beforeSend interceptor ran');
}
});
ctx.messages.onReceive((msg) => {
if (ctx.settings.get('logLevel') !== 'quiet') {
ctx.log(`Received message in ${msg.roomId}: "${msg.content.slice(0, 40)}"`);
}
});
// -------------------------------------------------------------------------
// Theme — Ocean Blue dark palette
// -------------------------------------------------------------------------
ctx.themes.register({
id: 'ocean',
name: 'Ocean Blue',
kind: 'dark',
colors: {
background: {
container: '#0d1b2a',
containerHover: '#1b2d42',
containerActive: '#243856',
containerLine: '#1e3a5f',
onContainer: '#c9d6e3',
},
surface: {
container: '#112233',
containerHover: '#1a3344',
containerActive: '#224455',
containerLine: '#1e3a5f',
onContainer: '#d0dde8',
},
surfaceVariant: {
container: '#162840',
containerHover: '#1f3555',
containerActive: '#28426a',
containerLine: '#2a4a70',
onContainer: '#b8cfe0',
},
primary: {
main: '#0077b6',
mainHover: '#0096c7',
mainActive: '#00b4d8',
mainLine: '#0077b6',
onMain: '#ffffff',
container: '#023e8a',
containerHover: '#0d47a1',
containerActive: '#1565c0',
containerLine: '#0d47a1',
onContainer: '#90e0ef',
},
secondary: {
main: '#48cae4',
mainHover: '#00b4d8',
mainActive: '#0096c7',
mainLine: '#48cae4',
onMain: '#000000',
container: '#0d6986',
containerHover: '#0e7fa0',
containerActive: '#0f95bb',
containerLine: '#0d6986',
onContainer: '#caf0f8',
},
success: {
main: '#00b894',
mainHover: '#00cca3',
mainActive: '#00dfb2',
mainLine: '#00b894',
onMain: '#000000',
container: '#007a65',
containerHover: '#009478',
containerActive: '#00ae8b',
containerLine: '#007a65',
onContainer: '#b2f0e8',
},
warning: {
main: '#f39c12',
mainHover: '#f5a623',
mainActive: '#f7b733',
mainLine: '#f39c12',
onMain: '#000000',
container: '#a66c00',
containerHover: '#bf7c00',
containerActive: '#d98c00',
containerLine: '#a66c00',
onContainer: '#fde9b2',
},
critical: {
main: '#e74c3c',
mainHover: '#ec5f50',
mainActive: '#f17264',
mainLine: '#e74c3c',
onMain: '#ffffff',
container: '#9c1e12',
containerHover: '#b52316',
containerActive: '#ce281a',
containerLine: '#9c1e12',
onContainer: '#fcd4d0',
},
other: {
focusRing: '#0096c7',
shadow: 'rgba(0,0,0,0.5)',
overlay: 'rgba(0,0,0,0.6)',
},
},
extraCss: `
body.plugin-example-plugin-ocean {
background: #0d1b2a;
color: #c9d6e3;
}
`,
});
// -------------------------------------------------------------------------
// Events — listen on the injected event client
// -------------------------------------------------------------------------
ctx.events.on('test-event', (data) => {
ctx.log(`test-event received: ${JSON.stringify(data)}`);
});
// -------------------------------------------------------------------------
// Timers — heartbeat every 30 s
// -------------------------------------------------------------------------
ctx.timers.setInterval(() => {
if (ctx.settings.get('logLevel') === 'verbose') {
ctx.log('Heartbeat tick');
}
}, 30_000);
// -------------------------------------------------------------------------
// Notify on load
// -------------------------------------------------------------------------
ctx.notify({
title: 'Example Plugin',
body: 'Loaded successfully! Try a /command below.',
type: 'success',
});
},
onUnload() {
// Timers, event handlers, and themes are cleaned up automatically by the registry.
},
/** Public API — accessible by other plugins via ctx.require('example-plugin') */
exports: {
version: '1.0.0',
greet: (name) => `Hi from Example Plugin, ${name}!`,
},
};