238 lines
7.8 KiB
JavaScript
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}!`,
|
|
},
|
|
};
|