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

100 lines
2.4 KiB

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