[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

5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 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
4 years ago
5 years ago
5 years ago
5 years ago
  1. // index.ts
  2. // Copyright (C) 2020 Dwayne Harris
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. export interface Attachment {
  14. url: string
  15. text?: string
  16. cover?: string
  17. }
  18. export interface PostData {
  19. [key: string]: any
  20. }
  21. export interface Post {
  22. text?: string
  23. cover?: string
  24. attachments?: Attachment[]
  25. data?: PostData
  26. visible: boolean
  27. }
  28. export interface Theme {
  29. primary: string
  30. primaryAlternate: string
  31. secondary: string
  32. backgroundPrimary: string
  33. backgroundSecondary: string
  34. text: string
  35. red: string
  36. green: string
  37. blue: string
  38. }
  39. export interface MessageContent {
  40. [key: string]: any
  41. settings?: InstallationSettings
  42. height?: number
  43. theme?: Theme
  44. colorScheme?: string
  45. parent?: Post
  46. }
  47. export interface IncomingMessageData {
  48. name: string
  49. content: MessageContent
  50. publicKey: string
  51. }
  52. export interface OutgoingMessageData {
  53. name: string
  54. content?: MessageContent
  55. error?: string
  56. settings?: object
  57. }
  58. export interface InstallationSettings {
  59. [key: string]: any
  60. }
  61. interface Listener {
  62. resolve: (value?: MessageContent | PromiseLike<MessageContent>) => void
  63. reject: (reason: any) => void
  64. once: boolean
  65. }
  66. interface ListenerCollection {
  67. [name: string]: Listener
  68. }
  69. type PostOptions = Post
  70. export class Communicator {
  71. private origin = 'http://localhost:8080'
  72. private publicKey: string
  73. private listeners: ListenerCollection
  74. constructor(publicKey: string) {
  75. this.publicKey = publicKey
  76. this.listeners = {}
  77. window.addEventListener('message', (event: MessageEvent) => {
  78. if (event.origin !== this.origin) return
  79. try {
  80. const data = JSON.parse(event.data) as OutgoingMessageData
  81. this.emit(data)
  82. } catch (err) {
  83. console.error(err)
  84. return
  85. }
  86. }, false)
  87. }
  88. private emit(data: OutgoingMessageData) {
  89. const listener = this.listeners[data.name]
  90. if (listener) {
  91. if (data.content) listener.resolve(data.content)
  92. if (data.error) listener.reject(data.error)
  93. if (listener.once) delete this.listeners[data.name]
  94. }
  95. }
  96. private async postAndReceive(name: string, content?: MessageContent) {
  97. if (window.parent) {
  98. window.parent.postMessage(JSON.stringify({
  99. name,
  100. content,
  101. publicKey: this.publicKey,
  102. }), this.origin)
  103. return new Promise<MessageContent>((resolve, reject) => {
  104. this.listeners[name] = {
  105. resolve,
  106. reject,
  107. once: true,
  108. }
  109. })
  110. }
  111. }
  112. async init() {
  113. return this.postAndReceive('init')
  114. }
  115. async setHeight(height: number) {
  116. return this.postAndReceive('setHeight', { height })
  117. }
  118. async saveSettings(settings: InstallationSettings) {
  119. return this.postAndReceive('saveSettings', { settings })
  120. }
  121. async post(options: PostOptions) {
  122. return this.postAndReceive('post', options)
  123. }
  124. }