You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.7 KiB
150 lines
3.7 KiB
// index.ts
|
|
// Copyright (C) 2020 Dwayne Harris
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
export interface Attachment {
|
|
url: string
|
|
text?: string
|
|
cover?: string
|
|
}
|
|
|
|
export interface PostData {
|
|
[key: string]: any
|
|
}
|
|
|
|
export interface Post {
|
|
text?: string
|
|
cover?: string
|
|
attachments?: Attachment[]
|
|
data?: PostData
|
|
visible: boolean
|
|
}
|
|
|
|
export interface Theme {
|
|
primary: string
|
|
primaryAlternate: string
|
|
secondary: string
|
|
backgroundPrimary: string
|
|
backgroundSecondary: string
|
|
text: string
|
|
red: string
|
|
green: string
|
|
blue: string
|
|
}
|
|
|
|
export interface MessageContent {
|
|
[key: string]: any
|
|
settings?: InstallationSettings
|
|
height?: number
|
|
theme?: Theme
|
|
colorScheme?: string
|
|
parent?: Post
|
|
}
|
|
|
|
export interface IncomingMessageData {
|
|
name: string
|
|
content: MessageContent
|
|
publicKey: string
|
|
}
|
|
|
|
export interface OutgoingMessageData {
|
|
name: string
|
|
content?: MessageContent
|
|
error?: string
|
|
settings?: object
|
|
}
|
|
|
|
export interface InstallationSettings {
|
|
[key: string]: any
|
|
}
|
|
|
|
interface Listener {
|
|
resolve: (value?: MessageContent | PromiseLike<MessageContent>) => void
|
|
reject: (reason: any) => void
|
|
once: boolean
|
|
}
|
|
|
|
interface ListenerCollection {
|
|
[name: string]: Listener
|
|
}
|
|
|
|
type PostOptions = Post
|
|
|
|
export class Communicator {
|
|
private origin = 'http://localhost:8080'
|
|
private publicKey: string
|
|
private listeners: ListenerCollection
|
|
|
|
constructor(publicKey: string) {
|
|
this.publicKey = publicKey
|
|
this.listeners = {}
|
|
|
|
window.addEventListener('message', (event: MessageEvent) => {
|
|
if (event.origin !== this.origin) return
|
|
|
|
try {
|
|
const data = JSON.parse(event.data) as OutgoingMessageData
|
|
this.emit(data)
|
|
} catch (err) {
|
|
console.error(err)
|
|
return
|
|
}
|
|
}, false)
|
|
}
|
|
|
|
private emit(data: OutgoingMessageData) {
|
|
const listener = this.listeners[data.name]
|
|
|
|
if (listener) {
|
|
if (data.content) listener.resolve(data.content)
|
|
if (data.error) listener.reject(data.error)
|
|
if (listener.once) delete this.listeners[data.name]
|
|
}
|
|
}
|
|
|
|
private async postAndReceive(name: string, content?: MessageContent) {
|
|
if (window.parent) {
|
|
window.parent.postMessage(JSON.stringify({
|
|
name,
|
|
content,
|
|
publicKey: this.publicKey,
|
|
}), this.origin)
|
|
|
|
return new Promise<MessageContent>((resolve, reject) => {
|
|
this.listeners[name] = {
|
|
resolve,
|
|
reject,
|
|
once: true,
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
async init() {
|
|
return this.postAndReceive('init')
|
|
}
|
|
|
|
async setHeight(height: number) {
|
|
return this.postAndReceive('setHeight', { height })
|
|
}
|
|
|
|
async saveSettings(settings: InstallationSettings) {
|
|
return this.postAndReceive('saveSettings', { settings })
|
|
}
|
|
|
|
async post(options: PostOptions) {
|
|
return this.postAndReceive('post', options)
|
|
}
|
|
}
|