[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.

95 lines
2.3 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import { Post } from '../types'
  2. export interface MessageContent {
  3. [key: string]: any
  4. height?: number
  5. parent?: Post
  6. }
  7. export interface IncomingMessageData {
  8. name: string
  9. content: MessageContent
  10. publicKey: string
  11. }
  12. export interface OutgoingMessageData {
  13. name: string
  14. content?: MessageContent
  15. error?: string
  16. settings?: object
  17. }
  18. interface Listener {
  19. resolve: (value?: MessageContent | PromiseLike<MessageContent>) => void
  20. reject: (reason: any) => void
  21. once: boolean
  22. }
  23. interface ListenerCollection {
  24. [name: string]: Listener
  25. }
  26. type PostOptions = Post
  27. export class Communicator {
  28. private origin = 'http://localhost:8080'
  29. private publicKey: string
  30. private listeners: ListenerCollection
  31. constructor(publicKey: string) {
  32. this.publicKey = publicKey
  33. this.listeners = {}
  34. window.addEventListener('message', (event: MessageEvent) => {
  35. if (event.origin !== this.origin) return
  36. try {
  37. const data = JSON.parse(event.data) as OutgoingMessageData
  38. this.emit(data)
  39. } catch (err) {
  40. console.error(err)
  41. return
  42. }
  43. }, false)
  44. }
  45. private emit(data: OutgoingMessageData) {
  46. const listener = this.listeners[data.name]
  47. if (listener) {
  48. if (data.content) listener.resolve(data.content)
  49. if (data.error) listener.reject(data.error)
  50. if (listener.once) delete this.listeners[data.name]
  51. }
  52. }
  53. private async postAndReceive(name: string, content?: MessageContent) {
  54. if (window.parent) {
  55. window.parent.postMessage(JSON.stringify({
  56. name,
  57. content,
  58. publicKey: this.publicKey,
  59. }), this.origin)
  60. return new Promise<MessageContent>((resolve, reject) => {
  61. this.listeners[name] = {
  62. resolve,
  63. reject,
  64. once: true,
  65. }
  66. })
  67. }
  68. }
  69. async init() {
  70. return this.postAndReceive('init')
  71. }
  72. async setHeight(height: number) {
  73. return this.postAndReceive('setHeight', { height })
  74. }
  75. async post(options: PostOptions) {
  76. return this.postAndReceive('post', options)
  77. }
  78. }