export interface IXHRParameters { method : string ; path : string ; async : boolean ; } export default abstract class BasePlugin { protected settings : any ; protected name : string ; public shouldInterceptWS : boolean ; public shouldInterceptXHR : boolean ; public shouldInterceptReact : boolean ; public constructor ( name , settings ) { this . name = name ; this . settings = settings ; this . shouldInterceptWS = false ; this . shouldInterceptXHR = false ; this . shouldInterceptReact = false ; } public async init ( ) { } public interceptWS ( data ) { return data ; } public interceptXHR ( request , parameters ) { } public interceptReact ( displayName , props ) { return props ; } public getCSS ( ) { return "" ; } public getDarkCSS ( ) { return "" ; } public static GenerateSettingsFromForm ( current , newSettings ) { current = current || { } ; current . enabled = ! ! newSettings && newSettings . enabled === "1" ; return current ; } protected async setUpObserver ( targetQuery , observerOptions , fn ) { const targetNode = await this . getElement ( ( ) => document . querySelector ( targetQuery ) ) ; const observer = new MutationObserver ( ( rs , o ) => { const nodes = rs . map ( r => [ ... r . addedNodes ] as any ) . reduce ( ( a , b ) => a . concat ( b ) ) as Node [ ] ; fn ( nodes , o ) ; } ) ; observer . observe ( targetNode , observerOptions ) ; } protected getElement < T > ( fn ) { return new Promise ( ( resolve , _ ) => { const res = fn ( ) ; if ( res ) { resolve ( res ) ; } const interval = setInterval ( ( ) => { const res = fn ( ) ; if ( res ) { clearInterval ( interval ) ; resolve ( res ) ; } } , 200 ) ; } ) ; } protected getSlackModel ( ) { const w = window as any ; return w . TS . model ; } protected setLocalValue ( key , value ) { this . setValue ( key , value , this . name ) ; } protected getLocalValue ( key ) { return this . getValue ( key , this . name ) ; } protected setGlobalValue ( key , value ) { this . setValue ( key , value ) ; } protected getGlobalValue ( key ) { return this . getValue ( key ) ; } protected updateReactCheckbox ( checkbox , value ) { checkbox . checked = value ; const event = new Event ( "click" , { bubbles : true } ) ; ( checkbox as any ) . _valueTracker . setValue ( ! value . toString ( ) ) ; checkbox . dispatchEvent ( event ) ; } private setValue ( key , value , namespace ? ) { const w = window as any ; if ( ! w . Refined ) { w . Refined = { } ; } let dest = w . Refined ; if ( namespace ) { if ( ! w . Refined [ namespace ] ) { w . Refined [ namespace ] = { } ; } dest = w . Refined [ namespace ] ; } dest [ key ] = value ; } private getValue ( key , namespace ? ) { const w = window as any ; if ( ! w . Refined ) { return undefined ; } let source = w . Refined ; if ( namespace ) { if ( ! w . Refined [ namespace ] ) { return undefined ; } source = w . Refined [ namespace ] ; } return source [ key ] ; } } export abstract class MessageTweakerPlugin extends BasePlugin { public constructor ( name , settings ) { super ( name , settings ) ; this . shouldInterceptWS = true ; this . shouldInterceptXHR = true ; } protected abstract processXHRMessages ( messages ) ; protected abstract processWSMessage ( message ) ; public interceptXHR ( request , parameters ) { let oldListener = _ => { } ; if ( request . onreadystatechange ) { oldListener = request . onreadystatechange . bind ( request ) ; } if ( parameters . path . startsWith ( "/api/conversations.view" ) || parameters . path . startsWith ( "/api/conversations.history" ) ) { request . onreadystatechange = e => { if ( request . readyState === 4 ) { this . processConversations ( request ) ; } oldListener ( e ) ; } ; } } public interceptWS ( data ) { if ( data . type === "message" ) { data = this . processWSMessage ( data ) ; } return data ; } private processConversations ( request ) { const data = JSON . parse ( request . responseText ) ; if ( data . ok ) { if ( data . history && data . history . messages ) { data . history . messages = this . processXHRMessages ( data . history . messages ) ; } else if ( data . messages ) { data . messages = this . processXHRMessages ( data . messages ) ; } request . bindResponse ( JSON . stringify ( data ) ) ; } } }