Creates complete addon structure with manifest, main/renderer modules, shared types, and demo views. Includes comprehensive README documenting addon API, lifecycle methods, permissions, capabilities, and contribution points. Implements settings panel and demo repository view to showcase addon features.
216 lines
5.7 KiB
JavaScript
216 lines
5.7 KiB
JavaScript
/**
|
|
* My First Addon - Renderer Process Module
|
|
*
|
|
* This file runs in Electron's renderer process and handles:
|
|
* - React components for GitCaddy's UI
|
|
* - Communication with the main process via IPC
|
|
* - UI state management
|
|
*
|
|
* The renderer process has limited access compared to main process:
|
|
* - No direct file system access
|
|
* - No spawning child processes
|
|
* - Must use IPC to communicate with main process
|
|
*/
|
|
|
|
const { DEFAULT_SETTINGS } = require('../shared/types');
|
|
|
|
/**
|
|
* Renderer Module Class
|
|
*
|
|
* GitCaddy will instantiate this class for UI integration.
|
|
*/
|
|
class MyFirstAddonRenderer {
|
|
constructor() {
|
|
this.context = null;
|
|
this.settings = { ...DEFAULT_SETTINGS };
|
|
this.disposables = [];
|
|
this.isActivated = false;
|
|
}
|
|
|
|
// ============================================================
|
|
// LIFECYCLE METHODS
|
|
// ============================================================
|
|
|
|
/**
|
|
* Initialize the renderer module.
|
|
*
|
|
* @param {IAddonRendererContext} context - Context provided by GitCaddy
|
|
*/
|
|
async initialize(context) {
|
|
this.context = context;
|
|
context.log.info('MyFirstAddon renderer initializing...');
|
|
|
|
// Load settings
|
|
await this.loadSettings();
|
|
|
|
// Listen for settings changes
|
|
const settingsDisposable = context.settings.onDidChange((key, value) => {
|
|
this.onSettingChanged(key, value);
|
|
});
|
|
this.disposables.push(settingsDisposable);
|
|
|
|
// Listen for messages from main process
|
|
const ipcDisposable = context.ipc.on('addon-message', (data) => {
|
|
this.onMessage(data);
|
|
});
|
|
this.disposables.push(ipcDisposable);
|
|
|
|
context.log.info('MyFirstAddon renderer initialized');
|
|
}
|
|
|
|
/**
|
|
* Called when the addon is activated.
|
|
*/
|
|
onActivated() {
|
|
this.isActivated = true;
|
|
this.context?.log.info('MyFirstAddon renderer: addon activated');
|
|
}
|
|
|
|
/**
|
|
* Called when the addon is deactivated.
|
|
*/
|
|
onDeactivated() {
|
|
this.isActivated = false;
|
|
this.context?.log.info('MyFirstAddon renderer: addon deactivated');
|
|
}
|
|
|
|
/**
|
|
* Get a React component for a specific UI slot.
|
|
*
|
|
* GitCaddy calls this to get custom UI components.
|
|
* Return null if you don't have a component for the slot.
|
|
*
|
|
* @param {string} slot - UI slot identifier
|
|
* @returns {React.ComponentType|null} React component or null
|
|
*/
|
|
getComponent(slot) {
|
|
// Example slots: 'commit-summary-input', 'sidebar-panel', etc.
|
|
this.context?.log.debug(`getComponent called for slot: ${slot}`);
|
|
|
|
// This addon doesn't provide custom React components
|
|
// If you want to add components, you'd return them here:
|
|
//
|
|
// switch (slot) {
|
|
// case 'sidebar-panel':
|
|
// return MySidebarComponent;
|
|
// default:
|
|
// return null;
|
|
// }
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Dispose of the renderer module.
|
|
*/
|
|
dispose() {
|
|
this.context?.log.info('MyFirstAddon renderer disposing...');
|
|
|
|
for (const disposable of this.disposables) {
|
|
disposable.dispose();
|
|
}
|
|
this.disposables = [];
|
|
|
|
this.context = null;
|
|
}
|
|
|
|
// ============================================================
|
|
// SETTINGS
|
|
// ============================================================
|
|
|
|
async loadSettings() {
|
|
if (!this.context) return;
|
|
|
|
const stored = this.context.settings.getAll();
|
|
this.settings = {
|
|
enableFeature: stored.enableFeature ?? DEFAULT_SETTINGS.enableFeature,
|
|
apiKey: stored.apiKey ?? DEFAULT_SETTINGS.apiKey,
|
|
mode: stored.mode ?? DEFAULT_SETTINGS.mode,
|
|
maxItems: stored.maxItems ?? DEFAULT_SETTINGS.maxItems,
|
|
};
|
|
}
|
|
|
|
onSettingChanged(key, value) {
|
|
if (key in this.settings) {
|
|
this.settings[key] = value;
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// IPC COMMUNICATION
|
|
// ============================================================
|
|
|
|
/**
|
|
* Handle messages from the main process.
|
|
*/
|
|
onMessage(data) {
|
|
this.context?.log.debug('Received message from main:', data);
|
|
}
|
|
|
|
/**
|
|
* Send a message to the main process.
|
|
*/
|
|
sendMessage(channel, data) {
|
|
this.context?.ipc.send(channel, data);
|
|
}
|
|
|
|
/**
|
|
* Invoke a method on the main process and wait for response.
|
|
*/
|
|
async invokeMain(method, ...args) {
|
|
return this.context?.ipc.invoke(method, ...args);
|
|
}
|
|
|
|
// ============================================================
|
|
// PUBLIC API
|
|
// ============================================================
|
|
|
|
/**
|
|
* Get current settings.
|
|
*/
|
|
getSettings() {
|
|
return { ...this.settings };
|
|
}
|
|
|
|
/**
|
|
* Check if a feature is enabled.
|
|
*/
|
|
isFeatureEnabled() {
|
|
return this.settings.enableFeature;
|
|
}
|
|
|
|
/**
|
|
* Get the current mode.
|
|
*/
|
|
getMode() {
|
|
return this.settings.mode;
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// RENDERER CONTEXT INTERFACE (for reference)
|
|
// ============================================================
|
|
|
|
/**
|
|
* @typedef {Object} IAddonRendererContext
|
|
* @property {string} addonId - Unique addon identifier
|
|
* @property {Object} manifest - Parsed addon.json
|
|
* @property {IAddonLogger} log - Logger instance
|
|
* @property {IAddonSettings} settings - Settings storage
|
|
* @property {IAddonIPC} ipc - IPC communication
|
|
* @property {IAppStateProxy} appState - Access to app state
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} IAppStateProxy
|
|
* @property {function} getCurrentRepository - Get current repository
|
|
* @property {function} getSelectedFiles - Get selected files
|
|
* @property {function} getCurrentDiff - Get current diff
|
|
* @property {function} getCommitMessage - Get commit message
|
|
* @property {function} getRecentCommits - Get recent commits
|
|
*/
|
|
|
|
// Export the renderer class as default
|
|
module.exports = MyFirstAddonRenderer;
|
|
module.exports.default = MyFirstAddonRenderer;
|