UNPKG

streamdeck-typescript

Version:

This library will help you build elgato stream deck plugins in typescript

273 lines (246 loc) 8.08 kB
import { StreamDeckActionClass } from '../classes/stream-deck-action.class'; import { StateType, TargetType } from '../interfaces/enums'; import { PossibleEventsToReceive } from '../interfaces/types'; import { ActionManager } from '../manager/action.manager'; import { StreamDeckHandlerBase } from './stream-deck-handler-base'; /** * This will help you create the stream deck action handler * @author XeroxDev <help@xeroxdev.de> * @copyright 2021 */ export abstract class StreamDeckPluginHandler< GlobalSettings = any > extends StreamDeckHandlerBase<GlobalSettings> { private readonly _actionManager: ActionManager; protected constructor() { super(); this._actionManager = new ActionManager(this); } public get actionManager(): ActionManager { return this._actionManager; } /** * Sets the action title * @param {string} title The string the title should be * @param {string} context The context which called it * @param {TargetType} target [Optional] Show title only on hardware, software or both (default: Both) * @param {StateType} state [Optional] Show title only on ON state or OFF state (default: Both) */ public setTitle( title: string, context: string, target: TargetType = TargetType.BOTH, state?: StateType ) { if (state) { this.send('setTitle', { context, payload: { title, target, state }, }); } else { this.send('setTitle', { context, payload: { title, target }, }); } } /** * Sets the action image * @param {string} image Image as string * @param {string} context The context which called it * @param {TargetType} target [Optional] Show image only on hardware, software or both (default: Both) * @param {StateType} state [Optional] Show image only on ON state or OFF state (default: Both) */ public setImage( image: string, context: string, target: TargetType = TargetType.BOTH, state?: StateType ) { if (state) { this.send('setImage', { context, payload: { image, target, state }, }); } else { this.send('setImage', { context, payload: { image, target }, }); } } /** * Sets the action image but instead from file, from URL * @param {string} url * @param {string} context * @param {TargetType} target * @param {StateType} state * @returns {Promise<string>} */ public setImageFromUrl( url: string, context: string, target: TargetType = TargetType.BOTH, state?: StateType ): Promise<string> { return new Promise((resolve, reject) => { let image = new Image(); image.onload = () => { let canvas = document.createElement('canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; let ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('image failed to load')); return; } ctx.drawImage(image, 0, 0); image.onload = null; image.onerror = null; (image as any) = null; const dataUrl = canvas.toDataURL('image/png'); this.setImage(dataUrl, context, target, state); resolve(dataUrl); }; image.onerror = () => { image.onload = null; image.onerror = null; (image as any) = null; reject(new Error('image failed to load')); }; image.src = url; }); } /** * Shows a alert icon on action * @param {string} context */ public showAlert(context: string) { this.send('showAlert', { context }); } /** * Shows a okay icon on action * @param {string} context */ public showOk(context: string) { this.send('showOk', { context }); } /** * Sets the state of the action (ON / OFF) * @param {StateType} state * @param {string} context The context which called it */ public setState(state: StateType, context: string) { this.send('setState', { context: context, payload: { state }, }); } /** * Switch to a profile * @param {string} profile * @param {string} device */ public switchToProfile(profile: string, device?: string) { this.send('switchToProfile', { context: this.uuid, device: device ? device : this.info.devices[0].id, payload: { profile }, }); } /** * Send data to the property inspector * @param {any} payload Data to send * @param {string} action [Optional] Action context. * @param {string} context The context which called it */ public sendToPropertyInspector( payload: any, action: string, context: string ) { this.send('sendToPropertyInspector', { context, action: action, payload, }); } protected _eventHandler(ev: MessageEvent): void { const eventData = JSON.parse(ev.data); const event: PossibleEventsToReceive = eventData.event; if ( event !== 'didReceiveGlobalSettings' && eventData.context && eventData.payload?.settings ) this.settingsManager.cacheContextSettings( eventData.context, eventData.payload.settings ); let settings, column, isInMultiAction, row, state, userDesiredState, action, context, device; action = eventData?.action; context = eventData?.context; device = eventData?.device; const payload = eventData?.payload; settings = payload?.settings; state = payload?.state; userDesiredState = payload?.userDesiredState; isInMultiAction = payload?.isInMultiAction; column = payload?.coordinates?.column; row = payload?.coordinates?.row; const actionClass = this._actionManager.addOrGetAction( context, new StreamDeckActionClass(this) ); if (actionClass) { if (action !== undefined) actionClass.action = action; if (context !== undefined) actionClass.context = context; if (device !== undefined) actionClass.device = device; if (settings !== undefined) actionClass.settings = settings; if (column !== undefined) actionClass.column = column; if (row !== undefined) actionClass.row = row; if (state !== undefined) actionClass.state = state; if (userDesiredState !== undefined) actionClass.userDesiredState = userDesiredState; if (isInMultiAction !== undefined) actionClass.isInMultiAction = isInMultiAction; } super._eventHandler(ev); } /** * Sets the action title * @param {string} context The context which called it * @param {any} json */ public setFeedback( context: string, payload: any ) { this.send('setFeedback', { context, payload: payload, }); } /** * Sets the action title * @param {string} context The context which called it * @param {string} layout */ public setFeedbackLayout( context: string, layout: string, ) { this.send('setFeedbackLayout', { context, payload: { layout }, }); } }