[ABANDONDED] Set of "apps" for the Flexor social network.
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

// 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)
}
}