{"version":3,"file":"CommentStore-DEDTjspt.mjs","names":[],"sources":["../src/websocket/wss.ts","../src/websocket/commentWebsocket.ts","../src/stores/CommentStore.ts"],"sourcesContent":["/* eslint-disable */\nlet SockJS: any = null;\nlet Stomp: any = null;\n/* eslint-enable */\n\ninterface Subscription {\n  id: string;\n  topic: string;\n  callback: (message: { body: string }) => void;\n  subscription?: () => void;\n}\n\nexport default class WssConnection {\n  url: string;\n  endpoint: string;\n  subscriptions: Array<Subscription>;\n  /* eslint-disable */\n  socket: {\n    (url: string, _reserved?: any, options?: SockJS.Options | undefined): WebSocket;\n    new (url: string, _reserved?: any, options?: SockJS.Options | undefined): WebSocket;\n    prototype: WebSocket;\n    CONNECTING: SockJS.CONNECTING;\n    OPEN: SockJS.OPEN;\n    CLOSING: SockJS.CLOSING;\n    CLOSED: SockJS.CLOSED;\n  }|undefined ;\n  client: any;\n  queuedMessages: Array<any>;\n  processingMsg: boolean;\n  wssBroken: boolean;\n  /* eslint-enable */\n  /**\n   *\n   * @param {String} url url of the wss\n   * @param {String} endpoint of the wss\n   * @param {Map<String, Function>} topics list of topics and associated callback\n   */\n  constructor(url: string, endpoint: string) {\n    this.url = url;\n    this.endpoint = endpoint;\n    this.subscriptions = [];\n    this.processingMsg = false;\n    this.queuedMessages = [];\n    this.wssBroken = false;\n  }\n  async processQueuedMessages() {\n    if (this.processingMsg) {\n      return;\n    }\n    if (this.queuedMessages.length === 0) {\n      return;\n    }\n    this.processingMsg = true;\n    try {\n      const message = this.queuedMessages.shift();\n      await message.callback(message.message);\n    } catch (error) {\n      console.log(error);\n    }\n    this.processingMsg = false;\n    this.processQueuedMessages();\n  }\n\n  async connect(): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      (async () => {\n        if (null === SockJS) {\n          await import(\"sockjs-client/dist/sockjs\").then((sockLibrary) => {\n            SockJS = sockLibrary.default;\n          });\n        }\n        if (null === Stomp) {\n          await import(\"@stomp/stompjs\").then((stompLibrary) => {\n            Stomp = stompLibrary.Stomp;\n          });\n        }\n        this.socket = new SockJS(\"https://\" + this.url + \"/\" + this.endpoint);\n        this.client = Stomp.over(this.socket);\n        this.client.heartbeat.outgoing = 2000;\n        this.client.heartbeat.incoming = 2000;\n        this.client.debug = (sockMessage: string) => {\n          if (\n            sockMessage.includes(\"did not receive server activity for the last\")\n          ) {\n            this.wssBroken = true;\n          }\n        };\n        this.client.onConnect = () => {\n          this.connectionSuccess();\n          resolve();\n        };\n        this.client.onStompError = () => {\n          this.wssBroken = true;\n          this.connectionErrorReconnect();\n          reject(new Error());\n        };\n        this.client.onWebSocketError = () => {\n          this.wssBroken = true;\n          this.connectionErrorReconnect();\n          reject(new Error());\n        };\n        this.client.onDisconnect = () => {\n          this.connectionErrorReconnect();\n          reject(new Error());\n        };\n        this.client.onWebSocketClose = () => {\n          this.connectionErrorReconnect();\n          reject(new Error());\n        };\n\n        this.client.activate();\n      })();\n    });\n  }\n\n  async connectionErrorReconnect() {\n    if (!this.wssBroken) {\n      return;\n    }\n    console.log(\"Error in ws try to reconnect\");\n    setTimeout(() => {\n      this.connect();\n    }, 10);\n    this.wssBroken = false;\n  }\n\n  connectionSuccess(): void {\n    this.subscriptions.forEach((element: Subscription) => {\n      // On récupère tous les évènements freeswitch\n      try {\n        this.subscribe(element.topic, element.callback);\n      } catch {\n        setTimeout(() => {\n          this.connect();\n        }, 10000);\n        return;\n      }\n    });\n  }\n\n  subscribe(topic: string, callback: (message: { body: string }) => any): void {\n    const subscription = this.client.subscribe(topic, (message: any) => {\n      this.queuedMessages.push({ message: message, callback: callback });\n      this.processQueuedMessages();\n    });\n    this.subscriptions.push({\n      id: subscription.id,\n      topic: topic,\n      callback: callback,\n    });\n  }\n\n  unsubscribe(topic: string): void {\n    if (!topic) {\n      throw new Error(\n        \"Cannot remove subscription if no search pattern is founded\",\n      );\n    }\n    const removedSubscriptions: Array<Subscription> = [];\n    this.subscriptions.forEach((item: Subscription) => {\n      let valid = true;\n      if (item.topic !== topic) {\n        valid = false;\n      }\n      if (valid) {\n        removedSubscriptions.push(item);\n        try {\n          this.client.unsubscribe(item.id);\n        } catch {\n          console.log(\"Error while deconnecting client with item \" + item.id);\n        }\n      }\n    });\n    this.subscriptions = this.subscriptions.filter(\n      (item: Subscription) => !removedSubscriptions.includes(item),\n    );\n  }\n\n  disconnect(): void {\n    this.client.deactivate();\n  }\n}\n","import { CommentMessage } from \"@/stores/class/config/commentsConfig\";\nimport WssConnection from \"./wss\";\n\nexport default class CommentEngine {\n  uri: string;\n  connection: WssConnection | undefined;\n  subscribedEventComment: number|undefined;\n\n  constructor(wssDomain: string) {\n    this.uri = wssDomain;\n    this.connection = undefined;\n    this.subscribedEventComment = undefined;\n  }\n\n  async initialize(): Promise<void> {\n    this.connection = new WssConnection(this.uri, \"websocket\");\n    await this.connection.connect();\n  }\n  async close(): Promise<void> {\n    if (!this.connection) {\n      return;\n    }\n    this.connection.disconnect();\n    this.connection = undefined;\n  }\n\n  subscribeToPodcastCommentEventBus(\n    podcastId: number,\n    queueName: string,\n    callback: (jsonMessage: CommentMessage) => void,\n  ): void {\n    if (!this.connection) {\n      throw new Error(\n        \"Websocket engine must be initialized, before it can subscribe to any events\",\n      );\n    }\n    if (podcastId) {\n      this.connection.subscribe(\n        queueName,\n        (message) => {\n          const jsonMessage = JSON.parse(message.body);\n          callback.call(this, jsonMessage);\n        },\n      );\n      this.subscribedEventComment = podcastId;\n    }\n  }\n\n  unsubscribeToPodcastCommentEventBus(podcastId: number, queueName: string): void {\n    if (!this.connection) {\n      throw new Error(\n        \"Websocket engine must be initialized, before it can unsubscribe to any events\",\n      );\n    }\n    if (!podcastId) {\n      throw new Error(\n        \"Cannot unsubscribe to comments event bus if no id provided\",\n      );\n    }\n    this.connection.unsubscribe(queueName);\n    this.subscribedEventComment = undefined;\n  }\n\n  isPodcastCommentEventConnected(podcastId: number): boolean {\n    return podcastId===this.subscribedEventComment;\n  }\n}\n","//Import dayjs extend\nimport dayjs from \"dayjs\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\ndayjs.extend(relativeTime);\n\nimport { defineStore } from \"pinia\";\nimport cookiesHelper from \"../helper/cookiesHelper\";\nimport WebSocketEngine from \"../websocket/commentWebsocket\";\nimport { CommentPodcast } from \"./class/general/comment\";\nimport { useAuthStore } from \"./AuthStore\";\nimport { useApiStore } from \"./ApiStore\";\nimport stringHelper from \"../helper/stringHelper\";\nimport { CommentMessage, CommentsConfig } from \"./class/config/commentsConfig\";\nimport classicApi from \"../api/classicApi\";\nimport { Podcast } from \"./class/general/podcast\";\nimport { ListClassicReturn } from \"./class/general/listReturn\";\nfunction errorCommentsConfig(): CommentsConfig {\n  return {\n    inherited: false,\n    abuse: {\n      authRequired: true,\n    },\n    commentLikes: {\n      authRequired: true,\n      dislikeEnabled: false,\n      likeEnabled: false,\n    },\n    comments: {\n      authRequired: true,\n      commentAllowed: \"NONE\",\n      defaultState: \"PENDING\",\n      depth: 2,\n    },\n    podcastLikes: {\n      authRequired: true,\n      dislikeEnabled: false,\n      likeEnabled: false,\n    },\n  };\n}\n\n\nexport interface CommentUser {\n  name: string | null;\n  uuid: string | null;\n  uuidHash: string | null;\n}\ninterface CommentState {\n  commentInitialized: boolean;\n  commentWebsocketengine: WebSocketEngine | undefined;\n  commentPodcastId?: number;\n  commentQueueName?: string;\n  commentEventToHandle: Array<CommentMessage>;\n  commentUser?: CommentUser;\n  commentsForPlayer: { [key: number]: Array<CommentPodcast> };\n  podcastsCommentsConfig: { [key: number]: CommentsConfig };\n}\nexport const useCommentStore = defineStore(\"CommentStore\", {\n  state: (): CommentState => ({\n    commentInitialized: false,\n    commentWebsocketengine: undefined,\n    commentPodcastId: undefined,\n    commentQueueName: undefined,\n    commentEventToHandle: [],\n    commentsForPlayer: {},\n    podcastsCommentsConfig: {},\n  }),\n  actions: {\n    async fetchCommentsForPlayer(podcastId: number) {\n      if (!this.commentsForPlayer[podcastId]) {\n        this.commentsForPlayer[podcastId] = [];\n        const size = 50;\n        let first = 0;\n        let keepFetching = true;\n        while (keepFetching) {\n          const data = await classicApi.fetchData<ListClassicReturn<CommentPodcast>>({\n            api:2,\n            path:\"comment/list\",\n            parameters:{\n              first: first,\n              size: size,\n              podcastId: podcastId,\n              sort: \"DATE_DESC\",\n              hideAnswers: true,\n              state: \"VALIDATED\",\n            },\n            isNotAuth:true\n          });\n          first += size;\n          this.commentsForPlayer[podcastId] = this.commentsForPlayer[\n            podcastId\n          ].concat(data.result);\n          keepFetching =\n            data.count !== this.commentsForPlayer[podcastId].length;\n        }\n      }\n      return this.commentsForPlayer[podcastId];\n    },\n    async digest(message: string) {\n      return Array.from(\n        new Uint8Array(\n          await crypto.subtle.digest(\n            \"SHA-1\",\n            new TextEncoder().encode(message),\n          ),\n        ),\n        (byte) => byte.toString(16).padStart(2, \"0\"),\n      ).join(\"\");\n    },\n    async initCommentUser() {\n      if (this.commentUser) {\n        return;\n      }\n      const authStore = useAuthStore();\n      if (authStore.authProfile) {\n        this.commentUser = {\n          name: authStore.authName,\n          uuid: authStore.authProfile.userId,\n        };\n        return;\n      }\n      let uuid = cookiesHelper.getCookie(\"comment-octopus-uuid\");\n      if (null === uuid) {\n        uuid = stringHelper.uuidv4();\n        cookiesHelper.setCookie(\"comment-octopus-uuid\", uuid);\n      }\n      const hash = await this.digest(uuid);\n      this.commentUser = {\n        name: cookiesHelper.getCookie(\"comment-octopus-name\"),\n        uuid: uuid,\n        uuidHash: hash,\n      };\n      if (\"#miniplayer\" === this.commentUser?.name) {\n        this.commentUser.name = null;\n      }\n    },\n    setCommentUser(name: string) {\n      const authStore = useAuthStore();\n      if (authStore.authProfile || !this.commentUser) {\n        return;\n      }\n      cookiesHelper.setCookie(\"comment-octopus-name\", name);\n      this.commentUser.name = name;\n    },\n    async getCommentsConfig(podcast: Podcast): Promise<CommentsConfig> {\n      if (this.podcastsCommentsConfig[podcast.podcastId]) {\n        return this.podcastsCommentsConfig[podcast.podcastId];\n      }\n      try {\n        this.podcastsCommentsConfig[podcast.podcastId] = await classicApi.fetchData<CommentsConfig>({\n          api: 2,\n          path:\"config/podcast/\" + podcast.podcastId,\n        });\n      } catch {\n        try {\n          this.podcastsCommentsConfig[podcast.podcastId] = await classicApi.fetchData<CommentsConfig>({\n            api: 2,\n            path: \"config/emission/\" + podcast.emission.emissionId,\n          });\n        } catch {\n          this.podcastsCommentsConfig[podcast.podcastId] = errorCommentsConfig(); \n        }\n      }\n      return this.podcastsCommentsConfig[podcast.podcastId];\n    },\n    resetPodcastsConfig() {\n      this.podcastsCommentsConfig = {};\n    },\n    updatePodcastsConfig(podcastId: number, config: CommentsConfig) {\n      this.podcastsCommentsConfig[podcastId] = config;\n    },\n    getCanPostCommentAllowed(\n      config: CommentsConfig,\n      podcast: Podcast,\n    ): boolean {\n      if (\"NONE\" === config.comments.commentAllowed) {\n        return false;\n      }\n      const rightsLiveOnly =\n        \"LIVE_ONLY\" === config.comments.commentAllowed &&\n        undefined !== podcast.conferenceId &&\n        \"READY_TO_RECORD\" === podcast.processingStatus;\n      const rightsLiveRecord =\n        \"LIVE_AND_REPLAY\" === config.comments.commentAllowed &&\n        undefined !== podcast.conferenceId;\n      return (\n        \"ALL\" === config.comments.commentAllowed ||\n        rightsLiveOnly ||\n        rightsLiveRecord\n      );\n    },\n    getCanPostComment(\n      config: CommentsConfig | undefined,\n      podcast: Podcast | undefined,\n      isAuth: boolean,\n    ): boolean {\n      if (!config || !podcast) {\n        return false;\n      }\n      return (\n        this.getCanPostCommentAllowed(config, podcast) &&\n        (!config.comments.authRequired ||\n          (config.comments.authRequired && isAuth))\n      );\n    },\n    getCanReportAbuse(\n      config: CommentsConfig | undefined,\n      isAuth: boolean,\n    ): boolean {\n      if (!config) {\n        return false;\n      }\n      return (\n        !config.abuse.authRequired || (config.abuse.authRequired && isAuth)\n      );\n    },\n\n    /*--------------------------------------------------------------------------------------------------------------\n    |                                                                                                              |\n    |                                           Initializing state                                                 |\n    |                                                                                                              |\n    --------------------------------------------------------------------------------------------------------------*/\n    async initialize() {\n      const apiStore = useApiStore();\n      const commentUrl = apiStore.commentUrl?? \"https://comments.dev2.saooti.org/\";\n      const url =  stringHelper.trimChar(commentUrl.replace(\"https://\", \"\"),\"/\");\n      const engine = new WebSocketEngine(url);\n      await engine.initialize();\n      this.commentWebsocketengine = engine;\n      this.commentInitialized = true;\n    },\n\n    /*--------------------------------------------------------------------------------------------------------------\n    |                                                                                                              |\n    |                                      Comments management methods                                             |\n    |                                                                                                              |\n    --------------------------------------------------------------------------------------------------------------*/\n    unsubscribeToEvent() {\n      if (!this.commentWebsocketengine) {\n        return;\n      }\n      if (\n        this.commentPodcastId &&\n        this.commentQueueName &&\n        this.commentWebsocketengine.isPodcastCommentEventConnected(\n          this.commentPodcastId,\n        )\n      ) {\n        this.commentWebsocketengine.unsubscribeToPodcastCommentEventBus(\n          this.commentPodcastId,\n          this.commentQueueName,\n        );\n      }\n    },\n\n    subscribeToEvents() {\n      if (!this.commentWebsocketengine) {\n        return;\n      }\n      if (this.commentPodcastId && this.commentQueueName) {\n        this.commentWebsocketengine.subscribeToPodcastCommentEventBus(\n          this.commentPodcastId,\n          this.commentQueueName,\n          (message) => {\n            this.commentEventToHandleUpdate(message);\n          },\n        );\n      }\n    },\n\n    async initComments(podcastId: number, organisationId: string) {\n      this.unsubscribeToEvent();\n      this.commentQueueName =\n        \"/topic/comment.\" + organisationId + \".\" + podcastId;\n      this.commentPodcastId = podcastId;\n      this.subscribeToEvents();\n    },\n    async unsubscribeComments() {\n      this.unsubscribeComments();\n      this.commentPodcastId = undefined;\n    },\n\n    /*--------------------------------------------------------------------------------------------------------------\n    |                                                                                                              |\n    |                              Managing conference WebSocket Event Received                                    |\n    |                                                                                                              |\n    --------------------------------------------------------------------------------------------------------------*/\n    commentEventHandled() {\n      this.commentEventToHandle.shift();\n    },\n    commentEventToHandleUpdate(eventToHandle: {\n      comment: CommentPodcast;\n      type: string;\n    }) {\n      if (eventToHandle) {\n        this.commentEventToHandle.push(eventToHandle);\n      } else {\n        this.commentEventToHandle.splice(0, this.commentEventToHandle.length);\n      }\n    },\n  },\n});\n"],"mappings":"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"}